summaryrefslogtreecommitdiffstats
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-07 13:12:05 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:02:59 +0000
commit33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (patch)
treef6af110909c79b2759136554f1143d8b0572af0a /chromium/cc
parent7d2c5d177e9813077a621df8d18c0deda73099b3 (diff)
BASELINE: Update Chromium to 104.0.5112.120
Change-Id: I5d2726c2ab018d75d055739b6ba64317904f05bb Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438935 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn22
-rw-r--r--chromium/cc/DEPS1
-rw-r--r--chromium/cc/OWNERS2
-rw-r--r--chromium/cc/animation/animation_host.cc112
-rw-r--r--chromium/cc/animation/animation_host.h29
-rw-r--r--chromium/cc/animation/animation_unittest.cc12
-rw-r--r--chromium/cc/animation/element_animations.cc91
-rw-r--r--chromium/cc/animation/element_animations.h15
-rw-r--r--chromium/cc/animation/element_animations_unittest.cc204
-rw-r--r--chromium/cc/animation/keyframe_effect.cc18
-rw-r--r--chromium/cc/animation/keyframe_effect.h2
-rw-r--r--chromium/cc/animation/keyframe_model_unittest.cc2
-rw-r--r--chromium/cc/base/list_container_helper.cc3
-rw-r--r--chromium/cc/base/list_container_helper.h5
-rw-r--r--chromium/cc/base/math_util.cc1
-rw-r--r--chromium/cc/base/math_util.h9
-rw-r--r--chromium/cc/base/rtree.h4
-rw-r--r--chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc2
-rw-r--r--chromium/cc/cc.gni9
-rw-r--r--chromium/cc/debug/debug_colors.cc231
-rw-r--r--chromium/cc/debug/debug_colors.h112
-rw-r--r--chromium/cc/input/compositor_input_interfaces.h5
-rw-r--r--chromium/cc/input/input_handler.h11
-rw-r--r--chromium/cc/input/scrollbar_animation_controller.cc10
-rw-r--r--chromium/cc/input/scrollbar_animation_controller.h4
-rw-r--r--chromium/cc/input/scrollbar_animation_controller_unittest.cc70
-rw-r--r--chromium/cc/input/scrollbar_controller.cc123
-rw-r--r--chromium/cc/input/scrollbar_controller.h48
-rw-r--r--chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc1
-rw-r--r--chromium/cc/input/threaded_input_handler.cc47
-rw-r--r--chromium/cc/input/threaded_input_handler.h10
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc114
-rw-r--r--chromium/cc/layers/layer.cc53
-rw-r--r--chromium/cc/layers/layer.h21
-rw-r--r--chromium/cc/layers/layer_impl.cc26
-rw-r--r--chromium/cc/layers/layer_impl.h19
-rw-r--r--chromium/cc/layers/layer_impl_unittest.cc4
-rw-r--r--chromium/cc/layers/layer_list_iterator.h5
-rw-r--r--chromium/cc/layers/layer_perftest.cc4
-rw-r--r--chromium/cc/layers/layer_unittest.cc319
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc93
-rw-r--r--chromium/cc/layers/picture_layer_impl.h9
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc106
-rw-r--r--chromium/cc/layers/recording_source.cc4
-rw-r--r--chromium/cc/layers/recording_source.h6
-rw-r--r--chromium/cc/layers/render_surface_impl.cc3
-rw-r--r--chromium/cc/layers/solid_color_layer.cc4
-rw-r--r--chromium/cc/layers/solid_color_layer.h2
-rw-r--r--chromium/cc/layers/solid_color_layer_impl.cc10
-rw-r--r--chromium/cc/layers/solid_color_layer_impl.h2
-rw-r--r--chromium/cc/layers/solid_color_layer_impl_unittest.cc21
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer_impl.cc9
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer_impl.h2
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc11
-rw-r--r--chromium/cc/layers/surface_layer_impl.h2
-rw-r--r--chromium/cc/layers/surface_layer_impl_unittest.cc12
-rw-r--r--chromium/cc/layers/surface_layer_unittest.cc8
-rw-r--r--chromium/cc/layers/texture_layer_impl.cc16
-rw-r--r--chromium/cc/layers/texture_layer_impl_unittest.cc6
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc6
-rw-r--r--chromium/cc/layers/tile_size_calculator.cc2
-rw-r--r--chromium/cc/layers/tile_size_calculator.h2
-rw-r--r--chromium/cc/layers/video_frame_provider.h4
-rw-r--r--chromium/cc/metrics/begin_main_frame_metrics.h1
-rw-r--r--chromium/cc/metrics/compositor_frame_reporter.cc204
-rw-r--r--chromium/cc/metrics/compositor_frame_reporter.h43
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller.cc17
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller.h10
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc74
-rw-r--r--chromium/cc/metrics/compositor_timing_history.cc56
-rw-r--r--chromium/cc/metrics/compositor_timing_history.h15
-rw-r--r--chromium/cc/metrics/compositor_timing_history_unittest.cc142
-rw-r--r--chromium/cc/metrics/custom_metrics_recorder.cc31
-rw-r--r--chromium/cc/metrics/custom_metrics_recorder.h27
-rw-r--r--chromium/cc/metrics/dropped_frame_counter.cc12
-rw-r--r--chromium/cc/metrics/dropped_frame_counter_unittest.cc36
-rw-r--r--chromium/cc/metrics/event_latency_tracing_recorder.cc119
-rw-r--r--chromium/cc/metrics/event_latency_tracker.cc23
-rw-r--r--chromium/cc/metrics/event_latency_tracker.h54
-rw-r--r--chromium/cc/metrics/event_metrics.cc12
-rw-r--r--chromium/cc/metrics/event_metrics.h33
-rw-r--r--chromium/cc/metrics/frame_info.cc5
-rw-r--r--chromium/cc/metrics/frame_info.h1
-rw-r--r--chromium/cc/metrics/frame_sequence_metrics.cc91
-rw-r--r--chromium/cc/metrics/frame_sequence_metrics.h10
-rw-r--r--chromium/cc/metrics/frame_sequence_metrics_unittest.cc46
-rw-r--r--chromium/cc/metrics/frame_sequence_tracker.cc4
-rw-r--r--chromium/cc/metrics/frame_sequence_tracker_unittest.cc6
-rw-r--r--chromium/cc/metrics/total_frame_counter.cc2
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc12
-rw-r--r--chromium/cc/mojom/render_frame_metadata.mojom9
-rw-r--r--chromium/cc/mojom/render_frame_metadata_mojom_traits.cc7
-rw-r--r--chromium/cc/mojom/render_frame_metadata_mojom_traits.h10
-rw-r--r--chromium/cc/paint/discardable_image_map_unittest.cc2
-rw-r--r--chromium/cc/paint/display_item_list.cc4
-rw-r--r--chromium/cc/paint/display_item_list.h2
-rw-r--r--chromium/cc/paint/display_item_list_unittest.cc1
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc6
-rw-r--r--chromium/cc/paint/oop_pixeltest.cc158
-rw-r--r--chromium/cc/paint/paint_filter.cc3
-rw-r--r--chromium/cc/paint/paint_flags.cc2
-rw-r--r--chromium/cc/paint/paint_flags.h5
-rw-r--r--chromium/cc/paint/paint_image_unittest.cc6
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc140
-rw-r--r--chromium/cc/paint/paint_op_buffer.h26
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc4
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.cc21
-rw-r--r--chromium/cc/paint/paint_op_buffer_unittest.cc181
-rw-r--r--chromium/cc/paint/paint_op_helper_unittest.cc6
-rw-r--r--chromium/cc/paint/paint_op_reader.cc153
-rw-r--r--chromium/cc/paint/paint_op_reader.h24
-rw-r--r--chromium/cc/paint/paint_op_writer.cc105
-rw-r--r--chromium/cc/paint/paint_op_writer.h11
-rw-r--r--chromium/cc/paint/raw_memory_transfer_cache_entry.cc2
-rw-r--r--chromium/cc/paint/record_paint_canvas.cc4
-rw-r--r--chromium/cc/paint/skottie_frame_data.h2
-rw-r--r--chromium/cc/paint/skottie_frame_data_provider.h3
-rw-r--r--chromium/cc/paint/skottie_serialization_history.cc7
-rw-r--r--chromium/cc/paint/skottie_serialization_history_unittest.cc44
-rw-r--r--chromium/cc/paint/skottie_wrapper.h17
-rw-r--r--chromium/cc/paint/skottie_wrapper_impl.cc234
-rw-r--r--chromium/cc/paint/skottie_wrapper_unittest.cc47
-rw-r--r--chromium/cc/paint/solid_color_analyzer.cc4
-rw-r--r--chromium/cc/paint/solid_color_analyzer_unittest.cc46
-rw-r--r--chromium/cc/paint/transfer_cache_unittest.cc3
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc2
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc5
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc6
-rw-r--r--chromium/cc/raster/raster_buffer_provider_perftest.cc6
-rw-r--r--chromium/cc/raster/raster_source.cc4
-rw-r--r--chromium/cc/raster/raster_source.h9
-rw-r--r--chromium/cc/raster/raster_source_unittest.cc64
-rw-r--r--chromium/cc/raster/task_graph_work_queue.cc7
-rw-r--r--chromium/cc/resources/resource_pool.cc9
-rw-r--r--chromium/cc/resources/resource_pool.h4
-rw-r--r--chromium/cc/resources/resource_pool_unittest.cc4
-rw-r--r--chromium/cc/scheduler/scheduler.cc163
-rw-r--r--chromium/cc/scheduler/scheduler.h10
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc29
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.h12
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc150
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc77
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc71
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_perftest.cc2
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc38
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.h4
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc1
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest.cc2
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc6
-rw-r--r--chromium/cc/tiles/tile.cc2
-rw-r--r--chromium/cc/tiles/tile.h2
-rw-r--r--chromium/cc/tiles/tile_manager.cc4
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc15
-rw-r--r--chromium/cc/tiles/tiling_set_eviction_queue.h3
-rw-r--r--chromium/cc/tiles/tiling_set_raster_queue_all.h7
-rw-r--r--chromium/cc/tiles/tiling_set_raster_queue_required.h5
-rw-r--r--chromium/cc/trees/browser_controls_params.h4
-rw-r--r--chromium/cc/trees/commit_state.cc5
-rw-r--r--chromium/cc/trees/commit_state.h6
-rw-r--r--chromium/cc/trees/draw_properties_unittest.cc11
-rw-r--r--chromium/cc/trees/draw_property_utils.cc18
-rw-r--r--chromium/cc/trees/draw_property_utils.h7
-rw-r--r--chromium/cc/trees/effect_node.cc2
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h1
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h1
-rw-r--r--chromium/cc/trees/layer_tree_host.cc62
-rw-r--r--chromium/cc/trees/layer_tree_host.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h7
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc217
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h39
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc352
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc56
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc32
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc30
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc392
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc28
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc44
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_proxy.cc2
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc140
-rw-r--r--chromium/cc/trees/layer_tree_impl.h47
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h11
-rw-r--r--chromium/cc/trees/layer_tree_settings.h10
-rw-r--r--chromium/cc/trees/mutator_host.h28
-rw-r--r--chromium/cc/trees/property_tree.cc73
-rw-r--r--chromium/cc/trees/property_tree.h22
-rw-r--r--chromium/cc/trees/property_tree_builder.cc63
-rw-r--r--chromium/cc/trees/property_tree_builder_unittest.cc10
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc27
-rw-r--r--chromium/cc/trees/proxy.h3
-rw-r--r--chromium/cc/trees/proxy_common.h1
-rw-r--r--chromium/cc/trees/proxy_impl.cc126
-rw-r--r--chromium/cc/trees/proxy_impl.h17
-rw-r--r--chromium/cc/trees/proxy_main.cc81
-rw-r--r--chromium/cc/trees/proxy_main.h4
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc4
-rw-r--r--chromium/cc/trees/render_frame_metadata.h9
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc86
-rw-r--r--chromium/cc/trees/single_thread_proxy.h7
-rw-r--r--chromium/cc/trees/target_property.h3
-rw-r--r--chromium/cc/trees/transform_node.h3
-rw-r--r--chromium/cc/trees/ukm_manager.cc125
-rw-r--r--chromium/cc/trees/ukm_manager.h21
-rw-r--r--chromium/cc/trees/ukm_manager_unittest.cc67
206 files changed, 4775 insertions, 2844 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index 091ec28180f..e52844d44a8 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -178,10 +178,14 @@ cc_component("cc") {
"metrics/compositor_frame_reporting_controller.h",
"metrics/compositor_timing_history.cc",
"metrics/compositor_timing_history.h",
+ "metrics/custom_metrics_recorder.cc",
+ "metrics/custom_metrics_recorder.h",
"metrics/dropped_frame_counter.cc",
"metrics/dropped_frame_counter.h",
"metrics/event_latency_tracing_recorder.cc",
"metrics/event_latency_tracing_recorder.h",
+ "metrics/event_latency_tracker.cc",
+ "metrics/event_latency_tracker.h",
"metrics/event_metrics.cc",
"metrics/event_metrics.h",
"metrics/events_metrics_manager.cc",
@@ -905,14 +909,15 @@ cc_test("cc_unittests") {
}
if (is_fuchsia) {
- use_cfv2 = false
- additional_manifest_fragments = [
- "//build/config/fuchsia/test/font_capabilities.test-cmx",
+ use_cfv1 = false
- # TODO(crbug.com/1185811): Figure out why jit_capabilities is needed.
- "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+ # TODO(https://crbug.com/1185811): Investigate removing the requirement for
+ # job_policy_ambient_mark_vmo_exec for the sake of V8's allocator in tests.
+ test_runner_shard = "//build/config/fuchsia/test/elf_test_ambient_exec_runner.shard.test-cml"
- "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/fonts.shard.test-cml",
+ "//third_party/fuchsia-sdk/sdk/pkg/vulkan/client.shard.cml",
]
}
@@ -993,9 +998,6 @@ if (is_android) {
# Right now, this only includes the Java switches. But if we need more Java
# files, they should be added here as necessary.
srcjar_deps = [ ":cc_android_java_enums_srcjar" ]
- deps = [
- "//base:base_java",
- "//third_party/androidx:androidx_annotation_annotation_java",
- ]
+ deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
}
}
diff --git a/chromium/cc/DEPS b/chromium/cc/DEPS
index 55466a8233c..ae56e384462 100644
--- a/chromium/cc/DEPS
+++ b/chromium/cc/DEPS
@@ -21,7 +21,6 @@ include_rules = [
"+gpu/command_buffer/common/shared_image_trace_utils.h",
"+gpu/command_buffer/common/shared_image_usage.h",
"+gpu/command_buffer/common/sync_token.h",
- "+gpu/command_buffer/common/texture_in_use_response.h",
"+gpu/config/gpu_feature_info.h",
"+gpu/config/gpu_finch_features.h",
"+gpu/config/gpu_info.h",
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index 172a0c0989d..e695df24414 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -15,6 +15,7 @@ ccameron@chromium.org
# scheduling / begin frames
sunnyps@chromium.org
+szager@chromium.org
# tiles, tile management, and raster work
vmpstr@chromium.org
@@ -28,7 +29,6 @@ flackr@chromium.org
# property trees
chrishtr@chromium.org
-weiliangc@chromium.org
pdr@chromium.org
wangxianzhu@chromium.org
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index d64a61535dd..18926560de3 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -154,6 +154,15 @@ void AnimationHost::SetHasSmilAnimation(bool has_smil_animation) {
has_smil_animation_.Write(*this) = has_smil_animation;
}
+bool AnimationHost::HasSharedElementTransition() const {
+ return has_shared_element_transition_.Read(*this);
+}
+
+void AnimationHost::SetHasSharedElementTransition(
+ bool has_shared_element_transition) {
+ has_shared_element_transition_.Write(*this) = has_shared_element_transition;
+}
+
void AnimationHost::SetCurrentFrameHadRaf(bool current_frame_had_raf) {
current_frame_had_raf_.Write(*this) = current_frame_had_raf;
}
@@ -179,6 +188,7 @@ void AnimationHost::RemoveElementId(ElementId element_id) {
scoped_refptr<ElementAnimations> element_animations =
GetElementAnimationsForElementId(element_id);
if (element_animations) {
+ DCHECK(!element_animations->HasTickingKeyframeEffect());
element_animations->RemoveKeyframeEffects();
}
}
@@ -187,6 +197,26 @@ void AnimationHost::RegisterAnimationForElement(ElementId element_id,
Animation* animation) {
DCHECK(element_id);
DCHECK(animation);
+#if DCHECK_IS_ON()
+ for (const auto& keyframe_model :
+ animation->keyframe_effect()->keyframe_models()) {
+ KeyframeModel* cc_keyframe_model =
+ KeyframeModel::ToCcKeyframeModel(keyframe_model.get());
+ ElementId model_element_id = cc_keyframe_model->element_id()
+ ? cc_keyframe_model->element_id()
+ : element_id;
+ DCHECK(cc_keyframe_model->affects_active_elements() ||
+ cc_keyframe_model->affects_pending_elements());
+ DCHECK(!cc_keyframe_model->affects_active_elements() ||
+ mutator_host_client()->IsElementInPropertyTrees(
+ model_element_id, ElementListType::ACTIVE));
+ // Test thread_instance_ because LayerTreeHost has no pending tree.
+ DCHECK(thread_instance_ == ThreadInstance::MAIN ||
+ !cc_keyframe_model->affects_pending_elements() ||
+ mutator_host_client()->IsElementInPropertyTrees(
+ model_element_id, ElementListType::PENDING));
+ }
+#endif
scoped_refptr<ElementAnimations> element_animations =
GetElementAnimationsForElementId(element_id);
@@ -307,6 +337,7 @@ void AnimationHost::PushPropertiesTo(MutatorHost* mutator_host_impl,
host_impl->SetHasCanvasInvalidation(HasCanvasInvalidation());
host_impl->SetHasInlineStyleMutation(HasJSAnimation());
host_impl->SetHasSmilAnimation(HasSmilAnimation());
+ host_impl->SetHasSharedElementTransition(HasSharedElementTransition());
if (needs_push_properties()) {
needs_push_properties_.Write(*this) = false;
@@ -609,81 +640,23 @@ bool AnimationHost::ScrollOffsetAnimationWasInterrupted(
: false;
}
-bool AnimationHost::IsAnimatingFilterProperty(ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsCurrentlyAnimatingProperty(
- TargetProperty::FILTER, list_type)
- : false;
-}
-
-bool AnimationHost::IsAnimatingBackdropFilterProperty(
- ElementId element_id,
- ElementListType list_type) const {
+bool AnimationHost::IsAnimatingProperty(ElementId element_id,
+ ElementListType list_type,
+ TargetProperty::Type property) const {
auto element_animations = GetElementAnimationsForElementId(element_id);
return element_animations ? element_animations->IsCurrentlyAnimatingProperty(
- TargetProperty::BACKDROP_FILTER, list_type)
+ property, list_type)
: false;
}
-bool AnimationHost::IsAnimatingOpacityProperty(
- ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsCurrentlyAnimatingProperty(
- TargetProperty::OPACITY, list_type)
- : false;
-}
-
-bool AnimationHost::IsAnimatingTransformProperty(
- ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsCurrentlyAnimatingProperty(
- TargetProperty::TRANSFORM, list_type)
- : false;
-}
-
-bool AnimationHost::HasPotentiallyRunningFilterAnimation(
+bool AnimationHost::HasPotentiallyRunningAnimationForProperty(
ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsPotentiallyAnimatingProperty(
- TargetProperty::FILTER, list_type)
- : false;
-}
-
-bool AnimationHost::HasPotentiallyRunningBackdropFilterAnimation(
- ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsPotentiallyAnimatingProperty(
- TargetProperty::BACKDROP_FILTER, list_type)
- : false;
-}
-
-bool AnimationHost::HasPotentiallyRunningOpacityAnimation(
- ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations
- ? element_animations->IsPotentiallyAnimatingProperty(
- TargetProperty::OPACITY, list_type)
- : false;
-}
-
-bool AnimationHost::HasPotentiallyRunningTransformAnimation(
- ElementId element_id,
- ElementListType list_type) const {
+ ElementListType list_type,
+ TargetProperty::Type property) const {
auto element_animations = GetElementAnimationsForElementId(element_id);
return element_animations
- ? element_animations->IsPotentiallyAnimatingProperty(
- TargetProperty::TRANSFORM, list_type)
+ ? element_animations->IsPotentiallyAnimatingProperty(property,
+ list_type)
: false;
}
@@ -694,7 +667,8 @@ bool AnimationHost::HasAnyAnimationTargetingProperty(
if (!element_animations)
return false;
- return element_animations->HasAnyAnimationTargetingProperty(property);
+ return element_animations->HasAnyAnimationTargetingProperty(property,
+ element_id);
}
bool AnimationHost::AnimationsPreserveAxisAlignment(
@@ -708,7 +682,7 @@ bool AnimationHost::AnimationsPreserveAxisAlignment(
float AnimationHost::MaximumScale(ElementId element_id,
ElementListType list_type) const {
if (auto element_animations = GetElementAnimationsForElementId(element_id))
- return element_animations->MaximumScale(list_type);
+ return element_animations->MaximumScale(element_id, list_type);
return kInvalidScale;
}
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
index 08a38b355ad..402c54f77be 100644
--- a/chromium/cc/animation/animation_host.h
+++ b/chromium/cc/animation/animation_host.h
@@ -136,28 +136,14 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const override;
- bool IsAnimatingFilterProperty(ElementId element_id,
- ElementListType list_type) const override;
- bool IsAnimatingBackdropFilterProperty(
- ElementId element_id,
- ElementListType list_type) const override;
- bool IsAnimatingOpacityProperty(ElementId element_id,
- ElementListType list_type) const override;
- bool IsAnimatingTransformProperty(ElementId element_id,
- ElementListType list_type) const override;
+ bool IsAnimatingProperty(ElementId element_id,
+ ElementListType list_type,
+ TargetProperty::Type property) const override;
- bool HasPotentiallyRunningFilterAnimation(
- ElementId element_id,
- ElementListType list_type) const override;
- bool HasPotentiallyRunningBackdropFilterAnimation(
- ElementId element_id,
- ElementListType list_type) const override;
- bool HasPotentiallyRunningOpacityAnimation(
+ bool HasPotentiallyRunningAnimationForProperty(
ElementId element_id,
- ElementListType list_type) const override;
- bool HasPotentiallyRunningTransformAnimation(
- ElementId element_id,
- ElementListType list_type) const override;
+ ElementListType list_type,
+ TargetProperty::Type property) const override;
bool HasAnyAnimationTargetingProperty(
ElementId element_id,
@@ -225,6 +211,7 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
bool HasCanvasInvalidation() const override;
bool HasJSAnimation() const override;
bool HasSmilAnimation() const override;
+ bool HasSharedElementTransition() const override;
// Starts/stops throughput tracking represented by |sequence_id|.
void StartThroughputTracking(TrackedAnimationSequenceId sequence_id);
@@ -234,6 +221,7 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
void SetHasCanvasInvalidation(bool has_canvas_invalidation);
void SetHasInlineStyleMutation(bool has_inline_style_mutation);
void SetHasSmilAnimation(bool has_svg_smil_animation);
+ void SetHasSharedElementTransition(bool hash_shared_element_transition);
void SetCurrentFrameHadRaf(bool current_frame_had_raf);
void SetNextFrameHasPendingRaf(bool next_frame_has_pending_raf);
@@ -298,6 +286,7 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
ProtectedSequenceReadable<bool> has_canvas_invalidation_{false};
ProtectedSequenceReadable<bool> has_inline_style_mutation_{false};
ProtectedSequenceReadable<bool> has_smil_animation_{false};
+ ProtectedSequenceReadable<bool> has_shared_element_transition_{false};
ProtectedSequenceWritable<PendingThroughputTrackerInfos>
pending_throughput_tracker_infos_;
diff --git a/chromium/cc/animation/animation_unittest.cc b/chromium/cc/animation/animation_unittest.cc
index 0454c9b9cb3..42203ab3fb1 100644
--- a/chromium/cc/animation/animation_unittest.cc
+++ b/chromium/cc/animation/animation_unittest.cc
@@ -428,10 +428,12 @@ TEST_F(AnimationTest, AddRemoveAnimationToNonAttachedAnimation) {
EXPECT_TRUE(animation_->keyframe_effect()->element_animations());
EXPECT_FALSE(animation_->keyframe_effect()
->element_animations()
- ->HasAnyAnimationTargetingProperty(TargetProperty::FILTER));
+ ->HasAnyAnimationTargetingProperty(TargetProperty::FILTER,
+ element_id_));
EXPECT_TRUE(animation_->keyframe_effect()
->element_animations()
- ->HasAnyAnimationTargetingProperty(TargetProperty::OPACITY));
+ ->HasAnyAnimationTargetingProperty(TargetProperty::OPACITY,
+ element_id_));
EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
host_->PushPropertiesTo(host_impl_, client_.GetPropertyTrees());
@@ -552,7 +554,7 @@ TEST_F(AnimationTest, ToString) {
EXPECT_EQ(
base::StringPrintf("Animation{id=%d, element_id=%s, "
"keyframe_models=[KeyframeModel{id=42, "
- "group=73, target_property_type=1, "
+ "group=73, target_property_type=4, "
"custom_property_name=, native_property_type=2, "
"run_state=WAITING_FOR_TARGET_AVAILABILITY, "
"element_id=(0)}]}",
@@ -565,10 +567,10 @@ TEST_F(AnimationTest, ToString) {
EXPECT_EQ(base::StringPrintf(
"Animation{id=%d, element_id=%s, "
"keyframe_models=[KeyframeModel{id=42, "
- "group=73, target_property_type=1, custom_property_name=, "
+ "group=73, target_property_type=4, custom_property_name=, "
"native_property_type=2, "
"run_state=WAITING_FOR_TARGET_AVAILABILITY, element_id=(0)}, "
- "KeyframeModel{id=45, group=76, target_property_type=5, "
+ "KeyframeModel{id=45, group=76, target_property_type=8, "
"custom_property_name=, native_property_type=2, "
"run_state=WAITING_FOR_TARGET_AVAILABILITY, element_id=(0)}]}",
animation_->id(), element_id_.ToString().c_str()),
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
index 753e500cf69..153e0997a4f 100644
--- a/chromium/cc/animation/element_animations.cc
+++ b/chromium/cc/animation/element_animations.cc
@@ -60,8 +60,10 @@ ElementAnimations::ElementAnimations(AnimationHost* host, ElementId element_id)
: animation_host_(host),
element_id_(element_id),
needs_push_properties_(false),
- active_maximum_scale_(kInvalidScale),
- pending_maximum_scale_(kInvalidScale) {
+ transform_property_active_maximum_scale_(kInvalidScale),
+ transform_property_pending_maximum_scale_(kInvalidScale),
+ scale_property_active_maximum_scale_(kInvalidScale),
+ scale_property_pending_maximum_scale_(kInvalidScale) {
InitAffectedElementTypes();
}
@@ -77,6 +79,9 @@ void ElementAnimations::InitAffectedElementTypes() {
gfx::TargetProperties ElementAnimations::GetPropertiesMaskForAnimationState() {
gfx::TargetProperties properties;
properties[TargetProperty::TRANSFORM] = true;
+ properties[TargetProperty::SCALE] = true;
+ properties[TargetProperty::ROTATE] = true;
+ properties[TargetProperty::TRANSLATE] = true;
properties[TargetProperty::OPACITY] = true;
properties[TargetProperty::FILTER] = true;
properties[TargetProperty::BACKDROP_FILTER] = true;
@@ -158,11 +163,12 @@ bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
return true;
}
-float ElementAnimations::MaximumScale(ElementListType list_type) const {
+float ElementAnimations::MaximumScale(ElementId element_id,
+ ElementListType list_type) const {
float maximum_scale = kInvalidScale;
for (auto& keyframe_effect : keyframe_effects_list_) {
- maximum_scale =
- std::max(maximum_scale, keyframe_effect.MaximumScale(list_type));
+ maximum_scale = std::max(
+ maximum_scale, keyframe_effect.MaximumScale(element_id, list_type));
}
return maximum_scale;
}
@@ -265,11 +271,34 @@ void ElementAnimations::InitClientAnimationState() {
// (instead of only changed) recalculated current states to the client.
pending_state_.Clear();
active_state_.Clear();
- active_maximum_scale_ = kInvalidScale;
- pending_maximum_scale_ = kInvalidScale;
+ transform_property_active_maximum_scale_ = kInvalidScale;
+ transform_property_pending_maximum_scale_ = kInvalidScale;
+ scale_property_active_maximum_scale_ = kInvalidScale;
+ scale_property_pending_maximum_scale_ = kInvalidScale;
UpdateClientAnimationState();
}
+void ElementAnimations::UpdateMaximumScale(ElementId element_id,
+ ElementListType list_type,
+ float* cached_scale) {
+ if (element_id) {
+ float maximum_scale = MaximumScale(element_id, list_type);
+ if (*cached_scale != maximum_scale) {
+ animation_host_->mutator_host_client()->MaximumScaleChanged(
+ element_id, list_type, maximum_scale);
+ *cached_scale = maximum_scale;
+ }
+ } else {
+ *cached_scale = kInvalidScale;
+ }
+}
+
+#if DCHECK_IS_ON()
+static inline bool IsInvalidOrOne(float scale) {
+ return scale == kInvalidScale || scale == 1.f;
+}
+#endif
+
void ElementAnimations::UpdateClientAnimationState() {
if (!element_id())
return;
@@ -311,6 +340,11 @@ void ElementAnimations::UpdateClientAnimationState() {
PropertyToElementIdMap element_id_map = GetPropertyToElementIdMap();
ElementId transform_element_id = element_id_map[TargetProperty::TRANSFORM];
+ ElementId scale_element_id = element_id_map[TargetProperty::SCALE];
+#if DCHECK_IS_ON()
+ ElementId rotate_element_id = element_id_map[TargetProperty::ROTATE];
+ ElementId translate_element_id = element_id_map[TargetProperty::TRANSLATE];
+#endif
if (prev_active != active_state_) {
PropertyAnimationState diff_active = prev_active ^ active_state_;
@@ -318,14 +352,16 @@ void ElementAnimations::UpdateClientAnimationState() {
element_id_map, ElementListType::ACTIVE, diff_active, active_state_);
}
- float maximum_scale = transform_element_id
- ? MaximumScale(ElementListType::ACTIVE)
- : kInvalidScale;
- if (maximum_scale != active_maximum_scale_) {
- animation_host_->mutator_host_client()->MaximumScaleChanged(
- transform_element_id, ElementListType::ACTIVE, maximum_scale);
- active_maximum_scale_ = maximum_scale;
- }
+ UpdateMaximumScale(transform_element_id, ElementListType::ACTIVE,
+ &transform_property_active_maximum_scale_);
+ UpdateMaximumScale(scale_element_id, ElementListType::ACTIVE,
+ &scale_property_active_maximum_scale_);
+#if DCHECK_IS_ON()
+ DCHECK(
+ IsInvalidOrOne(MaximumScale(rotate_element_id, ElementListType::ACTIVE)));
+ DCHECK(IsInvalidOrOne(
+ MaximumScale(translate_element_id, ElementListType::ACTIVE)));
+#endif
if (prev_pending != pending_state_) {
PropertyAnimationState diff_pending = prev_pending ^ pending_state_;
@@ -333,13 +369,16 @@ void ElementAnimations::UpdateClientAnimationState() {
element_id_map, ElementListType::PENDING, diff_pending, pending_state_);
}
- maximum_scale = transform_element_id ? MaximumScale(ElementListType::PENDING)
- : kInvalidScale;
- if (maximum_scale != pending_maximum_scale_) {
- animation_host_->mutator_host_client()->MaximumScaleChanged(
- transform_element_id, ElementListType::PENDING, maximum_scale);
- pending_maximum_scale_ = maximum_scale;
- }
+ UpdateMaximumScale(transform_element_id, ElementListType::PENDING,
+ &transform_property_pending_maximum_scale_);
+ UpdateMaximumScale(scale_element_id, ElementListType::PENDING,
+ &scale_property_pending_maximum_scale_);
+#if DCHECK_IS_ON()
+ DCHECK(IsInvalidOrOne(
+ MaximumScale(rotate_element_id, ElementListType::PENDING)));
+ DCHECK(IsInvalidOrOne(
+ MaximumScale(translate_element_id, ElementListType::PENDING)));
+#endif
}
void ElementAnimations::AttachToCurve(gfx::AnimationCurve* c) {
@@ -386,10 +425,12 @@ bool ElementAnimations::HasAnyKeyframeModel() const {
}
bool ElementAnimations::HasAnyAnimationTargetingProperty(
- TargetProperty::Type property) const {
+ TargetProperty::Type property,
+ ElementId element_id) const {
for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.GetKeyframeModel(property))
- return true;
+ if (gfx::KeyframeModel* model = keyframe_effect.GetKeyframeModel(property))
+ if (CalculateTargetElementId(this, model) == element_id)
+ return true;
}
return false;
}
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
index 10e25656f14..bdede8ebe86 100644
--- a/chromium/cc/animation/element_animations.h
+++ b/chromium/cc/animation/element_animations.h
@@ -80,7 +80,8 @@ class CC_ANIMATION_EXPORT ElementAnimations
// Returns true if there are any KeyframeModels at all to process.
bool HasAnyKeyframeModel() const;
- bool HasAnyAnimationTargetingProperty(TargetProperty::Type property) const;
+ bool HasAnyAnimationTargetingProperty(TargetProperty::Type property,
+ ElementId element_id) const;
// Returns true if there is an animation that is either currently animating
// the given property or scheduled to animate this property in the future, and
@@ -98,7 +99,7 @@ class CC_ANIMATION_EXPORT ElementAnimations
// Returns the maximum scale along any dimension at any destination in active
// scale animations, or kInvalidScale if there is no active transform
// animation or the scale cannot be computed.
- float MaximumScale(ElementListType list_type) const;
+ float MaximumScale(ElementId element_id, ElementListType list_type) const;
bool ScrollOffsetAnimationWasInterrupted() const;
@@ -187,6 +188,10 @@ class CC_ANIMATION_EXPORT ElementAnimations
static gfx::TargetProperties GetPropertiesMaskForAnimationState();
+ void UpdateMaximumScale(ElementId element_id,
+ ElementListType list_type,
+ float* cached_scale);
+
void UpdateKeyframeEffectsTickingState() const;
void RemoveKeyframeEffectsFromTicking() const;
@@ -203,8 +208,10 @@ class CC_ANIMATION_EXPORT ElementAnimations
PropertyAnimationState active_state_;
PropertyAnimationState pending_state_;
- float active_maximum_scale_;
- float pending_maximum_scale_;
+ float transform_property_active_maximum_scale_;
+ float transform_property_pending_maximum_scale_;
+ float scale_property_active_maximum_scale_;
+ float scale_property_pending_maximum_scale_;
};
} // namespace cc
diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc
index 021004ae4c3..63d3e3d442b 100644
--- a/chromium/cc/animation/element_animations_unittest.cc
+++ b/chromium/cc/animation/element_animations_unittest.cc
@@ -695,6 +695,66 @@ TEST_F(ElementAnimationsTest, AnimationsAreDeleted) {
EXPECT_FALSE(animation_impl_->keyframe_effect()->has_any_keyframe_model());
}
+// Test an animation that finishes on impl but is deleted on main before the
+// event is received. https://crbug.com/1325393.
+TEST_F(ElementAnimationsTest, AnimationFinishedOnImplDeletedOnMain) {
+ CreateTestLayer(true, false);
+ AttachTimelineAnimationLayer();
+ CreateImplTimelineAndAnimation();
+
+ auto events = CreateEventsForTesting();
+
+ AddOpacityTransitionToAnimation(animation_.get(), 1.0, 0.0f, 1.0f, false);
+ animation_->Tick(kInitialTickTime);
+ animation_->UpdateState(true, nullptr);
+ EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
+
+ PushProperties();
+ EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
+
+ animation_impl_->ActivateKeyframeModels();
+
+ animation_impl_->Tick(kInitialTickTime + base::Milliseconds(500));
+ animation_impl_->UpdateState(true, events.get());
+
+ // There should be a STARTED event for the animation.
+ EXPECT_EQ(1u, events->events_.size());
+ EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
+
+ events = CreateEventsForTesting();
+ animation_impl_->Tick(kInitialTickTime + base::Milliseconds(2000));
+ animation_impl_->UpdateState(true, events.get());
+
+ EXPECT_TRUE(host_impl_->needs_push_properties());
+
+ // There should be a FINISHED event for the animation.
+ EXPECT_EQ(1u, events->events_.size());
+ EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type);
+
+ // Before the FINISHED event is received, main aborts the keyframe
+ // and detaches the element.
+ animation_->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY, false);
+ PushProperties();
+ animation_->DetachElement();
+ // Expect no keyframe model.
+ EXPECT_FALSE(animation_->keyframe_effect()->has_any_keyframe_model());
+
+ // Then we dispatch the FINISHED event.
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
+
+ EXPECT_TRUE(host_->needs_push_properties());
+
+ PushProperties();
+
+ // Both animations should now have deleted the animation. The impl animations
+ // should have deleted the animation even though activation has not occurred,
+ // since the animation was already waiting for deletion when
+ // PushPropertiesTo was called.
+ EXPECT_FALSE(animation_->keyframe_effect()->has_any_keyframe_model());
+ EXPECT_FALSE(animation_impl_->keyframe_effect()->has_any_keyframe_model());
+}
+
// Tests that transitioning opacity from 0 to 1 works as expected.
static std::unique_ptr<KeyframeModel> CreateKeyframeModel(
@@ -2174,10 +2234,10 @@ TEST_F(ElementAnimationsTest, MaximumAnimationScaleNotScaled) {
AttachTimelineAnimationLayer();
CreateImplTimelineAndAnimation();
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
animation_impl_->AddKeyframeModel(
CreateKeyframeModel(std::unique_ptr<gfx::AnimationCurve>(
@@ -2185,10 +2245,10 @@ TEST_F(ElementAnimationsTest, MaximumAnimationScaleNotScaled) {
1, TargetProperty::OPACITY));
// Opacity animations aren't non-translation transforms.
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
std::unique_ptr<gfx::KeyframedTransformAnimationCurve> curve1(
gfx::KeyframedTransformAnimationCurve::Create());
@@ -2206,10 +2266,10 @@ TEST_F(ElementAnimationsTest, MaximumAnimationScaleNotScaled) {
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
// The only transform animation we've added is a translation.
- EXPECT_EQ(1.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(1.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(1.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(1.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
}
TEST_F(ElementAnimationsTest, MaximumAnimationNonCalculatableScale) {
@@ -2236,10 +2296,10 @@ TEST_F(ElementAnimationsTest, MaximumAnimationNonCalculatableScale) {
// All keyframes have perspective, so the ElementAnimations' scale is not
// calculatable.
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
}
TEST_F(ElementAnimationsTest, MaximumAnimationPartialNonCalculatableScale) {
@@ -2265,10 +2325,10 @@ TEST_F(ElementAnimationsTest, MaximumAnimationPartialNonCalculatableScale) {
// Though some keyframes have perspective and the scale is not calculatable,
// we use the other keyframes to calculate the ElementAnimations' scale.
- EXPECT_EQ(2.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(2.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(2.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(2.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
}
TEST_F(ElementAnimationsTest, MaximumScale) {
@@ -2293,16 +2353,16 @@ TEST_F(ElementAnimationsTest, MaximumScale) {
keyframe_model->set_affects_active_elements(false);
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
- EXPECT_EQ(5.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(5.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
animation_impl_->ActivateKeyframeModels();
- EXPECT_EQ(5.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(5.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(5.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(5.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
std::unique_ptr<gfx::KeyframedTransformAnimationCurve> curve2(
gfx::KeyframedTransformAnimationCurve::Create());
@@ -2344,25 +2404,25 @@ TEST_F(ElementAnimationsTest, MaximumScale) {
keyframe_model->set_affects_active_elements(false);
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(kInvalidScale,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(kInvalidScale, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
animation_impl_->ActivateKeyframeModels();
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
animation_impl_->keyframe_effect()->GetKeyframeModelById(2)->SetRunState(
KeyframeModel::FINISHED, TicksFromSecondsF(0.0));
// Only unfinished animations should be considered by MaximumAnimationScale.
- EXPECT_EQ(5.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(5.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(5.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(5.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
}
TEST_F(ElementAnimationsTest, MaximumAnimationScaleWithDirection) {
@@ -2391,61 +2451,61 @@ TEST_F(ElementAnimationsTest, MaximumAnimationScaleWithDirection) {
// NORMAL direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::NORMAL);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// ALTERNATE direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::ALTERNATE_NORMAL);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// REVERSE direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// ALTERNATE reverse direction.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
keyframe_model->set_playback_rate(-1.0);
// NORMAL direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::NORMAL);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// ALTERNATE direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::ALTERNATE_NORMAL);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// REVERSE direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
// ALTERNATE reverse direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::PENDING));
- EXPECT_EQ(6.f,
- element_animations_impl_->MaximumScale(ElementListType::ACTIVE));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::PENDING));
+ EXPECT_EQ(6.f, element_animations_impl_->MaximumScale(
+ element_id_, ElementListType::ACTIVE));
}
TEST_F(ElementAnimationsTest, NewlyPushedAnimationWaitsForActivation) {
diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc
index e9a1090934d..804d1c52449 100644
--- a/chromium/cc/animation/keyframe_effect.cc
+++ b/chromium/cc/animation/keyframe_effect.cc
@@ -67,10 +67,15 @@ KeyframeEffect::~KeyframeEffect() {
void KeyframeEffect::SetNeedsPushProperties() {
needs_push_properties_ = true;
+ // The keyframe effect may have been removed from the main thread while
+ // an event was in flight from the compositor. In this case, we may need
+ // to push the removal to the compositor but do not expect to have a bound
+ // element animations instance.
// TODO(smcgruer): We only need the below calls when needs_push_properties_
// goes from false to true - see http://crbug.com/764405
- DCHECK(element_animations());
- element_animations_->SetNeedsPushProperties();
+ if (element_animations()) {
+ element_animations_->SetNeedsPushProperties();
+ }
animation_->SetNeedsPushProperties();
}
@@ -443,7 +448,8 @@ bool KeyframeEffect::AnimationsPreserveAxisAlignment() const {
return true;
}
-float KeyframeEffect::MaximumScale(ElementListType list_type) const {
+float KeyframeEffect::MaximumScale(ElementId element_id,
+ ElementListType list_type) const {
float maximum_scale = kInvalidScale;
for (const auto& keyframe_model : keyframe_models()) {
if (keyframe_model->is_finished())
@@ -452,6 +458,12 @@ float KeyframeEffect::MaximumScale(ElementListType list_type) const {
auto* cc_keyframe_model =
KeyframeModel::ToCcKeyframeModel(keyframe_model.get());
+ ElementId model_element_id = cc_keyframe_model->element_id();
+ if (!model_element_id)
+ model_element_id = element_id_;
+ if (model_element_id != element_id)
+ continue;
+
if ((list_type == ElementListType::ACTIVE &&
!cc_keyframe_model->affects_active_elements()) ||
(list_type == ElementListType::PENDING &&
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index 45cb8cf3eb5..1ce30ccd2a0 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -120,7 +120,7 @@ class CC_ANIMATION_EXPORT KeyframeEffect : public gfx::KeyframeEffect {
// Returns the maximum scale along any dimension at any destination in active
// scale animations, or kInvalidScale if there is no active transform
// animation or the scale cannot be computed.
- float MaximumScale(ElementListType) const;
+ float MaximumScale(ElementId, ElementListType) const;
// Returns true if there is a keyframe_model that is either currently
// animating the given property or scheduled to animate this property in the
diff --git a/chromium/cc/animation/keyframe_model_unittest.cc b/chromium/cc/animation/keyframe_model_unittest.cc
index 8d95bcda0d0..32edc756ed2 100644
--- a/chromium/cc/animation/keyframe_model_unittest.cc
+++ b/chromium/cc/animation/keyframe_model_unittest.cc
@@ -1385,7 +1385,7 @@ TEST(KeyframeModelTest, ToString) {
std::make_unique<FakeFloatAnimationCurve>(15), 42, 73,
KeyframeModel::TargetPropertyId(TargetProperty::OPACITY));
EXPECT_EQ(base::StringPrintf(
- "KeyframeModel{id=%d, group=73, target_property_type=1, "
+ "KeyframeModel{id=%d, group=73, target_property_type=4, "
"custom_property_name=, native_property_type=2, "
"run_state=WAITING_FOR_TARGET_AVAILABILITY, element_id=(0)}",
keyframe_model->id()),
diff --git a/chromium/cc/base/list_container_helper.cc b/chromium/cc/base/list_container_helper.cc
index 319f0d6c0b7..70e5c1af765 100644
--- a/chromium/cc/base/list_container_helper.cc
+++ b/chromium/cc/base/list_container_helper.cc
@@ -13,6 +13,7 @@
#include "base/check_op.h"
#include "base/memory/aligned_memory.h"
+#include "base/memory/raw_ptr_exclusion.h"
namespace {
const size_t kDefaultNumElementTypesToReserve = 32;
@@ -265,7 +266,7 @@ class ListContainerHelper::CharAllocator {
//
// `last_list_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- InnerList* last_list_;
+ RAW_PTR_EXCLUSION InnerList* last_list_;
};
// PositionInCharAllocator
diff --git a/chromium/cc/base/list_container_helper.h b/chromium/cc/base/list_container_helper.h
index 1b34ca790ae..8df56ebd7ee 100644
--- a/chromium/cc/base/list_container_helper.h
+++ b/chromium/cc/base/list_container_helper.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "base/memory/raw_ptr_exclusion.h"
#include "cc/base/base_export.h"
namespace cc {
@@ -38,13 +39,13 @@ class CC_BASE_EXPORT ListContainerHelper final {
struct CC_BASE_EXPORT PositionInCharAllocator {
// `ptr_to_container` is not a raw_ptr<...> for performance reasons (based
// on analysis of sampling profiler data and tab_search:top100:2020).
- CharAllocator* ptr_to_container;
+ RAW_PTR_EXCLUSION CharAllocator* ptr_to_container;
size_t vector_index;
// `item_iterator` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- char* item_iterator;
+ RAW_PTR_EXCLUSION char* item_iterator;
PositionInCharAllocator(const PositionInCharAllocator& other);
PositionInCharAllocator& operator=(const PositionInCharAllocator& other);
diff --git a/chromium/cc/base/math_util.cc b/chromium/cc/base/math_util.cc
index 1aed6c19f96..7c700f83238 100644
--- a/chromium/cc/base/math_util.cc
+++ b/chromium/cc/base/math_util.cc
@@ -1007,6 +1007,7 @@ void MathUtil::AddCornerRadiiToTracedValue(
res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerRight).y());
res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerLeft).x());
res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerLeft).y());
+ res->EndArray();
}
void MathUtil::AddToTracedValue(const char* name,
diff --git a/chromium/cc/base/math_util.h b/chromium/cc/base/math_util.h
index a29fc4986a3..02aaebdc01f 100644
--- a/chromium/cc/base/math_util.h
+++ b/chromium/cc/base/math_util.h
@@ -5,22 +5,18 @@
#ifndef CC_BASE_MATH_UTIL_H_
#define CC_BASE_MATH_UTIL_H_
+#include <cmath>
#include <limits>
-#include <memory>
-#include <vector>
#include "base/check.h"
#include "base/cxx17_backports.h"
#include "build/build_config.h"
#include "cc/base/base_export.h"
#include "third_party/skia/include/core/SkM44.h"
+#include "third_party/skia/include/core/SkScalar.h"
#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/rounded_corners_f.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/transform.h"
-#include "ui/gfx/geometry/vector2d_f.h"
namespace base {
class Value;
@@ -34,6 +30,7 @@ class QuadF;
class Rect;
class RectF;
class RRectF;
+class Size;
class SizeF;
class Transform;
class Vector2dF;
diff --git a/chromium/cc/base/rtree.h b/chromium/cc/base/rtree.h
index 35f5ebcdf0a..d59c08a7f22 100644
--- a/chromium/cc/base/rtree.h
+++ b/chromium/cc/base/rtree.h
@@ -94,8 +94,8 @@ class RTree {
private:
// These values were empirically determined to produce reasonable performance
// in most cases.
- enum { kMinChildren = 6 };
- enum { kMaxChildren = 11 };
+ static constexpr int kMinChildren = 6;
+ static constexpr int kMaxChildren = 11;
template <typename U>
struct Node;
diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index 81644efb821..db96fd4c515 100644
--- a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -48,7 +48,7 @@ void RunBenchmark(RasterSource* raster_source,
// quantization when the layer is very small.
base::LapTimer timer(kWarmupRuns, base::Milliseconds(kTimeLimitMillis),
kTimeCheckInterval);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
content_rect, 1.f / contents_scale.x(), 1.f / contents_scale.y());
*is_solid_color =
diff --git a/chromium/cc/cc.gni b/chromium/cc/cc.gni
index 651cc7f0f2c..d731f680dbc 100644
--- a/chromium/cc/cc.gni
+++ b/chromium/cc/cc.gni
@@ -23,9 +23,6 @@ template("cc_component") {
}
configs -= cc_remove_configs
configs += cc_add_configs
-
- # TODO(crbug.com/1292951): Remove this line.
- configs -= [ "//build/config/compiler:prevent_unsafe_narrowing" ]
}
}
@@ -40,9 +37,6 @@ template("cc_test_static_library") {
# Not needed in test code.
configs -= [ "//build/config/compiler:wexit_time_destructors" ]
-
- # TODO(crbug.com/1292951): Remove this line.
- configs -= [ "//build/config/compiler:prevent_unsafe_narrowing" ]
}
}
@@ -57,8 +51,5 @@ template("cc_test") {
# Not needed in test code.
configs -= [ "//build/config/compiler:wexit_time_destructors" ]
-
- # TODO(crbug.com/1292951): Remove this line.
- configs -= [ "//build/config/compiler:prevent_unsafe_narrowing" ]
}
}
diff --git a/chromium/cc/debug/debug_colors.cc b/chromium/cc/debug/debug_colors.cc
index a90c7d34c38..6b91453f0e6 100644
--- a/chromium/cc/debug/debug_colors.cc
+++ b/chromium/cc/debug/debug_colors.cc
@@ -16,48 +16,48 @@ static float Scale(float width, float device_scale_factor) {
// ======= Layer border colors =======
// Tiled content layers are orange.
-SkColor DebugColors::TiledContentLayerBorderColor() {
- return SkColorSetARGB(128, 255, 128, 0);
+SkColor4f DebugColors::TiledContentLayerBorderColor() {
+ return {1.0f, 0.5f, 0.0f, 0.5f};
}
int DebugColors::TiledContentLayerBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Image layers are olive.
-SkColor DebugColors::ImageLayerBorderColor() {
- return SkColorSetARGB(128, 128, 128, 0);
+SkColor4f DebugColors::ImageLayerBorderColor() {
+ return {0.5f, 0.5f, 0.0f, 0.5f};
}
int DebugColors::ImageLayerBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Non-tiled content layers area green.
-SkColor DebugColors::ContentLayerBorderColor() {
- return SkColorSetARGB(128, 0, 128, 32);
+SkColor4f DebugColors::ContentLayerBorderColor() {
+ return {0.0f, 0.5f, 32.0f / 255.0f, 0.5f};
}
int DebugColors::ContentLayerBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Other container layers are yellow.
-SkColor DebugColors::ContainerLayerBorderColor() {
- return SkColorSetARGB(192, 255, 255, 0);
+SkColor4f DebugColors::ContainerLayerBorderColor() {
+ return {1.0f, 1.0f, 0.0f, 0.75f};
}
int DebugColors::ContainerLayerBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Surface layers are a blue-ish green.
-SkColor DebugColors::SurfaceLayerBorderColor() {
- return SkColorSetARGB(128, 0, 255, 136);
+SkColor4f DebugColors::SurfaceLayerBorderColor() {
+ return {0.0f, 1.0f, 136.0f / 255.0f, 0.5f};
}
int DebugColors::SurfaceLayerBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Render surfaces are blue.
-SkColor DebugColors::SurfaceBorderColor() {
- return SkColorSetARGB(100, 0, 0, 255);
+SkColor4f DebugColors::SurfaceBorderColor() {
+ return {0.0f, 0.0f, 1.0f, 100.0f / 255.0f};
}
int DebugColors::SurfaceBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
@@ -66,64 +66,64 @@ int DebugColors::SurfaceBorderWidth(float device_scale_factor) {
// ======= Tile colors =======
// High-res tile borders are cyan.
-SkColor DebugColors::HighResTileBorderColor() {
- return SkColorSetARGB(100, 80, 200, 200);
+SkColor4f DebugColors::HighResTileBorderColor() {
+ return {80.0f / 255.0f, 200.0f / 255.0f, 200.0f / 255.0f, 100.0f / 255.0f};
}
int DebugColors::HighResTileBorderWidth(float device_scale_factor) {
return Scale(1, device_scale_factor);
}
// Low-res tile borders are purple.
-SkColor DebugColors::LowResTileBorderColor() {
- return SkColorSetARGB(100, 212, 83, 192);
+SkColor4f DebugColors::LowResTileBorderColor() {
+ return {212.0f / 255.0f, 83.0f / 255.0f, 0.75f, 100.0f / 255.0f};
}
int DebugColors::LowResTileBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Other high-resolution tile borders are yellow.
-SkColor DebugColors::ExtraHighResTileBorderColor() {
- return SkColorSetARGB(100, 239, 231, 20);
+SkColor4f DebugColors::ExtraHighResTileBorderColor() {
+ return {239.0f / 255.0f, 231.0f / 255.0f, 20.0f / 255.0f, 100.0f / 255.0f};
}
int DebugColors::ExtraHighResTileBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Other low-resolution tile borders are green.
-SkColor DebugColors::ExtraLowResTileBorderColor() {
- return SkColorSetARGB(100, 93, 186, 18);
+SkColor4f DebugColors::ExtraLowResTileBorderColor() {
+ return {93.0f / 255.0f, 186.0f / 255.0f, 18.0f / 255.0f, 100.0f / 255.0f};
}
int DebugColors::ExtraLowResTileBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
}
// Missing tile borders are dark grey.
-SkColor DebugColors::MissingTileBorderColor() {
- return SkColorSetARGB(64, 64, 64, 0);
+SkColor4f DebugColors::MissingTileBorderColor() {
+ return {0.25f, 0.25f, 0.0f, 0.25f};
}
int DebugColors::MissingTileBorderWidth(float device_scale_factor) {
return Scale(1, device_scale_factor);
}
// Solid color tile borders are grey.
-SkColor DebugColors::SolidColorTileBorderColor() {
- return SkColorSetARGB(128, 128, 128, 128);
+SkColor4f DebugColors::SolidColorTileBorderColor() {
+ return {0.5f, 0.5f, 0.5f, 0.5f};
}
int DebugColors::SolidColorTileBorderWidth(float device_scale_factor) {
return Scale(1, device_scale_factor);
}
// OOM tile borders are red.
-SkColor DebugColors::OOMTileBorderColor() {
- return SkColorSetARGB(100, 255, 0, 0);
+SkColor4f DebugColors::OOMTileBorderColor() {
+ return {1.0f, 0.0f, 0.0f, 100.0f / 255.0f};
}
int DebugColors::OOMTileBorderWidth(float device_scale_factor) {
return Scale(1, device_scale_factor);
}
// Direct picture borders are chartreuse.
-SkColor DebugColors::DirectPictureBorderColor() {
- return SkColorSetARGB(255, 127, 255, 0);
+SkColor4f DebugColors::DirectPictureBorderColor() {
+ return {127.0f / 255.0f, 1.0f, 0.0f, 1.0f};
}
int DebugColors::DirectPictureBorderWidth(float device_scale_factor) {
return Scale(1, device_scale_factor);
@@ -146,8 +146,8 @@ DebugColors::TintCompositedContentColorTransformMatrix() {
}
// Compressed tile borders are blue.
-SkColor DebugColors::CompressedTileBorderColor() {
- return SkColorSetARGB(100, 20, 20, 240);
+SkColor4f DebugColors::CompressedTileBorderColor() {
+ return {20.0f / 255.0f, 20.0f / 255.0f, 240.0f / 255.0f, 100.0f / 255.0f};
}
int DebugColors::CompressedTileBorderWidth(float device_scale_factor) {
return Scale(2, device_scale_factor);
@@ -156,211 +156,214 @@ int DebugColors::CompressedTileBorderWidth(float device_scale_factor) {
// ======= Checkerboard colors =======
// Non-debug checkerboards are grey.
-SkColor DebugColors::DefaultCheckerboardColor() {
- return SkColorSetRGB(241, 241, 241);
+SkColor4f DebugColors::DefaultCheckerboardColor() {
+ return {241.0f / 255.0f, 241.0f / 255.0f, 241.0f / 255.0f, 1.0f};
}
// Invalidated tiles get sky blue checkerboards.
-SkColor DebugColors::InvalidatedTileCheckerboardColor() {
- return SkColorSetRGB(128, 200, 245);
+SkColor4f DebugColors::InvalidatedTileCheckerboardColor() {
+ return {0.5f, 200.0f / 255.0f, 245.0f / 255.0f, 1.0f};
}
// Evicted tiles get pale red checkerboards.
-SkColor DebugColors::EvictedTileCheckerboardColor() {
- return SkColorSetRGB(255, 200, 200);
+SkColor4f DebugColors::EvictedTileCheckerboardColor() {
+ return {1.0f, 200.0f / 255.0f, 200.0f / 255.0f, 1.0f};
}
// ======= Debug rect colors =======
-static SkColor FadedGreen(int initial_value, int step) {
+static SkColor4f FadedGreen(int initial_value, int step) {
DCHECK_GE(step, 0);
DCHECK_LE(step, DebugColors::kFadeSteps);
int value = step * initial_value / DebugColors::kFadeSteps;
- return SkColorSetARGB(value, 0, 195, 0);
+ return {0.0f, 195.0f / 255.0f, 0.0f, static_cast<float>(value) / 255.0f};
}
// Paint rects in green.
-SkColor DebugColors::PaintRectBorderColor(int step) {
+SkColor4f DebugColors::PaintRectBorderColor(int step) {
return FadedGreen(255, step);
}
int DebugColors::PaintRectBorderWidth() { return 2; }
-SkColor DebugColors::PaintRectFillColor(int step) {
+SkColor4f DebugColors::PaintRectFillColor(int step) {
return FadedGreen(60, step);
}
-static SkColor FadedBlue(int initial_value, int step) {
+static SkColor4f FadedBlue(int initial_value, int step) {
DCHECK_GE(step, 0);
DCHECK_LE(step, DebugColors::kFadeSteps);
int value = step * initial_value / DebugColors::kFadeSteps;
- return SkColorSetARGB(value, 0, 0, 255);
+ return {0.0f, 0.0f, 1.0f, static_cast<float>(value) / 255.0f};
}
/// Layout Shift rects in blue.
-SkColor DebugColors::LayoutShiftRectBorderColor() {
- return SkColorSetARGB(0, 0, 0, 255);
+SkColor4f DebugColors::LayoutShiftRectBorderColor() {
+ return {0.0f, 0.0f, 1.0f, 0.0f};
}
int DebugColors::LayoutShiftRectBorderWidth() {
// We don't want any border showing for the layout shift debug rects so we set
// the border width to be equal to 0.
return 0;
}
-SkColor DebugColors::LayoutShiftRectFillColor(int step) {
+SkColor4f DebugColors::LayoutShiftRectFillColor(int step) {
return FadedBlue(60, step);
}
// Property-changed rects in blue.
-SkColor DebugColors::PropertyChangedRectBorderColor() {
- return SkColorSetARGB(255, 0, 0, 255);
+SkColor4f DebugColors::PropertyChangedRectBorderColor() {
+ return {0.0f, 0.0f, 1.0f, 1.0f};
}
int DebugColors::PropertyChangedRectBorderWidth() { return 2; }
-SkColor DebugColors::PropertyChangedRectFillColor() {
- return SkColorSetARGB(30, 0, 0, 255);
+SkColor4f DebugColors::PropertyChangedRectFillColor() {
+ return {0.0f, 0.0f, 1.0f, 30.0f / 255.0f};
}
// Surface damage rects in yellow-orange.
-SkColor DebugColors::SurfaceDamageRectBorderColor() {
- return SkColorSetARGB(255, 200, 100, 0);
+SkColor4f DebugColors::SurfaceDamageRectBorderColor() {
+ return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 1.0f};
}
int DebugColors::SurfaceDamageRectBorderWidth() { return 2; }
-SkColor DebugColors::SurfaceDamageRectFillColor() {
- return SkColorSetARGB(30, 200, 100, 0);
+SkColor4f DebugColors::SurfaceDamageRectFillColor() {
+ return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 30.0f / 255.0f};
}
// Surface screen space rects in yellow-green.
-SkColor DebugColors::ScreenSpaceLayerRectBorderColor() {
- return SkColorSetARGB(255, 100, 200, 0);
+SkColor4f DebugColors::ScreenSpaceLayerRectBorderColor() {
+ return {100.0f / 255.0f, 200.0f / 255.0f, 0.0f, 1.0f};
}
int DebugColors::ScreenSpaceLayerRectBorderWidth() { return 2; }
-SkColor DebugColors::ScreenSpaceLayerRectFillColor() {
- return SkColorSetARGB(30, 100, 200, 0);
+SkColor4f DebugColors::ScreenSpaceLayerRectFillColor() {
+ return {100.0f / 255.0f, 200.0f / 255.0f, 0.0f, 30.0f / 255.0f};
}
// Touch-event-handler rects in yellow.
-SkColor DebugColors::TouchEventHandlerRectBorderColor() {
- return SkColorSetARGB(255, 239, 229, 60);
+SkColor4f DebugColors::TouchEventHandlerRectBorderColor() {
+ return {239.0f / 255.0f, 229.0f / 255.0f, 60.0f / 255.0f, 1.0f};
}
int DebugColors::TouchEventHandlerRectBorderWidth() { return 2; }
-SkColor DebugColors::TouchEventHandlerRectFillColor() {
- return SkColorSetARGB(30, 239, 229, 60);
+SkColor4f DebugColors::TouchEventHandlerRectFillColor() {
+ return {239.0f / 255.0f, 229.0f / 255.0f, 60.0f / 255.0f, 30.0f / 255.0f};
}
// Wheel-event-handler rects in green.
-SkColor DebugColors::WheelEventHandlerRectBorderColor() {
- return SkColorSetARGB(255, 189, 209, 57);
+SkColor4f DebugColors::WheelEventHandlerRectBorderColor() {
+ return {189.0f / 255.0f, 209.0f / 255.0f, 57.0f / 255.0f, 1.0f};
}
int DebugColors::WheelEventHandlerRectBorderWidth() { return 2; }
-SkColor DebugColors::WheelEventHandlerRectFillColor() {
- return SkColorSetARGB(30, 189, 209, 57);
+SkColor4f DebugColors::WheelEventHandlerRectFillColor() {
+ return {189.0f / 255.0f, 209.0f / 255.0f, 57.0f / 255.0f, 30.0f / 255.0f};
}
// Scroll-event-handler rects in teal.
-SkColor DebugColors::ScrollEventHandlerRectBorderColor() {
- return SkColorSetARGB(255, 24, 167, 181);
+SkColor4f DebugColors::ScrollEventHandlerRectBorderColor() {
+ return {24.0f / 255.0f, 167.0f / 255.0f, 181.0f / 255.0f, 1.0f};
}
int DebugColors::ScrollEventHandlerRectBorderWidth() { return 2; }
-SkColor DebugColors::ScrollEventHandlerRectFillColor() {
- return SkColorSetARGB(30, 24, 167, 181);
+SkColor4f DebugColors::ScrollEventHandlerRectFillColor() {
+ return {24.0f / 255.0f, 167.0f / 255.0f, 181.0f / 255.0f, 30.0f / 255.0f};
}
// Non-fast-scrollable rects in orange.
-SkColor DebugColors::NonFastScrollableRectBorderColor() {
- return SkColorSetARGB(255, 238, 163, 59);
+SkColor4f DebugColors::NonFastScrollableRectBorderColor() {
+ return {238.0f / 255.0f, 163.0f / 255.0f, 59.0f / 255.0f, 1.0f};
}
int DebugColors::NonFastScrollableRectBorderWidth() { return 2; }
-SkColor DebugColors::NonFastScrollableRectFillColor() {
- return SkColorSetARGB(30, 238, 163, 59);
+SkColor4f DebugColors::NonFastScrollableRectFillColor() {
+ return {238.0f / 255.0f, 163.0f / 255.0f, 59.0f / 255.0f, 30.0f / 255.0f};
}
// Main-thread scrolling reason rects in yellow-orange.
-SkColor DebugColors::MainThreadScrollingReasonRectBorderColor() {
- return SkColorSetARGB(255, 200, 100, 0);
+SkColor4f DebugColors::MainThreadScrollingReasonRectBorderColor() {
+ return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 1.0f};
}
int DebugColors::MainThreadScrollingReasonRectBorderWidth() {
return 2;
}
-SkColor DebugColors::MainThreadScrollingReasonRectFillColor() {
- return SkColorSetARGB(30, 200, 100, 0);
+SkColor4f DebugColors::MainThreadScrollingReasonRectFillColor() {
+ return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 30.0f / 255.0f};
}
// Animation bounds are lime-green.
-SkColor DebugColors::LayerAnimationBoundsBorderColor() {
- return SkColorSetARGB(255, 112, 229, 0);
+SkColor4f DebugColors::LayerAnimationBoundsBorderColor() {
+ return {112.0f / 255.0f, 229.0f / 255.0f, 0.0f, 1.0f};
}
int DebugColors::LayerAnimationBoundsBorderWidth() { return 2; }
-SkColor DebugColors::LayerAnimationBoundsFillColor() {
- return SkColorSetARGB(30, 112, 229, 0);
+SkColor4f DebugColors::LayerAnimationBoundsFillColor() {
+ return {112.0f / 255.0f, 229.0f / 255.0f, 0.0f, 30.0f / 255.0f};
}
// Picture borders in transparent blue.
-SkColor DebugColors::PictureBorderColor() {
- return SkColorSetARGB(100, 0, 0, 200);
+SkColor4f DebugColors::PictureBorderColor() {
+ return {0.0f, 0.0f, 200.0f / 255.0f, 100.0f / 255.0f};
}
// ======= HUD widget colors =======
-SkColor DebugColors::HUDBackgroundColor() {
- return SkColorSetARGB(217, 0, 0, 0);
+SkColor4f DebugColors::HUDBackgroundColor() {
+ return {0.0f, 0.0f, 0.0f, 217.0f / 255.0f};
}
-SkColor DebugColors::HUDSeparatorLineColor() {
- return SkColorSetARGB(64, 0, 255, 0);
+SkColor4f DebugColors::HUDSeparatorLineColor() {
+ return {0.0f, 1.0f, 0.0f, 0.25f};
}
-SkColor DebugColors::HUDIndicatorLineColor() {
- return SK_ColorYELLOW;
+SkColor4f DebugColors::HUDIndicatorLineColor() {
+ return SkColors::kYellow;
}
-SkColor DebugColors::HUDTitleColor() {
- return SkColorSetARGB(255, 232, 232, 232);
+SkColor4f DebugColors::HUDTitleColor() {
+ return {232.0f / 255.0f, 232.0f / 255.0f, 232.0f / 255.0f, 1.0f};
}
-SkColor DebugColors::PlatformLayerTreeTextColor() { return SK_ColorRED; }
-SkColor DebugColors::FPSDisplayTextAndGraphColor() {
- return SK_ColorGREEN;
+SkColor4f DebugColors::PlatformLayerTreeTextColor() {
+ return SkColors::kRed;
+}
+SkColor4f DebugColors::FPSDisplayTextAndGraphColor() {
+ return SkColors::kGreen;
}
// Color used to represent dropped compositor frames.
-SkColor DebugColors::FPSDisplayDroppedFrame() {
- return SkColorSetRGB(202, 91, 29);
+SkColor4f DebugColors::FPSDisplayDroppedFrame() {
+ return {202.0f / 255.0f, 91.0f / 255.0f, 29.0f / 255.0f, 1.0f};
}
// Color used to represent a "partial" frame, i.e. a frame that missed
// its commit deadline.
-SkColor DebugColors::FPSDisplayMissedFrame() {
- return SkColorSetRGB(255, 245, 0);
+SkColor4f DebugColors::FPSDisplayMissedFrame() {
+ return {1.0f, 245.0f / 255.0f, 0.0f, 1.0f};
}
// Color used to represent a frame that successfully rendered.
-SkColor DebugColors::FPSDisplaySuccessfulFrame() {
- return SkColorSetARGB(191, 174, 221, 255);
+SkColor4f DebugColors::FPSDisplaySuccessfulFrame() {
+ return {174.0f / 255.0f, 221.0f / 255.0f, 1.0f, 191.0f / 255.0f};
}
-SkColor DebugColors::MemoryDisplayTextColor() {
- return SK_ColorCYAN;
+SkColor4f DebugColors::MemoryDisplayTextColor() {
+ return SkColors::kCyan;
}
// Paint time display in green (similar to paint times in the WebInspector)
-SkColor DebugColors::PaintTimeDisplayTextAndGraphColor() {
- return SkColorSetRGB(75, 155, 55);
+SkColor4f DebugColors::PaintTimeDisplayTextAndGraphColor() {
+ return {75.0f / 255.0f, 155.0f / 255.0f, 55.0f / 255.0f, 1.0f};
}
-SkColor DebugColors::NonLCDTextHighlightColor(LCDTextDisallowedReason reason) {
+SkColor4f DebugColors::NonLCDTextHighlightColor(
+ LCDTextDisallowedReason reason) {
switch (reason) {
case LCDTextDisallowedReason::kNone:
case LCDTextDisallowedReason::kNoText:
- return SK_ColorTRANSPARENT;
+ return SkColors::kTransparent;
case LCDTextDisallowedReason::kSetting:
- return SkColorSetARGB(96, 128, 255, 0);
+ return {0.5f, 1.0f, 0.0f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kBackgroundColorNotOpaque:
- return SkColorSetARGB(96, 128, 128, 0);
+ return {0.5f, 0.5f, 0.0f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kContentsNotOpaque:
- return SkColorSetARGB(96, 255, 0, 0);
+ return {1.0f, 0.0f, 0.0f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kNonIntegralTranslation:
- return SkColorSetARGB(96, 255, 128, 0);
+ return {1.0f, 0.5f, 0.0f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kNonIntegralXOffset:
case LCDTextDisallowedReason::kNonIntegralYOffset:
- return SkColorSetARGB(96, 255, 0, 128);
+ return {1.0f, 0.0f, 0.5f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kWillChangeTransform:
case LCDTextDisallowedReason::kTransformAnimation:
- return SkColorSetARGB(96, 128, 0, 255);
+ return {0.5f, 0.0f, 1.0f, 96.0f / 255.0f};
case LCDTextDisallowedReason::kPixelOrColorEffect:
- return SkColorSetARGB(96, 0, 128, 0);
+ return {0.0f, 0.5f, 0.0f, 96.0f / 255.0f};
}
NOTREACHED();
- return SK_ColorTRANSPARENT;
+ return SkColors::kTransparent;
}
} // namespace cc
diff --git a/chromium/cc/debug/debug_colors.h b/chromium/cc/debug/debug_colors.h
index 109bb13b2ef..49ad7f389eb 100644
--- a/chromium/cc/debug/debug_colors.h
+++ b/chromium/cc/debug/debug_colors.h
@@ -16,121 +16,121 @@ class CC_DEBUG_EXPORT DebugColors {
public:
DebugColors() = delete;
- static SkColor TiledContentLayerBorderColor();
+ static SkColor4f TiledContentLayerBorderColor();
static int TiledContentLayerBorderWidth(float device_scale_factor);
- static SkColor ImageLayerBorderColor();
+ static SkColor4f ImageLayerBorderColor();
static int ImageLayerBorderWidth(float device_scale_factor);
- static SkColor ContentLayerBorderColor();
+ static SkColor4f ContentLayerBorderColor();
static int ContentLayerBorderWidth(float device_scale_factor);
- static SkColor ContainerLayerBorderColor();
+ static SkColor4f ContainerLayerBorderColor();
static int ContainerLayerBorderWidth(float device_scale_factor);
- static SkColor SurfaceLayerBorderColor();
+ static SkColor4f SurfaceLayerBorderColor();
static int SurfaceLayerBorderWidth(float device_scale_factor);
- static SkColor SurfaceBorderColor();
+ static SkColor4f SurfaceBorderColor();
static int SurfaceBorderWidth(float device_scale_factor);
- static SkColor HighResTileBorderColor();
+ static SkColor4f HighResTileBorderColor();
static int HighResTileBorderWidth(float device_scale_factor);
- static SkColor LowResTileBorderColor();
+ static SkColor4f LowResTileBorderColor();
static int LowResTileBorderWidth(float device_scale_factor);
- static SkColor ExtraHighResTileBorderColor();
+ static SkColor4f ExtraHighResTileBorderColor();
static int ExtraHighResTileBorderWidth(float device_scale_factor);
- static SkColor ExtraLowResTileBorderColor();
+ static SkColor4f ExtraLowResTileBorderColor();
static int ExtraLowResTileBorderWidth(float device_scale_factor);
- static SkColor MissingTileBorderColor();
+ static SkColor4f MissingTileBorderColor();
static int MissingTileBorderWidth(float device_scale_factor);
- static SkColor SolidColorTileBorderColor();
+ static SkColor4f SolidColorTileBorderColor();
static int SolidColorTileBorderWidth(float device_scale_factor);
- static SkColor OOMTileBorderColor();
+ static SkColor4f OOMTileBorderColor();
static int OOMTileBorderWidth(float device_scale_factor);
- static SkColor DirectPictureBorderColor();
+ static SkColor4f DirectPictureBorderColor();
static int DirectPictureBorderWidth(float device_scale_factor);
- static SkColor CompressedTileBorderColor();
+ static SkColor4f CompressedTileBorderColor();
static int CompressedTileBorderWidth(float device_scale_factor);
- static SkColor DefaultCheckerboardColor();
- static SkColor EvictedTileCheckerboardColor();
- static SkColor InvalidatedTileCheckerboardColor();
+ static SkColor4f DefaultCheckerboardColor();
+ static SkColor4f EvictedTileCheckerboardColor();
+ static SkColor4f InvalidatedTileCheckerboardColor();
static const int kFadeSteps = 50;
- static SkColor PaintRectBorderColor(int step);
+ static SkColor4f PaintRectBorderColor(int step);
static int PaintRectBorderWidth();
- static SkColor PaintRectFillColor(int step);
+ static SkColor4f PaintRectFillColor(int step);
- static SkColor LayoutShiftRectBorderColor();
+ static SkColor4f LayoutShiftRectBorderColor();
static int LayoutShiftRectBorderWidth();
- static SkColor LayoutShiftRectFillColor(int step);
+ static SkColor4f LayoutShiftRectFillColor(int step);
- static SkColor PropertyChangedRectBorderColor();
+ static SkColor4f PropertyChangedRectBorderColor();
static int PropertyChangedRectBorderWidth();
- static SkColor PropertyChangedRectFillColor();
+ static SkColor4f PropertyChangedRectFillColor();
- static SkColor SurfaceDamageRectBorderColor();
+ static SkColor4f SurfaceDamageRectBorderColor();
static int SurfaceDamageRectBorderWidth();
- static SkColor SurfaceDamageRectFillColor();
+ static SkColor4f SurfaceDamageRectFillColor();
- static SkColor ScreenSpaceLayerRectBorderColor();
+ static SkColor4f ScreenSpaceLayerRectBorderColor();
static int ScreenSpaceLayerRectBorderWidth();
- static SkColor ScreenSpaceLayerRectFillColor();
+ static SkColor4f ScreenSpaceLayerRectFillColor();
- static SkColor TouchEventHandlerRectBorderColor();
+ static SkColor4f TouchEventHandlerRectBorderColor();
static int TouchEventHandlerRectBorderWidth();
- static SkColor TouchEventHandlerRectFillColor();
+ static SkColor4f TouchEventHandlerRectFillColor();
- static SkColor WheelEventHandlerRectBorderColor();
+ static SkColor4f WheelEventHandlerRectBorderColor();
static int WheelEventHandlerRectBorderWidth();
- static SkColor WheelEventHandlerRectFillColor();
+ static SkColor4f WheelEventHandlerRectFillColor();
- static SkColor ScrollEventHandlerRectBorderColor();
+ static SkColor4f ScrollEventHandlerRectBorderColor();
static int ScrollEventHandlerRectBorderWidth();
- static SkColor ScrollEventHandlerRectFillColor();
+ static SkColor4f ScrollEventHandlerRectFillColor();
- static SkColor NonFastScrollableRectBorderColor();
+ static SkColor4f NonFastScrollableRectBorderColor();
static int NonFastScrollableRectBorderWidth();
- static SkColor NonFastScrollableRectFillColor();
+ static SkColor4f NonFastScrollableRectFillColor();
- static SkColor MainThreadScrollingReasonRectBorderColor();
+ static SkColor4f MainThreadScrollingReasonRectBorderColor();
static int MainThreadScrollingReasonRectBorderWidth();
- static SkColor MainThreadScrollingReasonRectFillColor();
+ static SkColor4f MainThreadScrollingReasonRectFillColor();
- static SkColor LayerAnimationBoundsBorderColor();
+ static SkColor4f LayerAnimationBoundsBorderColor();
static int LayerAnimationBoundsBorderWidth();
- static SkColor LayerAnimationBoundsFillColor();
+ static SkColor4f LayerAnimationBoundsFillColor();
- static SkColor NonPaintedFillColor();
- static SkColor MissingPictureFillColor();
- static SkColor MissingResizeInvalidations();
- static SkColor PictureBorderColor();
+ static SkColor4f NonPaintedFillColor();
+ static SkColor4f MissingPictureFillColor();
+ static SkColor4f MissingResizeInvalidations();
+ static SkColor4f PictureBorderColor();
static base::span<const float> TintCompositedContentColorTransformMatrix();
- static SkColor HUDBackgroundColor();
- static SkColor HUDSeparatorLineColor();
- static SkColor HUDIndicatorLineColor();
- static SkColor HUDTitleColor();
+ static SkColor4f HUDBackgroundColor();
+ static SkColor4f HUDSeparatorLineColor();
+ static SkColor4f HUDIndicatorLineColor();
+ static SkColor4f HUDTitleColor();
- static SkColor PlatformLayerTreeTextColor();
- static SkColor FPSDisplayTextAndGraphColor();
- static SkColor FPSDisplayDroppedFrame();
- static SkColor FPSDisplayMissedFrame();
- static SkColor FPSDisplaySuccessfulFrame();
- static SkColor MemoryDisplayTextColor();
- static SkColor PaintTimeDisplayTextAndGraphColor();
+ static SkColor4f PlatformLayerTreeTextColor();
+ static SkColor4f FPSDisplayTextAndGraphColor();
+ static SkColor4f FPSDisplayDroppedFrame();
+ static SkColor4f FPSDisplayMissedFrame();
+ static SkColor4f FPSDisplaySuccessfulFrame();
+ static SkColor4f MemoryDisplayTextColor();
+ static SkColor4f PaintTimeDisplayTextAndGraphColor();
- static SkColor NonLCDTextHighlightColor(LCDTextDisallowedReason);
+ static SkColor4f NonLCDTextHighlightColor(LCDTextDisallowedReason);
};
} // namespace cc
diff --git a/chromium/cc/input/compositor_input_interfaces.h b/chromium/cc/input/compositor_input_interfaces.h
index dcbd420b2cc..cdc8b4f10d4 100644
--- a/chromium/cc/input/compositor_input_interfaces.h
+++ b/chromium/cc/input/compositor_input_interfaces.h
@@ -57,6 +57,10 @@ class InputDelegateForCompositor {
virtual void RootLayerStateMayHaveChanged() = 0;
// Called to let the input handler know that a scrollbar for the given
+ // elementId has been added.
+ virtual void DidRegisterScrollbar(ElementId scroll_element_id,
+ ScrollbarOrientation orientation) = 0;
+ // Called to let the input handler know that a scrollbar for the given
// elementId has been removed.
virtual void DidUnregisterScrollbar(ElementId scroll_element_id,
ScrollbarOrientation orientation) = 0;
@@ -98,6 +102,7 @@ class CompositorDelegateForInput {
virtual bool HasAnimatedScrollbars() const = 0;
virtual void SetNeedsCommit() = 0;
virtual void SetNeedsFullViewportRedraw() = 0;
+ virtual void SetDeferBeginMainFrame(bool defer_begin_main_frame) const = 0;
virtual void DidUpdateScrollAnimationCurve() = 0;
virtual void AccumulateScrollDeltaForTracing(const gfx::Vector2dF& delta) = 0;
virtual void DidStartPinchZoom() = 0;
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index a242013bb07..ae2ff545aa7 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -94,6 +94,12 @@ struct CC_EXPORT InputHandlerScrollResult {
// scrolling node is the viewport, this would be the sum of the scroll offsets
// of the inner and outer node, representing the visual scroll offset.
gfx::PointF current_visual_offset;
+ // Used only in scroll unification. Tells the caller that we have performed
+ // the scroll (i.e. updated the offset in the scroll tree) on the compositor
+ // thread, but we will need a main thread lifecycle update + commit before
+ // the user will see the new pixels (for example, because the scroller does
+ // not have a composited layer).
+ bool needs_main_thread_repaint = false;
};
class CC_EXPORT InputHandlerClient {
@@ -394,6 +400,11 @@ class CC_EXPORT InputHandler {
// Returns true if ScrollbarController is in the middle of a scroll operation.
virtual bool ScrollbarScrollIsActive() = 0;
+ // Defers posting BeginMainFrame tasks. This is used during the main thread
+ // hit test for a GestureScrollBegin, to avoid posting a frame before the
+ // compositor thread has had a chance to update the scroll offset.
+ virtual void SetDeferBeginMainFrame(bool defer_begin_main_frame) const = 0;
+
protected:
virtual ~InputHandler() = default;
InputHandler() = default;
diff --git a/chromium/cc/input/scrollbar_animation_controller.cc b/chromium/cc/input/scrollbar_animation_controller.cc
index 098d0419e4e..a3eba61f9f8 100644
--- a/chromium/cc/input/scrollbar_animation_controller.cc
+++ b/chromium/cc/input/scrollbar_animation_controller.cc
@@ -55,6 +55,7 @@ ScrollbarAnimationController::ScrollbarAnimationController(
opacity_(initial_opacity),
show_scrollbars_on_scroll_gesture_(false),
need_thinning_animation_(false),
+ need_fade_animation_(true),
is_mouse_down_(false),
tickmarks_showing_(false) {}
@@ -75,6 +76,7 @@ ScrollbarAnimationController::ScrollbarAnimationController(
opacity_(initial_opacity),
show_scrollbars_on_scroll_gesture_(true),
need_thinning_animation_(true),
+ need_fade_animation_(!client->IsFluentScrollbar()),
is_mouse_down_(false),
tickmarks_showing_(false) {
vertical_controller_ = SingleScrollbarAnimationControllerThinning::Create(
@@ -119,6 +121,14 @@ void ScrollbarAnimationController::StopAnimation() {
void ScrollbarAnimationController::PostDelayedAnimation(
AnimationChange animation_change) {
+ // In contrast to Aura overlay scrollbars, Fluent overlay scrollbars
+ // should not fade out completely. After the initial paint, they remain on the
+ // screen in the minimal (thin) mode by default and can expand/transition to
+ // the full (thick) mode. The minimal <-> full mode thinning animation is
+ // controlled by SingleScrollbarAnimationControllerThinning.
+ if (!need_fade_animation_)
+ return;
+
animation_change_ = animation_change;
delayed_scrollbar_animation_.Cancel();
delayed_scrollbar_animation_.Reset(
diff --git a/chromium/cc/input/scrollbar_animation_controller.h b/chromium/cc/input/scrollbar_animation_controller.h
index 5306f0870de..ce4a3f92197 100644
--- a/chromium/cc/input/scrollbar_animation_controller.h
+++ b/chromium/cc/input/scrollbar_animation_controller.h
@@ -27,6 +27,7 @@ class CC_EXPORT ScrollbarAnimationControllerClient {
virtual void SetNeedsAnimateForScrollbarAnimation() = 0;
virtual void DidChangeScrollbarVisibility() = 0;
virtual ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const = 0;
+ virtual bool IsFluentScrollbar() const = 0;
protected:
virtual ~ScrollbarAnimationControllerClient() {}
@@ -156,6 +157,9 @@ class CC_EXPORT ScrollbarAnimationController {
const bool show_scrollbars_on_scroll_gesture_;
const bool need_thinning_animation_;
+ // Controls whether an overlay scrollbar should fade in/out. Should be True
+ // for Aura overlay scrollbars and False for Fluent overlay scrollbars.
+ const bool need_fade_animation_;
bool is_mouse_down_;
diff --git a/chromium/cc/input/scrollbar_animation_controller_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
index 0d4a4a54b50..6069fc44543 100644
--- a/chromium/cc/input/scrollbar_animation_controller_unittest.cc
+++ b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
@@ -34,8 +34,9 @@ const int kThumbThickness = 10;
class MockScrollbarAnimationControllerClient
: public ScrollbarAnimationControllerClient {
public:
- explicit MockScrollbarAnimationControllerClient(LayerTreeHostImpl* host_impl)
- : host_impl_(host_impl) {}
+ explicit MockScrollbarAnimationControllerClient(LayerTreeHostImpl* host_impl,
+ bool is_fluent)
+ : host_impl_(host_impl), is_fluent_(is_fluent) {}
~MockScrollbarAnimationControllerClient() override = default;
void PostDelayedScrollbarAnimationTask(base::OnceClosure start_fade,
@@ -49,6 +50,7 @@ class MockScrollbarAnimationControllerClient
return host_impl_->ScrollbarsFor(scroll_element_id);
}
MOCK_METHOD0(DidChangeScrollbarVisibility, void());
+ bool IsFluentScrollbar() const override { return is_fluent_; }
base::OnceClosure& start_fade() { return start_fade_; }
base::TimeDelta& delay() { return delay_; }
@@ -57,13 +59,15 @@ class MockScrollbarAnimationControllerClient
base::OnceClosure start_fade_;
base::TimeDelta delay_;
raw_ptr<LayerTreeHostImpl> host_impl_;
+ bool is_fluent_;
};
class ScrollbarAnimationControllerAuraOverlayTest
: public LayerTreeImplTestBase,
public testing::Test {
public:
- ScrollbarAnimationControllerAuraOverlayTest() : client_(host_impl()) {}
+ explicit ScrollbarAnimationControllerAuraOverlayTest(bool is_fluent = false)
+ : client_(host_impl(), is_fluent) {}
void ExpectScrollbarsOpacity(float opacity) {
EXPECT_FLOAT_EQ(opacity, v_scrollbar_layer_->Opacity());
@@ -153,6 +157,19 @@ class ScrollbarAnimationControllerAuraOverlayTest
NiceMock<MockScrollbarAnimationControllerClient> client_;
};
+class ScrollbarAnimationControllerFluentOverlayTest
+ : public ScrollbarAnimationControllerAuraOverlayTest {
+ public:
+ ScrollbarAnimationControllerFluentOverlayTest()
+ : ScrollbarAnimationControllerAuraOverlayTest(/* is_fluent */ true) {}
+
+ void SetUp() override {
+ ScrollbarAnimationControllerAuraOverlayTest::SetUp();
+ // Mock initial call for did request show on page load.
+ scrollbar_controller_->DidRequestShow();
+ }
+};
+
// Check initialization of scrollbar. Should start off invisible and thin.
TEST_F(ScrollbarAnimationControllerAuraOverlayTest, Idle) {
ExpectScrollbarsOpacity(0);
@@ -1291,6 +1308,52 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, TickmakrsShowHide) {
EXPECT_EQ(kFadeDelay, client_.delay());
}
+TEST_F(ScrollbarAnimationControllerFluentOverlayTest,
+ FluentScrollbarMinimalModeByDefault) {
+ // An fade out animation should have not been enqueued. Scrollbar stays in
+ // the minimal (thin) mode.
+ EXPECT_TRUE(client_.start_fade().is_null());
+ EXPECT_FLOAT_EQ(kIdleThicknessScale,
+ v_scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(kIdleThicknessScale,
+ h_scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden());
+ ExpectScrollbarsOpacity(1.f);
+}
+
+TEST_F(ScrollbarAnimationControllerFluentOverlayTest,
+ FluentScrollbarMinimalModeOnMouseLeave) {
+ // Move mouse inside scroller.
+ scrollbar_controller_->DidMouseMove(gfx::PointF(50, 50));
+ EXPECT_TRUE(client_.start_fade().is_null());
+ ExpectScrollbarsOpacity(1.f);
+
+ // Trigger mouse leave to check that Fluent overlay scrollbars don't fade out.
+ scrollbar_controller_->DidMouseLeave();
+
+ // An fade out animation should have not been enqueued. Scrollbar stays in
+ // the minimal (thin) mode.
+ EXPECT_TRUE(client_.start_fade().is_null());
+ EXPECT_FLOAT_EQ(kIdleThicknessScale,
+ v_scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(kIdleThicknessScale,
+ h_scrollbar_layer_->thumb_thickness_scale_factor());
+ ExpectScrollbarsOpacity(1.f);
+}
+
+TEST_F(ScrollbarAnimationControllerFluentOverlayTest,
+ FluentScrollbarMinimalModeOnWillUpdateScroll) {
+ // Scrollbar should be visible on scroll will update.
+ scrollbar_controller_->WillUpdateScroll();
+
+ // An fade out animation should have not been enqueued. Scrollbar stays in
+ // the minimal (thin) mode.
+ EXPECT_TRUE(client_.start_fade().is_null());
+ EXPECT_FLOAT_EQ(kIdleThicknessScale,
+ v_scrollbar_layer_->thumb_thickness_scale_factor());
+ ExpectScrollbarsOpacity(1.f);
+}
+
class ScrollbarAnimationControllerAndroidTest
: public LayerTreeImplTestBase,
public testing::Test,
@@ -1314,6 +1377,7 @@ class ScrollbarAnimationControllerAndroidTest
return host_impl()->ScrollbarsFor(scroll_element_id);
}
void DidChangeScrollbarVisibility() override {}
+ bool IsFluentScrollbar() const override { return false; }
protected:
void SetUp() override {
diff --git a/chromium/cc/input/scrollbar_controller.cc b/chromium/cc/input/scrollbar_controller.cc
index e9e7b7f2672..1c5510023c6 100644
--- a/chromium/cc/input/scrollbar_controller.cc
+++ b/chromium/cc/input/scrollbar_controller.cc
@@ -118,23 +118,20 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown(
if (scrollbar_part == ScrollbarPart::THUMB || perform_jump_click_on_track) {
drag_state_ = DragState();
bool clipped = false;
+
drag_state_->drag_origin =
- GetScrollbarRelativePosition(position_in_widget, &clipped);
- // If the point were clipped we shouldn't have hit tested to a valid part.
+ perform_jump_click_on_track
+ ? DragOriginForJumpClick(scrollbar)
+ : GetScrollbarRelativePosition(position_in_widget, &clipped);
+
+ // If the point were clipped we shouldn't have hit tested to a valid
+ // part.
DCHECK(!clipped);
// 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. Additionally, if a thumb drag is
- // being initiated *after* a jump click, scroll_position_at_start_ needs
- // to account for that.
- const float jump_click_thumb_drag_delta =
- scrollbar->orientation() == ScrollbarOrientation::HORIZONTAL
- ? scroll_result.scroll_delta.x()
- : scroll_result.scroll_delta.y();
- drag_state_->scroll_position_at_start_ =
- scrollbar->current_pos() +
- (perform_jump_click_on_track ? jump_click_thumb_drag_delta : 0);
+ // from the track during a thumb drag.
+ drag_state_->scroll_position_at_start_ = scrollbar->current_pos();
drag_state_->scroller_length_at_previous_move =
scrollbar->scroll_layer_length();
}
@@ -145,19 +142,37 @@ 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::CancelableOnceClosure>(base::BindOnce(
- &ScrollbarController::StartAutoScrollAnimation,
- base::Unretained(this),
- InitialDeltaToAutoscrollVelocity(scroll_result.scroll_delta),
- scrollbar_part));
- layer_tree_host_impl_->GetTaskRunner()->PostDelayedTask(
- FROM_HERE, cancelable_autoscroll_task_->callback(),
- kInitialAutoscrollTimerDelay);
+ autoscroll_state_ = AutoScrollState();
+ autoscroll_state_->velocity =
+ InitialDeltaToAutoscrollVelocity(scroll_result.scroll_delta);
+ autoscroll_state_->pressed_scrollbar_part = scrollbar_part;
+ PostAutoscrollTask(kInitialAutoscrollTimerDelay);
}
return scroll_result;
}
+void ScrollbarController::PostAutoscrollTask(const base::TimeDelta delay) {
+ cancelable_autoscroll_task_ =
+ std::make_unique<base::CancelableOnceClosure>(base::BindOnce(
+ &ScrollbarController::StartAutoScroll, base::Unretained(this)));
+ layer_tree_host_impl_->GetTaskRunner()->PostDelayedTask(
+ FROM_HERE, cancelable_autoscroll_task_->callback(), delay);
+}
+
+gfx::PointF ScrollbarController::DragOriginForJumpClick(
+ const ScrollbarLayerImplBase* scrollbar) const {
+ // If the user initiated a jump click, create an artificial drag origin to the
+ // middle of the thumb's current position. This is to simulate a jump click as
+ // though the user had initiated a drag normally and pulled the thumb down to
+ // the jump click position. This also keeps consistency with
+ // scroll_position_at_start_ which is used both to calculate scroll positions
+ // as well as for snapping back to origin if the user moves their mouse away.
+ gfx::Rect thumb = scrollbar->ComputeThumbQuadRect();
+ return scrollbar->orientation() == ScrollbarOrientation::HORIZONTAL
+ ? gfx::PointF(thumb.x() + thumb.width() / 2, 0)
+ : gfx::PointF(0, thumb.y() + thumb.height() / 2);
+}
+
bool ScrollbarController::SnapToDragOrigin(
const gfx::PointF pointer_position_in_widget) const {
// Consult the ScrollbarTheme to check if thumb snapping is supported on the
@@ -450,6 +465,9 @@ float ScrollbarController::GetScrollerToScrollbarRatio() const {
: thumb_rect.width();
float viewport_length = GetViewportLength();
+ if (scrollbar_track_length == scrollbar_thumb_length)
+ return 0;
+
return (scroll_layer_length - viewport_length) /
(scrollbar_track_length - scrollbar_thumb_length);
}
@@ -465,18 +483,36 @@ void ScrollbarController::ResetState() {
}
}
+void ScrollbarController::DidRegisterScrollbar(
+ ElementId element_id,
+ ScrollbarOrientation orientation) {
+ if (autoscroll_state_.has_value() &&
+ captured_scrollbar_metadata_->scroll_element_id == element_id &&
+ captured_scrollbar_metadata_->orientation == orientation &&
+ autoscroll_state_->status == AutoScrollStatus::AUTOSCROLL_READY) {
+ // This is necessary, as when the scrollbar is being registered the layer
+ // tree will not yet have synced its layer properties and cannot update
+ // scrollbar geometries yet. We need to wait until the sync is over
+ PostAutoscrollTask(base::TimeDelta::Min());
+ }
+}
+
void ScrollbarController::DidUnregisterScrollbar(
ElementId element_id,
ScrollbarOrientation orientation) {
- if (captured_scrollbar_metadata_.has_value() &&
+ if (autoscroll_state_.has_value() &&
captured_scrollbar_metadata_->scroll_element_id == element_id &&
- captured_scrollbar_metadata_->orientation == orientation)
- ResetState();
+ captured_scrollbar_metadata_->orientation == orientation &&
+ autoscroll_state_->status == AutoScrollStatus::AUTOSCROLL_SCROLLING) {
+ layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort();
+ autoscroll_state_->status = AutoScrollStatus::AUTOSCROLL_READY;
+ }
}
void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
if (!autoscroll_state_.has_value() ||
- !captured_scrollbar_metadata_.has_value())
+ !captured_scrollbar_metadata_.has_value() ||
+ autoscroll_state_->status != AutoScrollStatus::AUTOSCROLL_SCROLLING)
return;
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
@@ -525,8 +561,7 @@ void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
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,
- autoscroll_state_->pressed_scrollbar_part);
+ StartAutoScrollAnimation();
}
}
@@ -542,8 +577,7 @@ void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
!layer_tree_host_impl_->mutator_host()->IsElementAnimating(
scrollbar->scroll_element_id())) {
// Start animating if pointer re-enters the bounds.
- StartAutoScrollAnimation(autoscroll_state_->velocity,
- autoscroll_state_->pressed_scrollbar_part);
+ StartAutoScrollAnimation();
}
}
@@ -558,15 +592,26 @@ float ScrollbarController::InitialDeltaToAutoscrollVelocity(
return delta * kAutoscrollMultiplier;
}
-void ScrollbarController::StartAutoScrollAnimation(
- const float velocity,
- ScrollbarPart pressed_scrollbar_part) {
+void ScrollbarController::StartAutoScroll() {
+ DCHECK(autoscroll_state_.has_value());
+
+ if (ScrollbarLayer()) {
+ autoscroll_state_->status = AutoScrollStatus::AUTOSCROLL_SCROLLING;
+ StartAutoScrollAnimation();
+ } else {
+ autoscroll_state_->status = AutoScrollStatus::AUTOSCROLL_READY;
+ }
+}
+
+void ScrollbarController::StartAutoScrollAnimation() {
// Autoscroll and thumb drag are mutually exclusive. Both can't be active at
// the same time.
DCHECK(!drag_state_.has_value());
DCHECK(captured_scrollbar_metadata_.has_value());
- DCHECK_NE(velocity, 0);
+ DCHECK(autoscroll_state_.has_value());
DCHECK(ScrollbarLayer());
+ DCHECK_EQ(autoscroll_state_->status, AutoScrollStatus::AUTOSCROLL_SCROLLING);
+ DCHECK_NE(autoscroll_state_->velocity, 0);
// scroll_node is set up while handling GSB. If there's no node to scroll, we
// don't need to create any animation for it.
@@ -589,23 +634,20 @@ void ScrollbarController::StartAutoScrollAnimation(
// Negative scroll velocity indicates backwards scrolling whereas a positive
// value indicates forwards scrolling.
const float target_offset_in_orientation =
- velocity < 0 ? 0 : scroll_layer_length;
+ autoscroll_state_->velocity < 0 ? 0 : scroll_layer_length;
const gfx::PointF target_offset_2d =
scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::PointF(current_offset.x(), target_offset_in_orientation)
: gfx::PointF(target_offset_in_orientation, current_offset.y());
- autoscroll_state_ = AutoScrollState();
- autoscroll_state_->velocity = velocity;
autoscroll_state_->scroll_layer_length = scroll_layer_length;
- autoscroll_state_->pressed_scrollbar_part = pressed_scrollbar_part;
- autoscroll_state_->direction = velocity < 0
+ autoscroll_state_->direction = autoscroll_state_->velocity < 0
? AutoScrollDirection::AUTOSCROLL_BACKWARD
: AutoScrollDirection::AUTOSCROLL_FORWARD;
layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort();
layer_tree_host_impl_->AutoScrollAnimationCreate(
- *scroll_node, target_offset_2d, std::abs(velocity));
+ *scroll_node, target_offset_2d, std::abs(autoscroll_state_->velocity));
}
// Performs hit test and prepares scroll deltas that will be used by GSE.
@@ -620,7 +662,8 @@ InputHandlerPointerResult ScrollbarController::HandlePointerUp(
// TODO(arakeri): This needs to be moved to ScrollOffsetAnimationsImpl as it
// has knowledge about what type of animation is running. crbug.com/976353
// Only abort the animation if it is an "autoscroll" animation.
- if (autoscroll_state_.has_value())
+ if (autoscroll_state_.has_value() &&
+ autoscroll_state_->status == AutoScrollStatus::AUTOSCROLL_SCROLLING)
layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort();
ResetState();
diff --git a/chromium/cc/input/scrollbar_controller.h b/chromium/cc/input/scrollbar_controller.h
index aa5d019c7da..fdaf34df2d1 100644
--- a/chromium/cc/input/scrollbar_controller.h
+++ b/chromium/cc/input/scrollbar_controller.h
@@ -10,6 +10,7 @@
#include "base/cancelable_callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
+#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/input/input_handler.h"
#include "cc/input/scrollbar.h"
@@ -149,6 +150,8 @@ class CC_EXPORT ScrollbarController {
return cancelable_autoscroll_task_ != nullptr;
}
bool ScrollbarScrollIsActive() const { return scrollbar_scroll_is_active_; }
+ void DidRegisterScrollbar(ElementId element_id,
+ ScrollbarOrientation orientation);
void DidUnregisterScrollbar(ElementId element_id,
ScrollbarOrientation orientation);
ScrollbarLayerImplBase* ScrollbarLayer() const;
@@ -161,16 +164,33 @@ class CC_EXPORT ScrollbarController {
ThumbDragAfterJumpClick);
FRIEND_TEST_ALL_PREFIXES(ScrollUnifiedLayerTreeHostImplTest,
AbortAnimatedScrollBeforeStartingAutoscroll);
+ FRIEND_TEST_ALL_PREFIXES(ScrollUnifiedLayerTreeHostImplTest,
+ AutoscrollOnDeletedScrollbar);
+ FRIEND_TEST_ALL_PREFIXES(ScrollUnifiedLayerTreeHostImplTest,
+ ScrollOnLargeThumb);
// "Autoscroll" here means the continuous scrolling that occurs when the
// pointer is held down on a hit-testable area of the scrollbar such as an
// arrows of the track itself.
enum class AutoScrollDirection { AUTOSCROLL_FORWARD, AUTOSCROLL_BACKWARD };
+ enum class AutoScrollStatus {
+ // For when the 250ms delay before an autoscroll starts animating has not
+ // yet elapsed
+ AUTOSCROLL_WAITING,
+ // For when the delay has elapsed, but the autoscroll cannot animate for
+ // some reason (the scrollbar being unregistered)
+ AUTOSCROLL_READY,
+ // For when the autoscroll is animating
+ AUTOSCROLL_SCROLLING
+ };
+
struct CC_EXPORT AutoScrollState {
// Can only be either AUTOSCROLL_FORWARD or AUTOSCROLL_BACKWARD.
AutoScrollDirection direction = AutoScrollDirection::AUTOSCROLL_FORWARD;
+ AutoScrollStatus status = AutoScrollStatus::AUTOSCROLL_WAITING;
+
// Stores the autoscroll velocity. The sign is used to set the "direction".
float velocity = 0.f;
@@ -209,12 +229,17 @@ class CC_EXPORT ScrollbarController {
ScrollbarOrientation orientation;
};
- // "velocity" here is calculated based on the initial scroll delta (See
- // InitialDeltaToAutoscrollVelocity). This value carries a "sign" which is
- // needed to determine whether we should set up the autoscrolling in the
- // forwards or the backwards direction.
- void StartAutoScrollAnimation(float velocity,
- ScrollbarPart pressed_scrollbar_part);
+ // Posts an autoscroll task based on the autoscroll state, with the given
+ // delay
+ void PostAutoscrollTask(const base::TimeDelta delay);
+
+ // Initiates an autoscroll, setting the necessary status and starting the
+ // animation, if possible
+ void StartAutoScroll();
+
+ // Starts/restarts an autoscroll animation based off of the information in
+ // autoscroll_state_
+ void StartAutoScrollAnimation();
// Returns the DSF based on whether use-zoom-for-dsf is enabled.
float ScreenSpaceScaleFactor() const;
@@ -250,8 +275,13 @@ class CC_EXPORT ScrollbarController {
gfx::PointF GetScrollbarRelativePosition(const gfx::PointF position_in_widget,
bool* clipped) const;
- // Decides if the scroller should snap to the offset that it was originally at
- // (i.e the offset before the thumb drag).
+ // Computes an aritificial drag origin for jump clicks, to give the scrollbar
+ // a proper place to snap back to on a jump click then drag
+ gfx::PointF DragOriginForJumpClick(
+ const ScrollbarLayerImplBase* scrollbar) const;
+
+ // 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) const;
// Decides whether a track autoscroll should be aborted (or restarted) due to
@@ -298,7 +328,7 @@ class CC_EXPORT ScrollbarController {
absl::optional<CapturedScrollbarMetadata> captured_scrollbar_metadata_;
// Holds information pertaining to autoscrolling. This member is empty if and
- // only if an autoscroll is *not* in progress.
+ // only if an autoscroll is *not* in progress or scheduled
absl::optional<AutoScrollState> autoscroll_state_;
// Holds information pertaining to thumb drags. Useful while making decisions
diff --git a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
index 6efa8d18db0..ff0221ea9e5 100644
--- a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
+++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
@@ -39,6 +39,7 @@ class MockSingleScrollbarAnimationControllerClient
ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override {
return host_impl_->ScrollbarsFor(scroll_element_id);
}
+ bool IsFluentScrollbar() const override { return false; }
MOCK_METHOD2(PostDelayedScrollbarAnimationTask,
void(base::OnceClosure start_fade, base::TimeDelta delay));
diff --git a/chromium/cc/input/threaded_input_handler.cc b/chromium/cc/input/threaded_input_handler.cc
index 008fd647130..be15f495eaa 100644
--- a/chromium/cc/input/threaded_input_handler.cc
+++ b/chromium/cc/input/threaded_input_handler.cc
@@ -289,11 +289,12 @@ InputHandler::ScrollStatus ThreadedInputHandler::ScrollBegin(
// InputHander::ScrollThread::SCROLL_ON_MAIN_THREAD
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNoScrollingLayer;
- if (compositor_delegate_.GetSettings().is_layer_tree_for_subframe) {
- // OOPIFs never have a viewport scroll node so if we can't scroll
- // we need to be bubble up to the parent frame. This happens by
- // returning SCROLL_IGNORED.
- TRACE_EVENT_INSTANT0("cc", "Ignored - No ScrollNode (OOPIF)",
+ if (compositor_delegate_.GetSettings().is_for_embedded_frame) {
+ // OOPIFs or fenced frames never have a viewport scroll node so if we
+ // can't scroll we need to be bubble up to the parent frame. This happens
+ // by returning SCROLL_IGNORED.
+ TRACE_EVENT_INSTANT0("cc",
+ "Ignored - No ScrollNode (OOPIF or FencedFrame)",
TRACE_EVENT_SCOPE_THREAD);
} else {
// If we didn't hit a layer above we'd usually fallback to the
@@ -375,6 +376,7 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
if (!CurrentlyScrollingNode())
return InputHandlerScrollResult();
+ const ScrollNode& scroll_node = *CurrentlyScrollingNode();
last_scroll_update_state_ = *scroll_state;
// Snap on update if interacting with the scrollbar track or arrow buttons.
@@ -387,7 +389,7 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
}
gfx::Vector2dF resolvedScrollDelta = ResolveScrollGranularityToPixels(
- *CurrentlyScrollingNode(),
+ scroll_node,
gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y()),
scroll_state->delta_granularity());
@@ -406,7 +408,7 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
compositor_delegate_.AccumulateScrollDeltaForTracing(
gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y()));
- compositor_delegate_.WillScrollContent(CurrentlyScrollingNode()->element_id);
+ compositor_delegate_.WillScrollContent(scroll_node.element_id);
float initial_top_controls_offset = compositor_delegate_.GetImplDeprecated()
.browser_controls_manager()
@@ -418,10 +420,12 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
bool did_scroll_y = scroll_state->caused_scroll_y();
did_scroll_x_for_scroll_gesture_ |= did_scroll_x;
did_scroll_y_for_scroll_gesture_ |= did_scroll_y;
+ delta_consumed_for_scroll_gesture_ |=
+ scroll_state->delta_consumed_for_scroll_sequence();
bool did_scroll_content = did_scroll_x || did_scroll_y;
if (did_scroll_content) {
bool is_animated_scroll = ShouldAnimateScroll(*scroll_state);
- compositor_delegate_.DidScrollContent(CurrentlyScrollingNode()->element_id,
+ compositor_delegate_.DidScrollContent(scroll_node.element_id,
is_animated_scroll);
} else {
overscroll_delta_for_main_thread_ +=
@@ -437,7 +441,7 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
accumulated_root_overscroll_.set_y(0);
gfx::Vector2dF unused_root_delta;
- if (GetViewport().ShouldScroll(*CurrentlyScrollingNode())) {
+ if (GetViewport().ShouldScroll(scroll_node)) {
unused_root_delta =
gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y());
}
@@ -471,11 +475,15 @@ InputHandlerScrollResult ThreadedInputHandler::ScrollUpdate(
UpdateRootLayerStateForSynchronousInputHandler();
}
- scroll_result.current_visual_offset =
- GetVisualScrollOffset(*CurrentlyScrollingNode());
+ scroll_result.current_visual_offset = GetVisualScrollOffset(scroll_node);
float scale_factor = ActiveTree().page_scale_factor_for_scroll();
scroll_result.current_visual_offset.Scale(scale_factor);
+ if (base::FeatureList::IsEnabled(features::kScrollUnification) &&
+ !GetScrollTree().CanRealizeScrollsOnCompositor(scroll_node)) {
+ scroll_result.needs_main_thread_repaint = true;
+ }
+
// Run animations which need to respond to updated scroll offset.
compositor_delegate_.GetImplDeprecated().mutator_host()->TickScrollAnimations(
compositor_delegate_.GetImplDeprecated()
@@ -1124,6 +1132,12 @@ void ThreadedInputHandler::RootLayerStateMayHaveChanged() {
UpdateRootLayerStateForSynchronousInputHandler();
}
+void ThreadedInputHandler::DidRegisterScrollbar(
+ ElementId scroll_element_id,
+ ScrollbarOrientation orientation) {
+ scrollbar_controller_->DidRegisterScrollbar(scroll_element_id, orientation);
+}
+
void ThreadedInputHandler::DidUnregisterScrollbar(
ElementId scroll_element_id,
ScrollbarOrientation orientation) {
@@ -1182,10 +1196,7 @@ ActivelyScrollingType ThreadedInputHandler::GetActivelyScrollingType() const {
if (!last_scroll_update_state_)
return ActivelyScrollingType::kNone;
- bool did_scroll_content =
- did_scroll_x_for_scroll_gesture_ || did_scroll_y_for_scroll_gesture_;
-
- if (!did_scroll_content)
+ if (!delta_consumed_for_scroll_gesture_)
return ActivelyScrollingType::kNone;
if (ShouldAnimateScroll(last_scroll_update_state_.value()))
@@ -2157,6 +2168,7 @@ void ThreadedInputHandler::ClearCurrentlyScrollingNode() {
accumulated_root_overscroll_ = gfx::Vector2dF();
did_scroll_x_for_scroll_gesture_ = false;
did_scroll_y_for_scroll_gesture_ = false;
+ delta_consumed_for_scroll_gesture_ = false;
scroll_animating_snap_target_ids_ = TargetSnapAreaElementIds();
latched_scroll_type_.reset();
last_scroll_update_state_.reset();
@@ -2249,4 +2261,9 @@ bool ThreadedInputHandler::ScrollbarScrollIsActive() {
return scrollbar_controller_->ScrollbarScrollIsActive();
}
+void ThreadedInputHandler::SetDeferBeginMainFrame(
+ bool defer_begin_main_frame) const {
+ compositor_delegate_.SetDeferBeginMainFrame(defer_begin_main_frame);
+}
+
} // namespace cc
diff --git a/chromium/cc/input/threaded_input_handler.h b/chromium/cc/input/threaded_input_handler.h
index ff554e8562b..08a356852ae 100644
--- a/chromium/cc/input/threaded_input_handler.h
+++ b/chromium/cc/input/threaded_input_handler.h
@@ -106,6 +106,7 @@ class CC_EXPORT ThreadedInputHandler : public InputHandler,
void ScrollEndForSnapFling(bool did_finish) override;
void NotifyInputEvent() override;
bool ScrollbarScrollIsActive() override;
+ void SetDeferBeginMainFrame(bool defer_begin_main_frame) const override;
// =========== InputDelegateForCompositor Interface - This section implements
// the interface that LayerTreeHostImpl uses to communicate with the input
@@ -118,6 +119,8 @@ class CC_EXPORT ThreadedInputHandler : public InputHandler,
void DidCommit() override;
void DidActivatePendingTree() override;
void RootLayerStateMayHaveChanged() override;
+ void DidRegisterScrollbar(ElementId scroll_element_id,
+ ScrollbarOrientation orientation) override;
void DidUnregisterScrollbar(ElementId scroll_element_id,
ScrollbarOrientation orientation) override;
void ScrollOffsetAnimationFinished() override;
@@ -183,6 +186,8 @@ class CC_EXPORT ThreadedInputHandler : public InputHandler,
AutoscrollOnDeletedScrollbar);
FRIEND_TEST_ALL_PREFIXES(ScrollUnifiedLayerTreeHostImplTest,
ThumbDragAfterJumpClick);
+ FRIEND_TEST_ALL_PREFIXES(ScrollUnifiedLayerTreeHostImplTest,
+ ScrollOnLargeThumb);
FRIEND_TEST_ALL_PREFIXES(LayerTreeHostImplTest, AutoscrollTaskAbort);
// This method gets the scroll offset for a regular scroller, or the combined
@@ -424,6 +429,11 @@ class CC_EXPORT ThreadedInputHandler : public InputHandler,
bool did_scroll_x_for_scroll_gesture_ = false;
bool did_scroll_y_for_scroll_gesture_ = false;
+ // did_scroll_x/y_for_scroll_gesture_ is true when contents consume the delta,
+ // but delta_consumed_for_scroll_gesture_ can be true when only browser
+ // controls consume all the delta.
+ bool delta_consumed_for_scroll_gesture_ = false;
+
// TODO(bokan): Mac doesn't yet have smooth scrolling for wheel; however, to
// allow consistency in tests we use this bit to override that decision.
// https://crbug.com/574283.
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index ad9561ec843..bf883bd1e01 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -370,7 +370,7 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
display_item_list->Finalize();
auto* ri = raster_context_provider->RasterInterface();
- constexpr GLuint background_color = SkColorSetARGB(0, 0, 0, 0);
+ constexpr SkColor4f background_color = SkColors::kTransparent;
constexpr GLuint msaa_sample_count = -1;
constexpr bool can_use_lcd_text = true;
ri->BeginRasterCHROMIUM(background_color, needs_clear, msaa_sample_count,
@@ -685,7 +685,8 @@ void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
void HeadsUpDisplayLayerImpl::DrawGraphBackground(PaintCanvas* canvas,
PaintFlags* flags,
const SkRect& bounds) const {
- flags->setColor(DebugColors::HUDBackgroundColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags->setColor(DebugColors::HUDBackgroundColor().toSkColor());
canvas->drawRect(bounds, *flags);
}
@@ -693,7 +694,8 @@ void HeadsUpDisplayLayerImpl::DrawGraphLines(PaintCanvas* canvas,
PaintFlags* flags,
const SkRect& bounds) const {
// Draw top and bottom line.
- flags->setColor(DebugColors::HUDSeparatorLineColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags->setColor(DebugColors::HUDSeparatorLineColor().toSkColor());
canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(),
bounds.top() - 1, *flags);
canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(),
@@ -755,11 +757,13 @@ SkRect HeadsUpDisplayLayerImpl::DrawFrameThroughputDisplay(
}
VLOG(1) << value_text;
- flags.setColor(DebugColors::HUDTitleColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::HUDTitleColor().toSkColor());
DrawText(canvas, flags, title, TextAlign::kLeft, kTitleFontHeight,
title_bounds.left(), title_bounds.bottom());
- flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::FPSDisplayTextAndGraphColor().toSkColor());
DrawText(canvas, flags, value_text, TextAlign::kRight, kFontHeight,
text_bounds.right(), text_bounds.bottom());
@@ -786,13 +790,15 @@ SkRect HeadsUpDisplayLayerImpl::DrawFrameThroughputDisplay(
flags.setStyle(PaintFlags::kStroke_Style);
flags.setStrokeWidth(1);
- flags.setColor(DebugColors::FPSDisplaySuccessfulFrame());
+ // TODO(crbug/1308932): Remove all instances of toSkColor below and make all
+ // SkColor4f.
+ flags.setColor(DebugColors::FPSDisplaySuccessfulFrame().toSkColor());
canvas->drawPath(good_path, flags);
- flags.setColor(DebugColors::FPSDisplayDroppedFrame());
+ flags.setColor(DebugColors::FPSDisplayDroppedFrame().toSkColor());
canvas->drawPath(dropped_path, flags);
- flags.setColor(DebugColors::FPSDisplayMissedFrame());
+ flags.setColor(DebugColors::FPSDisplayMissedFrame().toSkColor());
canvas->drawPath(partial_path, flags);
return area;
@@ -822,11 +828,13 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(PaintCanvas* canvas,
SkPoint stat2_pos = SkPoint::Make(left + width - kPadding - 1,
top + 2 * kPadding + 3 * kFontHeight);
- flags.setColor(DebugColors::HUDTitleColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::HUDTitleColor().toSkColor());
DrawText(canvas, flags, "GPU memory", TextAlign::kLeft, kTitleFontHeight,
title_pos);
- flags.setColor(DebugColors::MemoryDisplayTextColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::MemoryDisplayTextColor().toSkColor());
std::string text = base::StringPrintf(
"%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte);
DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat1_pos);
@@ -916,7 +924,8 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
SkPoint gpu_status_pos = SkPoint::Make(left + width - kPadding,
top + 2 * kFontHeight + 2 * kPadding);
- flags.setColor(DebugColors::HUDTitleColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::HUDTitleColor().toSkColor());
DrawText(canvas, flags, "GPU raster", TextAlign::kLeft, kTitleFontHeight,
left + kPadding, top + kFontHeight + kPadding);
flags.setColor(color);
@@ -995,6 +1004,8 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
std::string label_text;
switch (debug_rects[i].type) {
+ // TODO(crbug/1308932): Remove all instances of toSkColor below and make
+ // all SkColor4f.
case LAYOUT_SHIFT_RECT_TYPE:
new_layout_shift_rects.push_back(debug_rects[i]);
continue;
@@ -1002,56 +1013,65 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
new_paint_rects.push_back(debug_rects[i]);
continue;
case PROPERTY_CHANGED_RECT_TYPE:
- stroke_color = DebugColors::PropertyChangedRectBorderColor();
- fill_color = DebugColors::PropertyChangedRectFillColor();
+ stroke_color =
+ DebugColors::PropertyChangedRectBorderColor().toSkColor();
+ fill_color = DebugColors::PropertyChangedRectFillColor().toSkColor();
stroke_width = DebugColors::PropertyChangedRectBorderWidth();
break;
case SURFACE_DAMAGE_RECT_TYPE:
- stroke_color = DebugColors::SurfaceDamageRectBorderColor();
- fill_color = DebugColors::SurfaceDamageRectFillColor();
+ stroke_color = DebugColors::SurfaceDamageRectBorderColor().toSkColor();
+ fill_color = DebugColors::SurfaceDamageRectFillColor().toSkColor();
stroke_width = DebugColors::SurfaceDamageRectBorderWidth();
break;
case SCREEN_SPACE_RECT_TYPE:
- stroke_color = DebugColors::ScreenSpaceLayerRectBorderColor();
- fill_color = DebugColors::ScreenSpaceLayerRectFillColor();
+ stroke_color =
+ DebugColors::ScreenSpaceLayerRectBorderColor().toSkColor();
+ fill_color = DebugColors::ScreenSpaceLayerRectFillColor().toSkColor();
stroke_width = DebugColors::ScreenSpaceLayerRectBorderWidth();
break;
case TOUCH_EVENT_HANDLER_RECT_TYPE:
- stroke_color = DebugColors::TouchEventHandlerRectBorderColor();
- fill_color = DebugColors::TouchEventHandlerRectFillColor();
+ stroke_color =
+ DebugColors::TouchEventHandlerRectBorderColor().toSkColor();
+ fill_color = DebugColors::TouchEventHandlerRectFillColor().toSkColor();
stroke_width = DebugColors::TouchEventHandlerRectBorderWidth();
label_text = "touch event listener: ";
label_text.append(TouchActionToString(debug_rects[i].touch_action));
break;
case WHEEL_EVENT_HANDLER_RECT_TYPE:
- stroke_color = DebugColors::WheelEventHandlerRectBorderColor();
- fill_color = DebugColors::WheelEventHandlerRectFillColor();
+ stroke_color =
+ DebugColors::WheelEventHandlerRectBorderColor().toSkColor();
+ fill_color = DebugColors::WheelEventHandlerRectFillColor().toSkColor();
stroke_width = DebugColors::WheelEventHandlerRectBorderWidth();
label_text = "mousewheel event listener";
break;
case SCROLL_EVENT_HANDLER_RECT_TYPE:
- stroke_color = DebugColors::ScrollEventHandlerRectBorderColor();
- fill_color = DebugColors::ScrollEventHandlerRectFillColor();
+ stroke_color =
+ DebugColors::ScrollEventHandlerRectBorderColor().toSkColor();
+ fill_color = DebugColors::ScrollEventHandlerRectFillColor().toSkColor();
stroke_width = DebugColors::ScrollEventHandlerRectBorderWidth();
label_text = "scroll event listener";
break;
case NON_FAST_SCROLLABLE_RECT_TYPE:
- stroke_color = DebugColors::NonFastScrollableRectBorderColor();
- fill_color = DebugColors::NonFastScrollableRectFillColor();
+ stroke_color =
+ DebugColors::NonFastScrollableRectBorderColor().toSkColor();
+ fill_color = DebugColors::NonFastScrollableRectFillColor().toSkColor();
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_color =
+ DebugColors::MainThreadScrollingReasonRectBorderColor().toSkColor();
+ fill_color =
+ DebugColors::MainThreadScrollingReasonRectFillColor().toSkColor();
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();
+ stroke_color =
+ DebugColors::LayerAnimationBoundsBorderColor().toSkColor();
+ fill_color = DebugColors::LayerAnimationBoundsFillColor().toSkColor();
stroke_width = DebugColors::LayerAnimationBoundsBorderWidth();
label_text = "animation bounds";
break;
@@ -1067,11 +1087,14 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
}
if (paint_rects_fade_step_ > 0) {
paint_rects_fade_step_--;
- for (size_t i = 0; i < paint_rects_.size(); ++i) {
- DrawDebugRect(canvas, &flags, paint_rects_[i],
- DebugColors::PaintRectBorderColor(paint_rects_fade_step_),
- DebugColors::PaintRectFillColor(paint_rects_fade_step_),
- DebugColors::PaintRectBorderWidth(), "");
+ for (auto& paint_rect : paint_rects_) {
+ // TODO(crbug/1308932): Remove all instances of toSkColor below and make
+ // all SkColor4f.
+ DrawDebugRect(
+ canvas, &flags, paint_rect,
+ DebugColors::PaintRectBorderColor(paint_rects_fade_step_).toSkColor(),
+ DebugColors::PaintRectFillColor(paint_rects_fade_step_).toSkColor(),
+ DebugColors::PaintRectBorderWidth(), "");
}
}
if (new_layout_shift_rects.size()) {
@@ -1080,11 +1103,14 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
}
if (layout_shift_rects_fade_step_ > 0) {
layout_shift_rects_fade_step_--;
- for (size_t i = 0; i < layout_shift_debug_rects_.size(); ++i) {
+ for (auto& layout_shift_debug_rect : layout_shift_debug_rects_) {
+ // TODO(crbug/1308932): Remove all instances of toSkColor below and make
+ // all SkColor4f.
DrawDebugRect(
- canvas, &flags, layout_shift_debug_rects_[i],
- DebugColors::LayoutShiftRectBorderColor(),
- DebugColors::LayoutShiftRectFillColor(layout_shift_rects_fade_step_),
+ canvas, &flags, layout_shift_debug_rect,
+ DebugColors::LayoutShiftRectBorderColor().toSkColor(),
+ DebugColors::LayoutShiftRectFillColor(layout_shift_rects_fade_step_)
+ .toSkColor(),
DebugColors::LayoutShiftRectBorderWidth(), "");
}
}
@@ -1100,7 +1126,8 @@ int HeadsUpDisplayLayerImpl::DrawSingleMetric(
bool has_value,
double value) const {
std::string value_str = "-";
- SkColor metrics_color = DebugColors::HUDTitleColor();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ SkColor metrics_color = DebugColors::HUDTitleColor().toSkColor();
SkColor badge_color = SK_ColorGREEN;
if (has_value) {
value_str = ToStringTwoDecimalPrecision(value) + info.UnitToString();
@@ -1148,7 +1175,8 @@ int HeadsUpDisplayLayerImpl::DrawSingleMetric(
// Draw the label and values of the metric.
PaintFlags flags;
- flags.setColor(DebugColors::HUDTitleColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::HUDTitleColor().toSkColor());
DrawText(canvas, flags, name, TextAlign::kLeft, metrics_sizes.kFontHeight,
left + metrics_sizes.kSidePadding + metrics_sizes.kBadgeWidth, top);
flags.setColor(metrics_color);
@@ -1201,11 +1229,13 @@ int HeadsUpDisplayLayerImpl::DrawSinglePercentageMetric(PaintCanvas* canvas,
std::string name,
double value) const {
std::string value_str = "-";
- SkColor metrics_color = DebugColors::HUDTitleColor();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ SkColor metrics_color = DebugColors::HUDTitleColor().toSkColor();
value_str = ToStringTwoDecimalPrecision(value) + "%";
PaintFlags flags;
- flags.setColor(DebugColors::HUDTitleColor());
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ flags.setColor(DebugColors::HUDTitleColor().toSkColor());
DrawText(canvas, flags, name, TextAlign::kLeft, metrics_sizes.kFontHeight,
left + metrics_sizes.kSidePadding + metrics_sizes.kBadgeWidth, top);
flags.setColor(metrics_color);
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index 5000df2f883..7e9dd9f6e9b 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -52,10 +52,10 @@ struct SameSizeAsLayer : public base::RefCounted<SameSizeAsLayer>,
LayerList children;
gfx::Size bounds;
unsigned bitfields;
- SkColor background_color;
+ SkColor4f background_color;
TouchActionRegion touch_action_region;
ElementId element_id;
- void* rare_inputs;
+ raw_ptr<void> rare_inputs;
} inputs;
raw_ptr<void> layer_tree_inputs;
gfx::Rect update_rect;
@@ -83,7 +83,7 @@ Layer::Inputs::Inputs()
contents_opaque_for_text(false),
is_drawable(false),
double_sided(true),
- background_color(0) {}
+ background_color(SkColors::kTransparent) {}
Layer::Inputs::~Inputs() = default;
@@ -526,7 +526,7 @@ void Layer::RequestCopyOfOutput(
layer_tree_host()->SetHasCopyRequest(true);
}
-void Layer::SetBackgroundColor(SkColor background_color) {
+void Layer::SetBackgroundColor(SkColor4f background_color) {
DCHECK(IsPropertyChangeAllowed());
auto& inputs = inputs_.Write(*this);
if (inputs.background_color == background_color)
@@ -536,9 +536,9 @@ void Layer::SetBackgroundColor(SkColor background_color) {
SetNeedsCommit();
}
-void Layer::SetSafeOpaqueBackgroundColor(SkColor background_color) {
+void Layer::SetSafeOpaqueBackgroundColor(SkColor4f background_color) {
DCHECK(IsPropertyChangeAllowed());
- SkColor opaque_color = SkColorSetA(background_color, SK_AlphaOPAQUE);
+ SkColor4f opaque_color = background_color.makeOpaque();
auto& inputs = EnsureLayerTreeInputs();
if (inputs.safe_opaque_background_color == opaque_color)
return;
@@ -546,39 +546,42 @@ void Layer::SetSafeOpaqueBackgroundColor(SkColor background_color) {
SetNeedsPushProperties();
}
-SkColor Layer::SafeOpaqueBackgroundColor(SkColor host_background_color) const {
+SkColor4f Layer::SafeOpaqueBackgroundColor(
+ SkColor4f host_background_color) const {
if (contents_opaque()) {
if (!IsAttached() || !IsUsingLayerLists()) {
// In layer tree mode, PropertyTreeBuilder should have calculated the safe
// opaque background color and called SetSafeOpaqueBackgroundColor().
DCHECK(layer_tree_inputs());
- DCHECK_EQ(SkColorGetA(layer_tree_inputs()->safe_opaque_background_color),
- SK_AlphaOPAQUE);
+ DCHECK(layer_tree_inputs()->safe_opaque_background_color.isOpaque());
return layer_tree_inputs()->safe_opaque_background_color;
}
// In layer list mode, the PropertyTreeBuilder algorithm doesn't apply
// because it depends on the layer tree hierarchy. Instead we use
// background_color() if it's not transparent, or layer_tree_host_'s
// background_color(), with the alpha channel forced to be opaque.
- SkColor color = background_color() == SK_ColorTRANSPARENT
- ? host_background_color
- : background_color();
- return SkColorSetA(color, SK_AlphaOPAQUE);
+ SkColor4f color = background_color() == SkColors::kTransparent
+ ? host_background_color
+ : background_color();
+ return color.makeOpaque();
}
- if (SkColorGetA(background_color()) == SK_AlphaOPAQUE) {
+ if (background_color().isOpaque()) {
// The layer is not opaque while the background color is, meaning that the
- // background color doesn't cover the whole layer. Use SK_ColorTRANSPARENT
- // to avoid intrusive checkerboard where the layer is not covered by the
- // background color.
- return SK_ColorTRANSPARENT;
+ // background color doesn't cover the whole layer. Use
+ // SkColors::kTransparent to avoid intrusive checkerboard where the layer is
+ // not covered by the background color.
+ return SkColors::kTransparent;
}
return background_color();
}
-SkColor Layer::SafeOpaqueBackgroundColor() const {
- SkColor host_background_color =
- IsAttached() ? layer_tree_host()->pending_commit_state()->background_color
- : layer_tree_inputs()->safe_opaque_background_color;
+SkColor4f Layer::SafeOpaqueBackgroundColor() const {
+ // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
+ SkColor4f host_background_color =
+ IsAttached()
+ ? SkColor4f::FromColor(
+ layer_tree_host()->pending_commit_state()->background_color)
+ : layer_tree_inputs()->safe_opaque_background_color;
return SafeOpaqueBackgroundColor(host_background_color);
}
@@ -1201,6 +1204,7 @@ void Layer::SetCaptureBounds(viz::RegionCaptureBounds bounds) {
EnsureRareInputs().capture_bounds = std::move(bounds);
SetPropertyTreesNeedRebuild();
SetNeedsCommit();
+ SetSubtreePropertyChanged();
}
void Layer::SetWheelEventRegion(Region wheel_event_region) {
@@ -1465,8 +1469,9 @@ void Layer::PushPropertiesTo(LayerImpl* layer,
layer->SetElementId(inputs.element_id);
layer->SetHasTransformNode(has_transform_node());
layer->SetBackgroundColor(inputs.background_color);
- layer->SetSafeOpaqueBackgroundColor(
- SafeOpaqueBackgroundColor(commit_state.background_color));
+ // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
+ layer->SetSafeOpaqueBackgroundColor(SafeOpaqueBackgroundColor(
+ SkColor4f::FromColor(commit_state.background_color)));
layer->SetBounds(inputs.bounds);
layer->SetTransformTreeIndex(transform_tree_index(property_trees));
layer->SetEffectTreeIndex(effect_tree_index(property_trees));
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index c99407a5938..588cecfa2a0 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -171,15 +171,15 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// Set and get the background color for the layer. This color is not used by
// basic Layers, but subclasses may make use of it.
- virtual void SetBackgroundColor(SkColor background_color);
- SkColor background_color() const {
+ virtual void SetBackgroundColor(SkColor4f background_color);
+ SkColor4f background_color() const {
return inputs_.Read(*this).background_color;
}
// For layer tree mode only. In layer list mode, client doesn't need to set
// it. Sets an opaque background color for the layer, to be used in place of
// the background_color() if the layer says contents_opaque() is true.
- void SetSafeOpaqueBackgroundColor(SkColor background_color);
+ void SetSafeOpaqueBackgroundColor(SkColor4f background_color);
// Returns a background color with opaqueness equal to the value of
// contents_opaque().
@@ -189,13 +189,14 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// from background_color() and the argument host_background_color.
// Otherwise, it returns something non-opaque. It prefers to return the
// background_color(), but if the background_color() is opaque (and this layer
- // claims to not be), then SK_ColorTRANSPARENT is returned to avoid intrusive
- // checkerboard where the layer is not covered by the background_color().
- SkColor SafeOpaqueBackgroundColor(SkColor host_background_color) const;
+ // claims to not be), then SkColors::kTransparent is returned to avoid
+ // intrusive checkerboard where the layer is not covered by the
+ // background_color().
+ SkColor4f SafeOpaqueBackgroundColor(SkColor4f host_background_color) const;
// Same as the one-argument version, except that host_background_color is
// layer_tree_host()->pending_commit_state()->background_color.
- SkColor SafeOpaqueBackgroundColor() const;
+ SkColor4f SafeOpaqueBackgroundColor() const;
// For layer tree mode only.
// Set and get the position of this layer, relative to its parent. This is
@@ -999,7 +1000,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
bool is_drawable : 1;
bool double_sided : 1;
- SkColor background_color;
+ SkColor4f background_color;
TouchActionRegion touch_action_region;
ElementId element_id;
@@ -1053,7 +1054,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// surface that darws in a render pass.
viz::SubtreeCaptureId subtree_capture_id;
- SkColor safe_opaque_background_color = SK_ColorTRANSPARENT;
+ SkColor4f safe_opaque_background_color = SkColors::kTransparent;
FilterOperations filters;
FilterOperations backdrop_filters;
@@ -1160,7 +1161,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
AllowRemoveForReadd& operator=(const AllowRemoveForReadd&) = delete;
private:
- Layer* layer_;
+ raw_ptr<Layer> layer_;
};
bool allow_remove_for_readd_ = false;
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index f657d64f539..1e9e856c2da 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -71,8 +71,8 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
contributes_to_drawn_render_surface_(false),
hit_testable_(false),
is_inner_viewport_scroll_layer_(false),
- background_color_(0),
- safe_opaque_background_color_(0),
+ background_color_(SkColors::kTransparent),
+ safe_opaque_background_color_(SkColors::kTransparent),
transform_tree_index_(kInvalidPropertyNodeId),
effect_tree_index_(kInvalidPropertyNodeId),
clip_tree_index_(kInvalidPropertyNodeId),
@@ -228,7 +228,7 @@ bool LayerImpl::ShowDebugBorders(DebugBorderType type) const {
return layer_tree_impl()->debug_state().show_debug_borders.test(type);
}
-void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
+void LayerImpl::GetDebugBorderProperties(SkColor4f* color, float* width) const {
float device_scale_factor =
layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
@@ -247,7 +247,7 @@ void LayerImpl::AppendDebugBorderQuad(
const gfx::Rect& quad_rect,
const viz::SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data) const {
- SkColor color;
+ SkColor4f color;
float width;
GetDebugBorderProperties(&color, &width);
AppendDebugBorderQuad(render_pass, quad_rect, shared_quad_state,
@@ -259,7 +259,7 @@ void LayerImpl::AppendDebugBorderQuad(
const gfx::Rect& quad_rect,
const viz::SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data,
- SkColor color,
+ SkColor4f color,
float width) const {
if (!ShowDebugBorders(DebugBorderType::LAYER))
return;
@@ -273,14 +273,15 @@ void LayerImpl::AppendDebugBorderQuad(
gfx::Rect visible_quad_rect(quad_rect);
auto* debug_border_quad =
render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
- debug_border_quad->SetNew(
- shared_quad_state, quad_rect, visible_quad_rect, color, width);
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ debug_border_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
+ color.toSkColor(), width);
if (contents_opaque()) {
// When opaque, draw a second inner border that is thicker than the outer
// border, but more transparent.
static const float kFillOpacity = 0.3f;
- SkColor fill_color = SkColorSetA(
- color, static_cast<uint8_t>(SkColorGetA(color) * kFillOpacity));
+ SkColor4f fill_color = color;
+ color.fA *= kFillOpacity;
float fill_width = width * 3;
gfx::Rect fill_rect = quad_rect;
fill_rect.Inset(fill_width / 2.f);
@@ -288,10 +289,11 @@ void LayerImpl::AppendDebugBorderQuad(
return;
gfx::Rect visible_fill_rect =
gfx::IntersectRects(visible_quad_rect, fill_rect);
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
auto* fill_quad =
render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
fill_quad->SetNew(shared_quad_state, fill_rect, visible_fill_rect,
- fill_color, fill_width);
+ fill_color.toSkColor(), fill_width);
}
}
@@ -569,7 +571,7 @@ bool LayerImpl::HitTestable() const {
return should_hit_test;
}
-void LayerImpl::SetBackgroundColor(SkColor background_color) {
+void LayerImpl::SetBackgroundColor(SkColor4f background_color) {
if (background_color_ == background_color)
return;
@@ -577,7 +579,7 @@ void LayerImpl::SetBackgroundColor(SkColor background_color) {
NoteLayerPropertyChanged();
}
-void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor background_color) {
+void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor4f background_color) {
safe_opaque_background_color_ = background_color;
}
diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h
index 8777e92c956..a02b814d77a 100644
--- a/chromium/cc/layers/layer_impl.h
+++ b/chromium/cc/layers/layer_impl.h
@@ -164,13 +164,12 @@ class CC_EXPORT LayerImpl {
void SetHitTestable(bool should_hit_test);
bool HitTestable() const;
- void SetBackgroundColor(SkColor background_color);
- SkColor background_color() const { return background_color_; }
- void SetSafeOpaqueBackgroundColor(SkColor background_color);
- SkColor safe_opaque_background_color() const {
+ void SetBackgroundColor(SkColor4f background_color);
+ SkColor4f background_color() const { return background_color_; }
+ void SetSafeOpaqueBackgroundColor(SkColor4f background_color);
+ SkColor4f safe_opaque_background_color() const {
// Layer::SafeOpaqueBackgroundColor() should ensure this.
- DCHECK_EQ(contents_opaque(),
- SkColorGetA(safe_opaque_background_color_) == SK_AlphaOPAQUE);
+ DCHECK_EQ(contents_opaque(), safe_opaque_background_color_.isOpaque());
return safe_opaque_background_color_;
}
@@ -471,7 +470,7 @@ class CC_EXPORT LayerImpl {
bool will_always_push_properties = false);
// Get the color and size of the layer's debug border.
- virtual void GetDebugBorderProperties(SkColor* color, float* width) const;
+ virtual void GetDebugBorderProperties(SkColor4f* color, float* width) const;
void AppendDebugBorderQuad(viz::CompositorRenderPass* render_pass,
const gfx::Rect& quad_rect,
@@ -481,7 +480,7 @@ class CC_EXPORT LayerImpl {
const gfx::Rect& quad_rect,
const viz::SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data,
- SkColor color,
+ SkColor4f color,
float width) const;
static float GetPreferredRasterScale(
@@ -538,8 +537,8 @@ class CC_EXPORT LayerImpl {
TouchActionRegion touch_action_region_;
- SkColor background_color_;
- SkColor safe_opaque_background_color_;
+ SkColor4f background_color_;
+ SkColor4f safe_opaque_background_color_;
int transform_tree_index_;
int effect_tree_index_;
diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc
index 73a0698f378..095e57d61a4 100644
--- a/chromium/cc/layers/layer_impl_unittest.cc
+++ b/chromium/cc/layers/layer_impl_unittest.cc
@@ -102,7 +102,7 @@ TEST_F(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) {
gfx::Point arbitrary_point = gfx::Point(333, 444);
gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
- SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
+ SkColor4f arbitrary_color{0.1f, 0.2f, 0.3f, 1.0f};
gfx::Transform arbitrary_transform;
arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
FilterOperations arbitrary_filters;
@@ -166,7 +166,7 @@ TEST_F(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
gfx::PointF arbitrary_scroll_offset(
gfx::PointAtOffsetFromOrigin(arbitrary_vector2d));
gfx::Size large_size = gfx::Size(1000, 1000);
- SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
+ SkColor4f arbitrary_color{0.1f, 0.2f, 0.3f, 1.0f};
gfx::Transform arbitrary_transform;
arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
FilterOperations arbitrary_filters;
diff --git a/chromium/cc/layers/layer_list_iterator.h b/chromium/cc/layers/layer_list_iterator.h
index 2641c280c7f..dc7e92a20a3 100644
--- a/chromium/cc/layers/layer_list_iterator.h
+++ b/chromium/cc/layers/layer_list_iterator.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ptr_exclusion.h"
#include "cc/cc_export.h"
namespace cc {
@@ -42,7 +43,7 @@ class CC_EXPORT LayerListIterator {
// `current_layer` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- Layer* current_layer_;
+ RAW_PTR_EXCLUSION Layer* current_layer_;
std::vector<size_t> list_indices_;
};
@@ -67,7 +68,7 @@ class CC_EXPORT LayerListConstIterator {
const Layer* operator*() const { return current_layer_; }
private:
- const Layer* current_layer_;
+ raw_ptr<const Layer> current_layer_;
std::vector<size_t> list_indices_;
};
diff --git a/chromium/cc/layers/layer_perftest.cc b/chromium/cc/layers/layer_perftest.cc
index 4c419ecb509..dba359c1b9d 100644
--- a/chromium/cc/layers/layer_perftest.cc
+++ b/chromium/cc/layers/layer_perftest.cc
@@ -125,7 +125,7 @@ TEST_F(LayerPerfTest, ImplPushPropertiesTo) {
std::unique_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 2);
- SkColor background_color = SK_ColorRED;
+ SkColor4f background_color = SkColors::kRed;
gfx::Size bounds(1000, 1000);
bool draws_content = true;
bool contents_opaque = true;
@@ -142,7 +142,7 @@ TEST_F(LayerPerfTest, ImplPushPropertiesTo) {
test_layer->PushPropertiesTo(impl_layer.get());
background_color =
- background_color == SK_ColorRED ? SK_ColorGREEN : SK_ColorRED;
+ background_color == SkColors::kRed ? SkColors::kGreen : SkColors::kRed;
bounds = bounds == gfx::Size(1000, 1000) ? gfx::Size(500, 500)
: gfx::Size(1000, 1000);
draws_content = !draws_content;
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index 372a57aab19..e822609d136 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -87,6 +87,21 @@ using ::testing::_;
EXPECT_FALSE(child->subtree_property_changed()); \
EXPECT_FALSE(grand_child->subtree_property_changed());
+// TODO(https://crbug.com/1330728): tests should be cleaned up to eliminate
+// mixing of EXPECT_CALL with calls to the mock functions. This method
+// should be deduped with EXPECT_SET_NEEDS_COMMIT as part of this cleanup.
+#define EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(code_to_test) \
+ do { \
+ code_to_test; \
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); \
+ } while (false)
+
+#define EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED(code_to_test) \
+ do { \
+ code_to_test; \
+ EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset()); \
+ } while (false)
+
namespace cc {
namespace {
@@ -110,9 +125,18 @@ class MockLayerTreeHost : public LayerTreeHost {
return thread_unsafe_commit_state();
}
- MOCK_METHOD0(SetNeedsCommit, void());
- MOCK_METHOD0(SetNeedsUpdateLayers, void());
- MOCK_METHOD0(SetNeedsFullTreeSync, void());
+ MOCK_METHOD(void, SetNeedsUpdateLayers, (), (override));
+ MOCK_METHOD(void, SetNeedsFullTreeSync, (), (override));
+
+ void SetNeedsCommit() override { needs_commit_ = true; }
+ bool GetNeedsCommitAndReset() {
+ const bool out = needs_commit_;
+ needs_commit_ = false;
+ return out;
+ }
+
+ private:
+ bool needs_commit_ = false;
};
bool LayerNeedsDisplay(Layer* layer) {
@@ -259,11 +283,7 @@ TEST_F(LayerTest, BasicCreateAndDestroy) {
scoped_refptr<Layer> test_layer = Layer::Create();
ASSERT_TRUE(test_layer.get());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
test_layer->SetLayerTreeHost(layer_tree_host_.get());
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
test_layer->SetLayerTreeHost(nullptr);
}
@@ -283,21 +303,22 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
top->AddChild(child);
top->AddChild(child2);
child->AddChild(grand_child);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
+
// To force a transform node for |top|.
gfx::Transform top_transform;
top_transform.Scale3d(1, 2, 3);
top->SetTransform(top_transform);
child->SetForceRenderSurfaceForTesting(true);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
// Resizing without a mask layer or masks_to_bounds, should only require a
// regular commit. Note that a layer and its mask should match sizes, but
// the mask isn't in the tree yet, so won't need its own commit.
gfx::Size arbitrary_size = gfx::Size(1, 2);
- EXPECT_SET_NEEDS_COMMIT(1, top->SetBounds(arbitrary_size));
- EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size));
- EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(top->SetBounds(arbitrary_size));
+ EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED(
+ mask_layer1->SetBounds(arbitrary_size));
+ EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync());
layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMaskLayer(mask_layer1));
@@ -335,11 +356,11 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
// Once there is a mask layer, resizes require subtree properties to update.
arbitrary_size = gfx::Size(11, 22);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBounds(arbitrary_size));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMasksToBounds(true));
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
@@ -351,9 +372,10 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
grand_child->PushPropertiesTo(grand_child_impl.get(), *commit_state,
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetContentsOpaque(true));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -365,8 +387,8 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetTrilinearFiltering(true));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -378,8 +400,8 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetTrilinearFiltering(false));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -391,9 +413,10 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
top->SetRoundedCorner({1, 2, 3, 4});
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetIsFastRoundedCorner(true));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -405,8 +428,8 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetHideLayerAndSubtree(true));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -418,8 +441,8 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBlendMode(arbitrary_blend_mode));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -434,9 +457,10 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
// Should be a different size than previous call, to ensure it marks tree
// changed.
arbitrary_size = gfx::Size(111, 222);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBounds(arbitrary_size));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -450,8 +474,8 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
FilterOperations arbitrary_filters;
arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetFilters(arbitrary_filters));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -463,7 +487,6 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
top->SetBackdropFilters(arbitrary_filters));
@@ -476,9 +499,9 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
grand_child->PushPropertiesTo(grand_child_impl.get(), *commit_state,
unsafe_state));
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
top->SetPosition(arbitrary_point_f);
TransformNode* node =
layer_tree_host_->property_trees()->transform_tree_mutable().Node(
@@ -496,12 +519,13 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
layer_tree_host_->property_trees()->ResetAllChangeTracking());
layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
EXPECT_FALSE(node->transform_changed);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
child->SetPosition(arbitrary_point_f);
node = layer_tree_host_->property_trees()->transform_tree_mutable().Node(
child->transform_tree_index());
EXPECT_TRUE(node->transform_changed);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -516,11 +540,11 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
EXPECT_FALSE(node->transform_changed);
gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
top->SetTransformOrigin(arbitrary_point_3f);
node = layer_tree_host_->property_trees()->transform_tree_mutable().Node(
top->transform_tree_index());
EXPECT_TRUE(node->transform_changed);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
/*has_updates=*/true);
@@ -535,11 +559,11 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
gfx::Transform arbitrary_transform;
arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
top->SetTransform(arbitrary_transform);
node = layer_tree_host_->property_trees()->transform_tree_mutable().Node(
top->transform_tree_index());
EXPECT_TRUE(node->transform_changed);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
}
TEST_F(LayerTest, AddAndRemoveChild) {
@@ -787,8 +811,8 @@ TEST_F(LayerTest, ReplaceChildWithNewChild) {
EXPECT_FALSE(child4->parent());
- EXPECT_SET_NEEDS_FULL_TREE_SYNC(
- AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));
+ EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1),
+ parent_->ReplaceChild(child2_.get(), child4));
EXPECT_FALSE(LayerNeedsDisplay(parent_.get()));
EXPECT_FALSE(LayerNeedsDisplay(child1_.get()));
EXPECT_FALSE(LayerNeedsDisplay(child2_.get()));
@@ -815,8 +839,8 @@ TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
EXPECT_EQ(child4, test_layer->children()[0]);
EXPECT_EQ(test_layer.get(), child4->parent());
- EXPECT_SET_NEEDS_FULL_TREE_SYNC(
- AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));
+ EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1),
+ parent_->ReplaceChild(child2_.get(), child4));
ASSERT_EQ(3U, parent_->children().size());
EXPECT_EQ(child1_, parent_->children()[0]);
@@ -833,10 +857,8 @@ TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
TEST_F(LayerTest, ReplaceChildWithSameChild) {
CreateSimpleTestTree();
- // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its the
- // same child.
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(0);
+ // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its
+ // the same child.
parent_->ReplaceChild(child2_.get(), child2_);
VerifyTestTreeInitialState();
@@ -886,7 +908,7 @@ TEST_F(LayerTest, GetRootLayerAfterTreeManipulations) {
EXPECT_EQ(parent_.get(), child1_->RootLayer());
EXPECT_EQ(parent_.get(), child2_->RootLayer());
EXPECT_EQ(parent_.get(), child3_->RootLayer());
- EXPECT_EQ(child4.get(), child4->RootLayer());
+ EXPECT_EQ(child4.get(), child4->RootLayer());
EXPECT_EQ(parent_.get(), grand_child1_->RootLayer());
EXPECT_EQ(parent_.get(), grand_child2_->RootLayer());
EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());
@@ -917,8 +939,8 @@ TEST_F(LayerTest, GetRootLayerAfterTreeManipulations) {
child2_->ReplaceChild(grand_child3_.get(), child1_);
- // |grand_child3| gets orphaned and the child1 subtree gets planted back into
- // the tree under child2.
+ // |grand_child3| gets orphaned and the child1 subtree gets planted back
+ // into the tree under child2.
EXPECT_EQ(parent_.get(), parent_->RootLayer());
EXPECT_EQ(parent_.get(), child1_->RootLayer());
EXPECT_EQ(parent_.get(), child2_->RootLayer());
@@ -938,7 +960,7 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
scoped_refptr<Layer> test_layer = Layer::Create();
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(test_layer));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(true));
gfx::Size test_bounds = gfx::Size(501, 508);
@@ -948,9 +970,9 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
// Before anything, test_layer should not be dirty.
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
- // This is just initialization, but SetNeedsCommit behavior is verified anyway
- // to avoid warnings.
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBounds(test_bounds));
+ // This is just initialization, but SetNeedsCommit behavior is verified
+ // anyway to avoid warnings.
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetBounds(test_bounds));
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
// The real test begins here.
@@ -972,12 +994,13 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
// Case 3: SetNeedsDisplay() with an empty rect.
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
- EXPECT_SET_NEEDS_COMMIT(0, test_layer->SetNeedsDisplayRect(gfx::Rect()));
+ EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED(
+ test_layer->SetNeedsDisplayRect(gfx::Rect()));
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
SimulateCommitForLayer(test_layer.get());
// Case 4: SetNeedsDisplay() with a non-drawable layer
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(false));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(false));
SimulateCommitForLayer(test_layer.get());
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
EXPECT_SET_NEEDS_UPDATE(0, test_layer->SetNeedsDisplayRect(dirty_rect));
@@ -988,7 +1011,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
scoped_refptr<Layer> test_layer = Layer::Create();
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(test_layer));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(true));
FakeContentLayerClient client;
scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client);
@@ -999,37 +1022,50 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
// Next, test properties that should call SetNeedsCommit (but not
// SetNeedsDisplay). All properties need to be set to new values in order for
// SetNeedsCommit to be called.
- EXPECT_SET_NEEDS_COMMIT(
- 1, test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f)));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBackgroundColor(SK_ColorLTGRAY));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetMasksToBounds(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetClipRect(gfx::Rect(1, 2, 3, 4)));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4}));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsFastRoundedCorner(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendMode(SkBlendMode::kHue));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetBackgroundColor(SkColors::kLtGray));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetMasksToBounds(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetClipRect(gfx::Rect(1, 2, 3, 4)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetRoundedCorner({1, 2, 3, 4}));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsFastRoundedCorner(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetOpacity(0.5f));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetBlendMode(SkBlendMode::kHue));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetContentsOpaque(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetPosition(gfx::PointF(4.f, 9.f)));
// We can use any layer pointer here since we aren't syncing for real.
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1)));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset(gfx::PointF(10, 10)));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion(
- Region(gfx::Rect(1, 1, 2, 2))));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(
- gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetScrollable(gfx::Size(1, 1)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetUserScrollable(true, false));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetScrollOffset(gfx::PointF(10, 10)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetNonFastScrollableRegion(Region(gfx::Rect(1, 1, 2, 2))));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)));
TouchActionRegion touch_action_region;
touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10));
- EXPECT_SET_NEEDS_COMMIT(
- 1, test_layer->SetTouchActionRegion(std::move(touch_action_region)));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2)));
-
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetTouchActionRegion(std::move(touch_action_region)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetForceRenderSurfaceForTesting(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetHideLayerAndSubtree(true));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetElementId(ElementId(2)));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetCaptureBounds(viz::RegionCaptureBounds(
+ base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{
+ {viz::RegionCaptureCropId(123u, 456u),
+ gfx::Rect(0, 0, 640, 480)}})));
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, test_layer->SetMaskLayer(mask_layer1));
-
- // The above tests should not have caused a change to the needs_display flag.
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
+ // The above tests should not have caused a change to the needs_display
+ // flag.
EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
// As layers are removed from the tree, they will cause a tree sync.
@@ -1050,8 +1086,8 @@ TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
CommitAndPushProperties(test_layer.get(), impl_layer_ptr);
EXPECT_EQ(gfx::Rect(0, 0, 5, 5), impl_layer_ptr->update_rect());
- // The LayerImpl's update_rect() should be accumulated here, since we did not
- // do anything to clear it.
+ // The LayerImpl's update_rect() should be accumulated here, since we did
+ // not do anything to clear it.
test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5));
CommitAndPushProperties(test_layer.get(), impl_layer_ptr);
EXPECT_EQ(gfx::Rect(0, 0, 15, 15), impl_layer_ptr->update_rect());
@@ -1074,7 +1110,7 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) {
gfx::Transform transform;
transform.Rotate(45.0);
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(transform));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetTransform(transform));
EXPECT_FALSE(impl_layer->LayerPropertyChanged());
@@ -1094,7 +1130,8 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForRoundCorner) {
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(test_layer));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4}));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(
+ test_layer->SetRoundedCorner({1, 2, 3, 4}));
EXPECT_FALSE(impl_layer->LayerPropertyChanged());
@@ -1113,7 +1150,7 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) {
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(test_layer));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));
+ EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetOpacity(0.5f));
EXPECT_FALSE(impl_layer->LayerPropertyChanged());
@@ -1182,8 +1219,8 @@ TEST_F(LayerLayerTreeHostTest, EnteringTree) {
FakeContentLayerClient client;
scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
- // Set up a detached tree of layers. The host pointer should be nil for these
- // layers.
+ // Set up a detached tree of layers. The host pointer should be nil for
+ // these layers.
parent->AddChild(child);
child->SetMaskLayer(mask);
@@ -1255,8 +1292,9 @@ TEST_F(LayerLayerTreeHostTest, ChangeHost) {
AssertLayerTreeHostMatchesForSubtree(parent.get(),
first_layer_tree_host.get());
- // Now re-root the tree to a new host (simulating what we do on a context lost
- // event). This should update the host pointers for all layers in the tree.
+ // Now re-root the tree to a new host (simulating what we do on a context
+ // lost event). This should update the host pointers for all layers in the
+ // tree.
auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
std::unique_ptr<LayerTreeHost> second_layer_tree_host =
factory.Create(animation_host2.get());
@@ -1289,8 +1327,8 @@ TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) {
AssertLayerTreeHostMatchesForSubtree(first_parent.get(),
first_layer_tree_host.get());
- // Now reparent the subtree starting at second_child to a layer in a different
- // tree.
+ // Now reparent the subtree starting at second_child to a layer in a
+ // different tree.
auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
std::unique_ptr<LayerTreeHost> second_layer_tree_host =
factory.Create(animation_host2.get());
@@ -1327,7 +1365,8 @@ TEST_F(LayerLayerTreeHostTest, ReplaceMaskLayer) {
AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());
- // Replacing the mask should clear out the old mask's subtree's host pointers.
+ // Replacing the mask should clear out the old mask's subtree's host
+ // pointers.
parent->SetMaskLayer(mask_replacement);
EXPECT_EQ(nullptr, mask->layer_tree_host());
EXPECT_EQ(nullptr, mask_child->layer_tree_host());
@@ -1360,23 +1399,17 @@ TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
for (int host_opaque = 0; host_opaque < 2; ++host_opaque) {
layer->SetContentsOpaque(!!contents_opaque);
- layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
- : SK_ColorTRANSPARENT);
+ layer->SetBackgroundColor(layer_opaque ? SkColors::kRed
+ : SkColors::kTransparent);
layer_tree_host->set_background_color(
host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);
layer_tree_host->property_trees()->set_needs_rebuild(true);
layer_tree_host->BuildPropertyTreesForTesting();
- SkColor safe_color = layer->SafeOpaqueBackgroundColor();
- if (contents_opaque) {
- EXPECT_EQ(SkColorGetA(safe_color), 255u)
- << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
- << host_opaque << "\n";
- } else {
- EXPECT_NE(SkColorGetA(safe_color), 255u)
- << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
- << host_opaque << "\n";
- }
+ EXPECT_EQ(contents_opaque,
+ layer->SafeOpaqueBackgroundColor().isOpaque())
+ << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
+ << host_opaque << "\n";
}
}
}
@@ -1433,7 +1466,6 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
LayerImpl::Create(host_impl_.active_tree(), 1);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(root_layer));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(5);
// A layer that draws content should be hit testable.
root_layer->SetIsDrawable(true);
@@ -1441,6 +1473,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
CommitAndPushProperties(root_layer.get(), impl_layer.get());
EXPECT_TRUE(impl_layer->draws_content());
EXPECT_TRUE(impl_layer->HitTestable());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
// A layer that does not draw content and does not hit test without drawing
// content should not be hit testable.
@@ -1449,6 +1482,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
CommitAndPushProperties(root_layer.get(), impl_layer.get());
EXPECT_FALSE(impl_layer->draws_content());
EXPECT_FALSE(impl_layer->HitTestable());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
// |SetHitTestableWithoutDrawsContent| should cause a layer to become hit
// testable even though it does not draw content.
@@ -1456,6 +1490,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
CommitAndPushProperties(root_layer.get(), impl_layer.get());
EXPECT_FALSE(impl_layer->draws_content());
EXPECT_TRUE(impl_layer->HitTestable());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
}
void ReceiveCopyOutputResult(int* result_count,
@@ -1581,12 +1616,12 @@ TEST_F(LayerTest, AnimationSchedulesLayerUpdate) {
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer));
auto element_id = layer->element_id();
- EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
+ EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers());
layer_tree_host_->SetElementOpacityMutated(element_id,
ElementListType::ACTIVE, 0.5f);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
+ EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers());
gfx::Transform transform;
transform.Rotate(45.0);
layer_tree_host_->SetElementTransformMutated(
@@ -1609,15 +1644,12 @@ TEST_F(LayerTest, ElementIdIsPushed) {
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
layer_tree_host_->SetRootLayer(test_layer));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
-
test_layer->SetElementId(ElementId(2));
-
EXPECT_FALSE(impl_layer->element_id());
CommitAndPushProperties(test_layer.get(), impl_layer.get());
-
EXPECT_EQ(ElementId(2), impl_layer->element_id());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
}
TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
@@ -1627,7 +1659,6 @@ TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
// Expect additional calls due to has-animation check and initialization
// of keyframes.
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(3);
scoped_refptr<AnimationTimeline> timeline =
AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
animation_host_->AddAnimationTimeline(timeline);
@@ -1635,11 +1666,17 @@ TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
AddOpacityTransitionToElementWithAnimation(element_id, timeline, 10.0, 1.f,
0.f, false);
EXPECT_TRUE(animation_host_->IsElementAnimating(element_id));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
test_layer->SetLayerTreeHost(layer_tree_host_.get());
// Layer should now be registered by element id.
EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
+
+ // We're expected to remove the animations before calling
+ // SetLayerTreeHost(nullptr).
+ animation_host_->RemoveAnimationTimeline(timeline);
test_layer->SetLayerTreeHost(nullptr);
// Layer should have been un-registered.
@@ -1650,7 +1687,6 @@ TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
// compositor is expensive and updated counts can wait until the next
// commit to be pushed. See https://crbug.com/1083244.
TEST_F(LayerTest, PushAnimationCountsLazily) {
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
animation_host_->SetAnimationCounts(0);
animation_host_->SetCurrentFrameHadRaf(true);
animation_host_->SetNextFrameHasPendingRaf(true);
@@ -1662,19 +1698,20 @@ TEST_F(LayerTest, PushAnimationCountsLazily) {
*layer_tree_host_->property_trees());
EXPECT_TRUE(host_impl_.animation_host()->CurrentFrameHadRAF());
EXPECT_TRUE(host_impl_.animation_host()->HasSmilAnimation());
+ EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset());
}
TEST_F(LayerTest, SetElementIdNotUsingLayerLists) {
scoped_refptr<Layer> test_layer = Layer::Create();
test_layer->SetLayerTreeHost(layer_tree_host_.get());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
ElementId element_id = ElementId(2);
EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
test_layer->SetElementId(element_id);
// Layer should now be registered by element id.
EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
ElementId other_element_id = ElementId(3);
test_layer->SetElementId(other_element_id);
@@ -1684,6 +1721,7 @@ TEST_F(LayerTest, SetElementIdNotUsingLayerLists) {
EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(other_element_id));
test_layer->SetLayerTreeHost(nullptr);
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
}
// Verifies that when mirror count of the layer is incremented or decremented,
@@ -1703,7 +1741,8 @@ TEST_F(LayerTest, UpdateMirrorCount) {
EXPECT_EQ(0u, layer_tree_host_->GetPendingCommitState()
->layers_that_should_push_properties.size());
- // Incrementing mirror count from zero should trigger property trees rebuild.
+ // Incrementing mirror count from zero should trigger property trees
+ // rebuild.
test_layer->IncrementMirrorCount();
EXPECT_EQ(1, test_layer->mirror_count());
EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
@@ -1747,6 +1786,64 @@ TEST_F(LayerTest, UpdateMirrorCount) {
test_layer->SetLayerTreeHost(nullptr);
}
+TEST_F(LayerTest, UpdatingCaptureBounds) {
+ static const viz::RegionCaptureBounds kEmptyBounds;
+ static const viz::RegionCaptureBounds kPopulatedBounds(
+ base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{
+ {viz::RegionCaptureCropId(123u, 456u), gfx::Rect(0, 0, 640, 480)}});
+ static const viz::RegionCaptureBounds kUpdatedBounds(
+ base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{
+ {viz::RegionCaptureCropId(123u, 456u), gfx::Rect(0, 0, 1280, 720)}});
+
+ // We don't track full tree syncs in this test.
+ EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
+
+ scoped_refptr<Layer> layer = Layer::Create();
+ layer_tree_host_->SetRootLayer(layer);
+
+ // Clear the updates caused by setting a new root layer.
+ layer->ClearSubtreePropertyChangedForTesting();
+ layer_tree_host_->property_trees()->set_needs_rebuild(false);
+
+ // An empty bounds when none is currently set should not cause an update.
+ layer->SetCaptureBounds(kEmptyBounds);
+ EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild());
+ EXPECT_FALSE(layer->subtree_property_changed());
+ EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset());
+
+ // Setting to a new bounds should cause an update.
+ layer->SetCaptureBounds(kPopulatedBounds);
+ EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
+ EXPECT_TRUE(layer->subtree_property_changed());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
+
+ // Reset properties.
+ layer->ClearSubtreePropertyChangedForTesting();
+ layer_tree_host_->property_trees()->set_needs_rebuild(false);
+
+ // Setting to the same bounds should not, however.
+ layer->SetCaptureBounds(kPopulatedBounds);
+ EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild());
+ EXPECT_FALSE(layer->subtree_property_changed());
+ EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset());
+
+ // Switching to a differently valued bounds should cause an update.
+ layer->SetCaptureBounds(kUpdatedBounds);
+ EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
+ EXPECT_TRUE(layer->subtree_property_changed());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
+
+ // Reset properties.
+ layer->ClearSubtreePropertyChangedForTesting();
+ layer_tree_host_->property_trees()->set_needs_rebuild(false);
+
+ // Finally, setting to empty should cause an update.
+ layer->SetCaptureBounds(kEmptyBounds);
+ EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
+ EXPECT_TRUE(layer->subtree_property_changed());
+ EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset());
+}
+
TEST_F(LayerTest, UpdatingClipRect) {
const gfx::Size kRootSize(200, 200);
const gfx::Vector2dF kParentOffset(10.f, 20.f);
@@ -1765,7 +1862,6 @@ TEST_F(LayerTest, UpdatingClipRect) {
scoped_refptr<Layer> clipped_4 = Layer::Create();
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
layer_tree_host_->SetRootLayer(root);
root->AddChild(parent);
parent->AddChild(clipped_1);
@@ -1807,9 +1903,9 @@ TEST_F(LayerTest, UpdatingClipRect) {
EXPECT_EQ(gfx::RectF(kClipRect) + kParentOffset, node_3->clip);
EXPECT_EQ(gfx::RectF(kClipRect) + kParentOffset, node_4->clip);
- // The following layer properties should result in the layer being clipped to
- // its bounds along with being clipped by the clip rect. Check if the final
- // rect on the clip node is set correctly.
+ // The following layer properties should result in the layer being clipped
+ // to its bounds along with being clipped by the clip rect. Check if the
+ // final rect on the clip node is set correctly.
// Setting clip to layer bounds.
clipped_1->SetMasksToBounds(true);
@@ -1871,7 +1967,6 @@ TEST_F(LayerTest, UpdatingRoundedCorners) {
scoped_refptr<Layer> layer_5 = Layer::Create();
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
layer_tree_host_->SetRootLayer(root);
root->AddChild(layer_1);
root->AddChild(layer_2);
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index b8d830dca49..39e68be28b6 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -230,9 +230,10 @@ void PictureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
Occlusion occlusion = draw_properties().occlusion_in_content_space;
EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
+ // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
SolidColorLayerImpl::AppendSolidQuads(
render_pass, occlusion, shared_quad_state, scaled_visible_layer_rect,
- raster_source_->GetSolidColor(),
+ SkColor4f::FromColor(raster_source_->GetSolidColor()),
!layer_tree_impl()->settings().enable_edge_anti_aliasing,
effect_node->blend_mode, append_quads_data);
return;
@@ -366,7 +367,7 @@ void PictureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
shared_quad_state->visible_quad_layer_rect,
ideal_contents_scale_key());
iter; ++iter) {
- SkColor color;
+ SkColor4f color;
float width;
if (*iter && iter->draw_info().IsReadyToDraw()) {
TileDrawInfo::Mode mode = iter->draw_info().mode();
@@ -399,23 +400,24 @@ void PictureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
gfx::Rect geometry_rect = iter.geometry_rect();
geometry_rect.Offset(quad_offset);
gfx::Rect visible_geometry_rect = geometry_rect;
- debug_border_quad->SetNew(shared_quad_state,
- geometry_rect,
- visible_geometry_rect,
- color,
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ debug_border_quad->SetNew(shared_quad_state, geometry_rect,
+ visible_geometry_rect, color.toSkColor(),
width);
}
}
if (layer_tree_impl()->debug_state().highlight_non_lcd_text_layers) {
- SkColor color =
+ // TODO(crbug/1308932): Remove all instances of toSkColor below and make all
+ // SkColor4f.
+ SkColor4f color =
DebugColors::NonLCDTextHighlightColor(lcd_text_disallowed_reason());
- if (color != SK_ColorTRANSPARENT &&
+ if (color != SkColors::kTransparent &&
GetRasterSource()->GetDisplayItemList()->AreaOfDrawText(
gfx::Rect(bounds()))) {
render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>()->SetNew(
- shared_quad_state, debug_border_rect, debug_border_rect, color,
- append_quads_data);
+ shared_quad_state, debug_border_rect, debug_border_rect,
+ color.toSkColor(), append_quads_data);
}
}
@@ -513,15 +515,16 @@ void PictureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
if (!has_draw_quad) {
// Checkerboard.
- SkColor color = safe_opaque_background_color();
+ SkColor4f color = safe_opaque_background_color();
if (ShowDebugBorders(DebugBorderType::LAYER)) {
// Fill the whole tile with the missing tile color.
color = DebugColors::DefaultCheckerboardColor();
}
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
quad->SetNew(shared_quad_state, offset_geometry_rect,
- offset_visible_geometry_rect, color, false);
+ offset_visible_geometry_rect, color.toSkColor(), false);
ValidateQuadResources(quad);
if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
@@ -840,10 +843,11 @@ void PictureLayerImpl::UpdateCanUseLCDText(
ComputeLCDTextDisallowedReason(raster_translation_aligns_pixels);
}
-bool PictureLayerImpl::HasWillChangeTransformHint() const {
+bool PictureLayerImpl::AffectedByWillChangeTransformHint() const {
TransformNode* transform_node =
GetTransformTree().Node(transform_tree_index());
- return transform_node && transform_node->will_change_transform;
+ return transform_node &&
+ transform_node->node_or_ancestors_will_change_transform;
}
LCDTextDisallowedReason PictureLayerImpl::ComputeLCDTextDisallowedReason(
@@ -859,7 +863,7 @@ LCDTextDisallowedReason PictureLayerImpl::ComputeLCDTextDisallowedReason(
if (!layer_tree_impl()->settings().can_use_lcd_text)
return LCDTextDisallowedReason::kSetting;
if (!contents_opaque_for_text()) {
- if (SkColorGetA(background_color()) != SK_AlphaOPAQUE)
+ if (!background_color().isOpaque())
return LCDTextDisallowedReason::kBackgroundColorNotOpaque;
return LCDTextDisallowedReason::kContentsNotOpaque;
}
@@ -1224,16 +1228,13 @@ void PictureLayerImpl::RemoveAllTilings() {
bool PictureLayerImpl::CanRecreateHighResTilingForLCDTextAndRasterTransform(
const PictureLayerTiling& high_res) const {
- // This is for the sync tree only to avoid flickering.
- if (!layer_tree_impl()->IsSyncTree())
- return false;
// We can recreate the tiling if we would invalidate all of its tiles.
if (high_res.may_contain_low_resolution_tiles())
return true;
// Keep the non-ideal raster translation unchanged for transform animations
// to avoid re-rasterization during animation.
if (draw_properties().screen_space_transform_is_animating ||
- HasWillChangeTransformHint())
+ AffectedByWillChangeTransformHint())
return false;
// Also avoid re-rasterization during pinch-zoom.
if (layer_tree_impl()->PinchGestureActive())
@@ -1243,6 +1244,11 @@ bool PictureLayerImpl::CanRecreateHighResTilingForLCDTextAndRasterTransform(
if (lcd_text_disallowed_reason_ == LCDTextDisallowedReason::kNoText &&
high_res.raster_transform().scale() == raster_contents_scale_)
return false;
+ // If ReadyToActivate() is already scheduled, recreating tiling should be
+ // delayed until the activation is executed. Otherwise the tiles in viewport
+ // will be deleted.
+ if (layer_tree_impl()->IsSyncTree() && layer_tree_impl()->IsReadyToActivate())
+ return false;
return true;
}
@@ -1261,12 +1267,28 @@ void PictureLayerImpl::UpdateTilingsForRasterScaleAndTranslation(
high_res->raster_transform().translation() != raster_translation;
bool can_use_lcd_text_changed =
high_res->can_use_lcd_text() != can_use_lcd_text();
+ bool can_recreate_highres_tiling =
+ CanRecreateHighResTilingForLCDTextAndRasterTransform(*high_res);
+ // Only for the sync tree to avoid flickering.
bool should_recreate_high_res =
(raster_transform_is_not_ideal || can_use_lcd_text_changed) &&
- CanRecreateHighResTilingForLCDTextAndRasterTransform(*high_res);
+ layer_tree_impl()->IsSyncTree() && can_recreate_highres_tiling;
+ // Only request an invalidation if we don't already have a pending tree.
+ bool can_request_invalidation_for_high_res =
+ (raster_transform_is_not_ideal || can_use_lcd_text_changed) &&
+ !layer_tree_impl()->settings().commit_to_active_tree &&
+ layer_tree_impl()->IsActiveTree() && can_recreate_highres_tiling &&
+ !layer_tree_impl()->HasPendingTree();
+
if (should_recreate_high_res) {
tilings_->Remove(high_res);
high_res = nullptr;
+ } else if (can_request_invalidation_for_high_res) {
+ // Anytime a condition which flips whether we can recreate the tiling
+ // changes, we'll get a call to UpdateDrawProperties. We check whether we
+ // could recreate the tiling when this runs on the active tree to trigger
+ // an impl-side invalidation (if needed).
+ layer_tree_impl()->RequestImplSideInvalidationForRerasterTiling();
} else if (!has_adjusted_raster_scale) {
// Nothing changed, no need to update tilings.
DCHECK_EQ(HIGH_RESOLUTION, high_res->resolution());
@@ -1353,7 +1375,7 @@ bool PictureLayerImpl::ShouldAdjustRasterScale() const {
// will-change: transform hint to preserve maximum resolution tiles
// needed.
if (draw_properties().screen_space_transform_is_animating ||
- !HasWillChangeTransformHint())
+ !AffectedByWillChangeTransformHint())
return true;
}
@@ -1418,7 +1440,7 @@ bool PictureLayerImpl::ShouldAdjustRasterScale() const {
// Don't update will-change: transform layers if the raster contents scale is
// bigger than the minimum scale.
- if (HasWillChangeTransformHint()) {
+ if (AffectedByWillChangeTransformHint()) {
float min_raster_scale = MinimumRasterContentsScaleForWillChangeTransform();
if (raster_contents_scale_.x() >= min_raster_scale &&
raster_contents_scale_.y() >= min_raster_scale)
@@ -1525,7 +1547,7 @@ void PictureLayerImpl::RecalculateRasterScales() {
if (draw_properties().screen_space_transform_is_animating)
AdjustRasterScaleForTransformAnimation(preserved_raster_contents_scale);
- if (HasWillChangeTransformHint()) {
+ if (AffectedByWillChangeTransformHint()) {
float min_scale = MinimumRasterContentsScaleForWillChangeTransform();
raster_contents_scale_.SetToMax(gfx::Vector2dF(min_scale, min_scale));
}
@@ -1571,7 +1593,7 @@ void PictureLayerImpl::AdjustRasterScaleForTransformAnimation(
raster_contents_scale_.SetToMax(
gfx::Vector2dF(maximum_animation_scale, maximum_animation_scale));
- if (HasWillChangeTransformHint()) {
+ if (AffectedByWillChangeTransformHint()) {
// If we have a will-change: transform hint, do not shrink the content
// raster scale, otherwise we will end up throwing away larger tiles we may
// need again.
@@ -1637,7 +1659,7 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
float PictureLayerImpl::MinimumRasterContentsScaleForWillChangeTransform()
const {
- DCHECK(HasWillChangeTransformHint());
+ DCHECK(AffectedByWillChangeTransformHint());
float native_scale = ideal_device_scale_ * ideal_page_scale_;
float ideal_scale = ideal_contents_scale_key();
// Clamp will-change: transform layers to be at least the native scale,
@@ -1810,7 +1832,7 @@ void PictureLayerImpl::UpdateIdealScales() {
ideal_contents_scale_ = GetIdealContentsScale();
if (layer_tree_impl()->PageScaleTransformNode()) {
- DCHECK(!layer_tree_impl()->settings().is_layer_tree_for_subframe);
+ DCHECK(layer_tree_impl()->settings().is_for_scalable_page);
ideal_page_scale_ = IsAffectedByPageScale()
? layer_tree_impl()->current_page_scale_factor()
: 1.f;
@@ -1819,16 +1841,16 @@ void PictureLayerImpl::UpdateIdealScales() {
// This layer may be in a layer tree embedded in a hierarchy that has its own
// page scale factor. We represent that here as 'external_page_scale_factor',
// a value that affects raster scale in the same way that page_scale_factor
- // does, but doesn't affect any geometry calculations. In a normal main frame
- // or OOPIF, only one of current or external page scale factor is ever used
- // but not both. The only exception to this is a main frame in a portal. It
- // may have a current_page_scale_factor (e.g. due to a viewport <meta> tag)
- // as well as an external_page_scale_factor coming from the page scale of its
- // embedder page.
+ // does, but doesn't affect any geometry calculations. In a normal main frame,
+ // fenced frame, or OOPIF, only one of current or external page scale factor
+ // is ever used but not both. The only exception to this is a main frame in a
+ // portal or a guest view. In these cases we may have a
+ // current_page_scale_factor (e.g. due to a viewport <meta> tag) as well as an
+ // external_page_scale_factor coming from the page scale of its embedder page.
float external_page_scale_factor =
layer_tree_impl() ? layer_tree_impl()->external_page_scale_factor() : 1.f;
DCHECK(!layer_tree_impl() ||
- !layer_tree_impl()->settings().is_layer_tree_for_subframe ||
+ layer_tree_impl()->settings().is_for_scalable_page ||
external_page_scale_factor == 1.f ||
layer_tree_impl()->current_page_scale_factor() == 1.f);
ideal_page_scale_ *= external_page_scale_factor;
@@ -1842,9 +1864,8 @@ void PictureLayerImpl::UpdateIdealScales() {
ideal_contents_scale_.y() / ideal_page_scale_};
}
-void PictureLayerImpl::GetDebugBorderProperties(
- SkColor* color,
- float* width) const {
+void PictureLayerImpl::GetDebugBorderProperties(SkColor4f* color,
+ float* width) const {
float device_scale_factor =
layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
diff --git a/chromium/cc/layers/picture_layer_impl.h b/chromium/cc/layers/picture_layer_impl.h
index b25dfa0a0fc..23ca1f2c635 100644
--- a/chromium/cc/layers/picture_layer_impl.h
+++ b/chromium/cc/layers/picture_layer_impl.h
@@ -214,7 +214,7 @@ class CC_EXPORT PictureLayerImpl
void SanityCheckTilingState() const;
- void GetDebugBorderProperties(SkColor* color, float* width) const override;
+ void GetDebugBorderProperties(SkColor4f* color, float* width) const override;
void GetAllPrioritizedTilesForTracing(
std::vector<PrioritizedTile>* prioritized_tiles) const override;
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -236,10 +236,9 @@ class CC_EXPORT PictureLayerImpl
bool raster_translation_aligns_pixels) const;
void UpdateCanUseLCDText(bool raster_translation_aligns_pixels);
- // TODO(crbug.com/1114504): For now this checks the immediate transform node
- // only. The callers may actually want to know if this layer or ancestor has
- // will change transform.
- bool HasWillChangeTransformHint() const;
+ // Whether the transform node for this layer, or any ancestor transform
+ // node, has a will-change hint for one of the transform properties.
+ bool AffectedByWillChangeTransformHint() const;
raw_ptr<PictureLayerImpl> twin_layer_ = nullptr;
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index 53ff0342e61..ba9a96637b4 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -915,7 +915,7 @@ TEST_F(LegacySWPictureLayerImplTest, CleanUpTilings) {
float page_scale = 1.f;
SetupDefaultTrees(layer_bounds);
- GetTransformNode(active_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings());
EXPECT_FLOAT_EQ(
1.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key());
@@ -2073,7 +2073,7 @@ TEST_F(LegacySWPictureLayerImplTest,
SetInitialDeviceScaleFactor(2.f);
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
- GetTransformNode(active_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
// One ideal tile exists, this will get used when drawing.
std::vector<Tile*> ideal_tiles;
@@ -3103,8 +3103,8 @@ TEST_F(LegacySWPictureLayerImplTest,
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f);
- GetTransformNode(active_layer())->will_change_transform = true;
- GetTransformNode(pending_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
+ SetWillChangeTransform(pending_layer(), true);
// Starting an animation should cause tiling resolution to get set to the
// maximum animation scale factor.
@@ -3134,6 +3134,41 @@ TEST_F(LegacySWPictureLayerImplTest,
// we should not reset the scale factor.
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
+
+ // Test that will-change:transform on an ancestor has the same
+ // effects. We happen to have the page scale layer as an ancestor, so
+ // just use that.
+ maximum_animation_scale = 2.f;
+ LayerImpl* active_page_scale_layer =
+ host_impl()->active_tree()->LayerById(active_layer()->id() - 1);
+ LayerImpl* pending_page_scale_layer =
+ host_impl()->pending_tree()->LayerById(pending_layer()->id() - 1);
+ DCHECK_EQ(GetTransformNode(active_page_scale_layer)->id,
+ GetTransformNode(active_layer())->parent_id);
+ DCHECK_EQ(GetTransformNode(pending_page_scale_layer)->id,
+ GetTransformNode(pending_layer())->parent_id);
+ SetWillChangeTransform(active_layer(), false);
+ SetWillChangeTransform(pending_layer(), false);
+ SetContentsScaleOnBothLayers(contents_scale * 2.f, device_scale, page_scale);
+ SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
+ EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f);
+ SetContentsAndAnimationScalesOnBothLayers(contents_scale, device_scale,
+ page_scale, maximum_animation_scale,
+ affected_by_invalid_scale);
+ EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
+ SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
+ EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f);
+ SetWillChangeTransform(active_page_scale_layer, true);
+ SetWillChangeTransform(pending_page_scale_layer, true);
+ // re-set the false so node_or_ancestors_will_change_transform is recomputed
+ SetWillChangeTransform(active_layer(), false);
+ SetWillChangeTransform(pending_layer(), false);
+ SetContentsAndAnimationScalesOnBothLayers(contents_scale, device_scale,
+ page_scale, maximum_animation_scale,
+ affected_by_invalid_scale);
+ EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
+ SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
+ EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
}
TEST_F(LegacySWPictureLayerImplTest, HighResTilingDuringAnimationAspectRatio) {
@@ -3193,8 +3228,8 @@ TEST_F(LegacySWPictureLayerImplTest,
// The clamping logic still works with will-change:transform.
// Raster source size change forces adjustment of raster scale.
- GetTransformNode(active_layer())->will_change_transform = true;
- GetTransformNode(pending_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
+ SetWillChangeTransform(pending_layer(), true);
layer_bounds = gfx::Size(200, 200);
Region invalidation;
// UpdateRasterSource() requires that the pending tree doesn't have tiles.
@@ -3674,8 +3709,8 @@ TEST_F(LegacySWPictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
// If we change the layer contents scale after setting will change
// will, then it will be updated if it's below the minimum scale (page scale *
// device scale).
- GetTransformNode(active_layer())->will_change_transform = true;
- GetTransformNode(pending_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
+ SetWillChangeTransform(pending_layer(), true);
contents_scale = 0.75f;
@@ -3698,8 +3733,8 @@ TEST_F(LegacySWPictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
// Disabling the will-change hint will once again make the raster scale update
// with the ideal scale.
- GetTransformNode(active_layer())->will_change_transform = false;
- GetTransformNode(pending_layer())->will_change_transform = false;
+ SetWillChangeTransform(active_layer(), false);
+ SetWillChangeTransform(pending_layer(), false);
contents_scale = 3.f;
@@ -3723,8 +3758,8 @@ TEST_F(LegacySWPictureLayerImplTest, TinyRasterScale) {
// If we change the layer contents scale after setting will change
// will, then it will be updated if it's below the minimum scale (page scale *
// device scale).
- GetTransformNode(active_layer())->will_change_transform = true;
- GetTransformNode(pending_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
+ SetWillChangeTransform(pending_layer(), true);
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
// The scale is clamped to the native scale.
@@ -3760,8 +3795,8 @@ TEST_F(LegacySWPictureLayerImplTest,
float contents_scale = 1.f;
float device_scale = 1.f;
float page_scale = 1.f;
- GetTransformNode(active_layer())->will_change_transform = true;
- GetTransformNode(pending_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
+ SetWillChangeTransform(pending_layer(), true);
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f);
@@ -4011,7 +4046,7 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) {
float page_scale = 1.f;
float scale = 1.f;
- GetTransformNode(active_layer())->will_change_transform = true;
+ SetWillChangeTransform(active_layer(), true);
ResetTilingsAndRasterScales();
SetContentsScaleOnBothLayers(scale, device_scale, page_scale);
@@ -5682,21 +5717,27 @@ TEST_F(LegacySWPictureLayerImplTest, HighResWasLowResCollision) {
TEST_F(LegacySWPictureLayerImplTest, CompositedImageCalculateContentsScale) {
gfx::Size layer_bounds(400, 400);
+ gfx::Rect layer_rect(layer_bounds);
+
+ host_impl()->active_tree()->SetDeviceViewportRect(layer_rect);
+
scoped_refptr<FakeRasterSource> pending_raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
+ SetupPendingTree(pending_raster_source);
- host_impl()->CreatePendingTree();
LayerTreeImpl* pending_tree = host_impl()->pending_tree();
+ const int kLayerId = 100;
std::unique_ptr<FakePictureLayerImpl> pending_layer =
- FakePictureLayerImpl::Create(pending_tree, root_id(),
+ FakePictureLayerImpl::Create(pending_tree, kLayerId,
pending_raster_source);
pending_layer->SetDirectlyCompositedImageDefaultRasterScale(
gfx::Vector2dF(1, 1));
pending_layer->SetDrawsContent(true);
FakePictureLayerImpl* pending_layer_ptr = pending_layer.get();
- pending_tree->SetRootLayerForTesting(std::move(pending_layer));
- SetupRootProperties(pending_layer_ptr);
+ pending_tree->AddLayer(std::move(pending_layer));
+ CopyProperties(pending_tree->root_layer(), pending_layer_ptr);
+
UpdateDrawProperties(pending_tree);
SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, 2.f, 3.f, 4.f);
@@ -5706,23 +5747,26 @@ TEST_F(LegacySWPictureLayerImplTest, CompositedImageCalculateContentsScale) {
TEST_F(LegacySWPictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) {
gfx::Size layer_bounds(400, 400);
gfx::Rect layer_rect(layer_bounds);
+
+ host_impl()->active_tree()->SetDeviceViewportRect(layer_rect);
+
scoped_refptr<FakeRasterSource> pending_raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
+ SetupPendingTree(pending_raster_source);
- host_impl()->active_tree()->SetDeviceViewportRect(layer_rect);
- host_impl()->CreatePendingTree();
LayerTreeImpl* pending_tree = host_impl()->pending_tree();
+ const int kLayerId = 100;
std::unique_ptr<FakePictureLayerImpl> pending_layer =
- FakePictureLayerImpl::Create(pending_tree, root_id(),
+ FakePictureLayerImpl::Create(pending_tree, kLayerId,
pending_raster_source);
pending_layer->SetDirectlyCompositedImageDefaultRasterScale(
gfx::Vector2dF(1, 1));
pending_layer->SetDrawsContent(true);
FakePictureLayerImpl* pending_layer_ptr = pending_layer.get();
- pending_tree->SetRootLayerForTesting(std::move(pending_layer));
- pending_tree->SetDeviceViewportRect(layer_rect);
- SetupRootProperties(pending_layer_ptr);
+ pending_tree->AddLayer(std::move(pending_layer));
+ CopyProperties(pending_tree->root_layer(), pending_layer_ptr);
+
UpdateDrawProperties(pending_tree);
// Set PictureLayerImpl::ideal_contents_scale_ to 2.f.
@@ -5739,7 +5783,7 @@ TEST_F(LegacySWPictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) {
host_impl()->ActivateSyncTree();
FakePictureLayerImpl* active_layer = static_cast<FakePictureLayerImpl*>(
- host_impl()->active_tree()->root_layer());
+ host_impl()->active_tree()->LayerById(kLayerId));
SetupDrawPropertiesAndUpdateTiles(active_layer,
suggested_ideal_contents_scale,
device_scale_factor, page_scale_factor);
@@ -6236,7 +6280,7 @@ TEST_F(LegacySWPictureLayerImplTest,
FakeRasterSource::CreateFilledWithText(gfx::Size(200, 200));
SetupTreesWithInvalidation(raster_source, raster_source, Region());
- pending_layer()->SetBackgroundColor(SK_ColorWHITE);
+ pending_layer()->SetBackgroundColor(SkColors::kWhite);
pending_layer()->SetContentsOpaque(true);
pending_layer()->SetOffsetToTransformParent(gfx::Vector2dF(0.2, 0.3));
host_impl()->pending_tree()->set_needs_update_draw_properties();
@@ -6292,7 +6336,7 @@ TEST_F(LegacySWPictureLayerImplTest,
auto raster_source = FakeRasterSource::CreateFilled(gfx::Size(200, 200));
SetupTreesWithInvalidation(raster_source, raster_source, Region());
- pending_layer()->SetBackgroundColor(SK_ColorWHITE);
+ pending_layer()->SetBackgroundColor(SkColors::kWhite);
pending_layer()->SetContentsOpaque(true);
pending_layer()->SetOffsetToTransformParent(gfx::Vector2dF(0.2, 0.3));
host_impl()->pending_tree()->set_needs_update_draw_properties();
@@ -6496,14 +6540,14 @@ TEST_P(LCDTextTest, Opacity) {
TEST_P(LCDTextTest, ContentsNotOpaque) {
// Non-opaque content and opaque background.
layer_->SetContentsOpaque(false);
- layer_->SetBackgroundColor(SK_ColorGREEN);
+ layer_->SetBackgroundColor(SkColors::kGreen);
CheckCanUseLCDText(LCDTextDisallowedReason::kContentsNotOpaque,
"contents not opaque", layer_);
CheckCanUseLCDText(LCDTextDisallowedReason::kNone,
"descedant of contents not opaque", descendant_);
// Non-opaque content and non-opaque background.
- layer_->SetBackgroundColor(SkColorSetARGB(128, 255, 255, 255));
+ layer_->SetBackgroundColor({1.0f, 1.0f, 1.0f, 0.5f});
CheckCanUseLCDText(LCDTextDisallowedReason::kBackgroundColorNotOpaque,
"background not opaque", layer_);
CheckCanUseLCDText(LCDTextDisallowedReason::kNone,
@@ -6591,7 +6635,7 @@ TEST_P(LCDTextTest, BackdropFilterAnimation) {
TEST_P(LCDTextTest, ContentsOpaqueForText) {
layer_->SetContentsOpaque(false);
- layer_->SetBackgroundColor(SK_ColorGREEN);
+ layer_->SetBackgroundColor(SkColors::kGreen);
layer_->SetContentsOpaqueForText(true);
CheckCanUseLCDText(LCDTextDisallowedReason::kNone, "contents opaque for text",
layer_);
diff --git a/chromium/cc/layers/recording_source.cc b/chromium/cc/layers/recording_source.cc
index 7e5de75f1f9..3d618c14319 100644
--- a/chromium/cc/layers/recording_source.cc
+++ b/chromium/cc/layers/recording_source.cc
@@ -115,7 +115,7 @@ void RecordingSource::SetSlowdownRasterScaleFactor(int factor) {
slow_down_raster_scale_factor_for_debug_ = factor;
}
-void RecordingSource::SetBackgroundColor(SkColor background_color) {
+void RecordingSource::SetBackgroundColor(SkColor4f background_color) {
background_color_ = background_color;
}
@@ -130,7 +130,7 @@ scoped_refptr<RasterSource> RecordingSource::CreateRasterSource() const {
void RecordingSource::DetermineIfSolidColor() {
DCHECK(display_list_);
is_solid_color_ = false;
- solid_color_ = SK_ColorTRANSPARENT;
+ solid_color_ = SkColors::kTransparent;
if (display_list_->TotalOpCount() > kMaxOpsToAnalyzeForLayer)
return;
diff --git a/chromium/cc/layers/recording_source.h b/chromium/cc/layers/recording_source.h
index 0f9c6eff422..d0df0ac1429 100644
--- a/chromium/cc/layers/recording_source.h
+++ b/chromium/cc/layers/recording_source.h
@@ -36,7 +36,7 @@ class CC_EXPORT RecordingSource {
gfx::Size GetSize() const;
void SetEmptyBounds();
void SetSlowdownRasterScaleFactor(int factor);
- void SetBackgroundColor(SkColor background_color);
+ void SetBackgroundColor(SkColor4f background_color);
void SetRequiresClear(bool requires_clear);
void SetNeedsDisplayRect(const gfx::Rect& layer_rect);
@@ -52,8 +52,8 @@ class CC_EXPORT RecordingSource {
int slow_down_raster_scale_factor_for_debug_ = 0;
bool requires_clear_ = false;
bool is_solid_color_ = false;
- SkColor solid_color_ = SK_ColorTRANSPARENT;
- SkColor background_color_ = SK_ColorTRANSPARENT;
+ SkColor4f solid_color_ = SkColors::kTransparent;
+ SkColor4f background_color_ = SkColors::kTransparent;
scoped_refptr<DisplayItemList> display_list_;
float recording_scale_factor_ = 1.0f;
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index 6636586c4ff..d274baf743c 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -111,7 +111,8 @@ SkBlendMode RenderSurfaceImpl::BlendMode() const {
}
SkColor RenderSurfaceImpl::GetDebugBorderColor() const {
- return DebugColors::SurfaceBorderColor();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ return DebugColors::SurfaceBorderColor().toSkColor();
}
float RenderSurfaceImpl::GetDebugBorderWidth() const {
diff --git a/chromium/cc/layers/solid_color_layer.cc b/chromium/cc/layers/solid_color_layer.cc
index adf0319e52e..8cc831ed7fe 100644
--- a/chromium/cc/layers/solid_color_layer.cc
+++ b/chromium/cc/layers/solid_color_layer.cc
@@ -23,8 +23,8 @@ SolidColorLayer::SolidColorLayer() = default;
SolidColorLayer::~SolidColorLayer() = default;
-void SolidColorLayer::SetBackgroundColor(SkColor color) {
- SetContentsOpaque(SkColorGetA(color) == 255);
+void SolidColorLayer::SetBackgroundColor(SkColor4f color) {
+ SetContentsOpaque(color.isOpaque());
Layer::SetBackgroundColor(color);
}
diff --git a/chromium/cc/layers/solid_color_layer.h b/chromium/cc/layers/solid_color_layer.h
index 77dabef7980..ea24db75029 100644
--- a/chromium/cc/layers/solid_color_layer.h
+++ b/chromium/cc/layers/solid_color_layer.h
@@ -25,7 +25,7 @@ class CC_EXPORT SolidColorLayer : public Layer {
std::unique_ptr<LayerImpl> CreateLayerImpl(
LayerTreeImpl* tree_impl) const override;
- void SetBackgroundColor(SkColor color) override;
+ void SetBackgroundColor(SkColor4f color) override;
protected:
SolidColorLayer();
diff --git a/chromium/cc/layers/solid_color_layer_impl.cc b/chromium/cc/layers/solid_color_layer_impl.cc
index 9baa31ce948..7e6332cf236 100644
--- a/chromium/cc/layers/solid_color_layer_impl.cc
+++ b/chromium/cc/layers/solid_color_layer_impl.cc
@@ -31,7 +31,7 @@ void SolidColorLayerImpl::AppendSolidQuads(
const Occlusion& occlusion_in_layer_space,
viz::SharedQuadState* shared_quad_state,
const gfx::Rect& visible_layer_rect,
- SkColor color,
+ SkColor4f color,
bool force_anti_aliasing_off,
SkBlendMode effect_blend_mode,
AppendQuadsData* append_quads_data) {
@@ -45,8 +45,7 @@ void SolidColorLayerImpl::AppendSolidQuads(
// mask, but will not work in complex blend mode situations. This bug is
// tracked in crbug.com/939168.
if (effect_blend_mode == SkBlendMode::kSrcOver) {
- float alpha =
- (SkColorGetA(color) * (1.0f / 255.0f)) * shared_quad_state->opacity;
+ float alpha = color.fA * shared_quad_state->opacity;
if (alpha < std::numeric_limits<float>::epsilon())
return;
@@ -58,8 +57,9 @@ void SolidColorLayerImpl::AppendSolidQuads(
return;
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- quad->SetNew(shared_quad_state, visible_layer_rect, visible_quad_rect, color,
- force_anti_aliasing_off);
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ quad->SetNew(shared_quad_state, visible_layer_rect, visible_quad_rect,
+ color.toSkColor(), force_anti_aliasing_off);
}
void SolidColorLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
diff --git a/chromium/cc/layers/solid_color_layer_impl.h b/chromium/cc/layers/solid_color_layer_impl.h
index 2090424d5d2..321e6b2c3f7 100644
--- a/chromium/cc/layers/solid_color_layer_impl.h
+++ b/chromium/cc/layers/solid_color_layer_impl.h
@@ -27,7 +27,7 @@ class CC_EXPORT SolidColorLayerImpl : public LayerImpl {
const Occlusion& occlusion_in_layer_space,
viz::SharedQuadState* shared_quad_state,
const gfx::Rect& visible_layer_rect,
- SkColor color,
+ SkColor4f color,
bool force_anti_aliasing_off,
SkBlendMode effect_blend_mode,
AppendQuadsData* append_quads_data);
diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
index c921c646df7..4b45a147510 100644
--- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc
+++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
@@ -33,7 +33,7 @@ TEST_F(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) {
auto* layer = AddLayer<SolidColorLayerImpl>();
layer->SetBounds(layer_size);
layer->SetDrawsContent(true);
- layer->SetBackgroundColor(SK_ColorRED);
+ layer->SetBackgroundColor(SkColors::kRed);
CopyProperties(root_layer(), layer);
CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest;
UpdateActiveTreeDrawProperties();
@@ -44,7 +44,10 @@ TEST_F(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) {
}
TEST_F(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) {
- SkColor test_color = 0xFFA55AFF;
+ // TODO(crbug.com/1308932): Somewhere along the path this gets cast to an int
+ // so the test fails if the values are not x/255. This should not be the case
+ // when the SkColor4f project is completed.
+ SkColor4f test_color{165.0f / 255.0f, 90.0f / 255.0f, 1.0f, 1.0f};
auto render_pass = viz::CompositorRenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
@@ -78,7 +81,7 @@ TEST_F(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) {
auto* layer = AddLayer<SolidColorLayerImpl>();
layer->SetDrawsContent(true);
layer->SetBounds(layer_size);
- layer->SetBackgroundColor(SK_ColorRED);
+ layer->SetBackgroundColor(SkColors::kRed);
CopyProperties(root_layer(), layer);
auto& effect_node = CreateEffectNode(layer);
effect_node.opacity = opacity;
@@ -104,7 +107,7 @@ TEST_F(SolidColorLayerImplTest, VerifyCorrectRenderSurfaceOpacityInQuad) {
auto* layer = AddLayer<SolidColorLayerImpl>();
layer->SetDrawsContent(true);
layer->SetBounds(layer_size);
- layer->SetBackgroundColor(SK_ColorRED);
+ layer->SetBackgroundColor(SkColors::kRed);
CopyProperties(root_layer(), layer);
auto& effect_node = CreateEffectNode(layer);
effect_node.render_surface_reason = RenderSurfaceReason::kTest;
@@ -126,7 +129,7 @@ TEST_F(SolidColorLayerImplTest, VerifyCorrectRenderSurfaceOpacityInQuad) {
}
TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentAlpha) {
- SkColor test_color = 0;
+ SkColor4f test_color = SkColors::kTransparent;
auto render_pass = viz::CompositorRenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
@@ -144,7 +147,7 @@ TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentAlpha) {
}
TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentOpacity) {
- SkColor test_color = 0xFFA55AFF;
+ SkColor4f test_color{0.5f, 0.8f, 1.0f, 1.0f};
auto render_pass = viz::CompositorRenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
@@ -184,7 +187,7 @@ TEST_F(SolidColorLayerImplTest, VerifyNeedsBlending) {
UpdateDrawProperties(host.get());
EXPECT_FALSE(layer->contents_opaque());
- layer->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30));
+ layer->SetBackgroundColor({0.2f, 0.3f, 0.4f, 1.0f});
EXPECT_TRUE(layer->contents_opaque());
auto& unsafe_state = host->GetUnsafeStateForCommit();
@@ -220,7 +223,7 @@ TEST_F(SolidColorLayerImplTest, VerifyNeedsBlending) {
host->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()});
EXPECT_TRUE(layer->contents_opaque());
- layer->SetBackgroundColor(SkColorSetARGB(254, 10, 20, 30));
+ layer->SetBackgroundColor({0.2f, 0.3f, 0.4f, 0.9f});
EXPECT_FALSE(layer->contents_opaque());
completion_event_ptr = std::make_unique<CompletionEvent>(
@@ -260,7 +263,7 @@ TEST_F(SolidColorLayerImplTest, Occlusion) {
gfx::Size viewport_size(1000, 1000);
auto* solid_color_layer_impl = AddLayer<SolidColorLayerImpl>();
- solid_color_layer_impl->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30));
+ solid_color_layer_impl->SetBackgroundColor({0.1f, 0.2f, 0.3f, 1.0f});
solid_color_layer_impl->SetBounds(layer_size);
solid_color_layer_impl->SetDrawsContent(true);
CopyProperties(root_layer(), solid_color_layer_impl);
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
index 8a3f3a2f460..f1b8b88edf3 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
@@ -50,7 +50,9 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl(
/*is_overlay*/ true),
thumb_thickness_(thumb_thickness),
track_start_(track_start),
- color_(tree_impl->settings().solid_color_scrollbar_color) {}
+ // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
+ color_(SkColor4f::FromColor(
+ tree_impl->settings().solid_color_scrollbar_color)) {}
void SolidColorScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) {
ScrollbarLayerImplBase::PushPropertiesTo(layer);
@@ -106,8 +108,9 @@ void SolidColorScrollbarLayerImpl::AppendQuads(
return;
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- quad->SetNew(
- shared_quad_state, thumb_quad_rect, visible_quad_rect, color_, false);
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ quad->SetNew(shared_quad_state, thumb_quad_rect, visible_quad_rect,
+ color_.toSkColor(), false);
}
const char* SolidColorScrollbarLayerImpl::LayerTypeAsString() const {
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h
index 6aff854d3f5..2c688ed4c4d 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h
+++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h
@@ -52,7 +52,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase {
int thumb_thickness_;
int track_start_;
- SkColor color_;
+ SkColor4f color_;
};
} // namespace cc
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index b58be0601fa..c3050488efb 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -182,8 +182,9 @@ void SurfaceLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
if (surface_range_.IsValid()) {
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- surface_range_, background_color(),
+ surface_range_, background_color().toSkColor(),
stretch_content_to_fill_bounds_);
quad->is_reflection = is_reflection_;
// Add the primary surface ID as a dependency.
@@ -199,8 +200,10 @@ void SurfaceLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
} else {
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- background_color(), false /* force_anti_aliasing_off */);
+ background_color().toSkColor(),
+ false /* force_anti_aliasing_off */);
}
// Unless the client explicitly specifies otherwise, don't block on
@@ -217,7 +220,7 @@ gfx::Rect SurfaceLayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
layer_tree_impl()->device_scale_factor());
}
-void SurfaceLayerImpl::GetDebugBorderProperties(SkColor* color,
+void SurfaceLayerImpl::GetDebugBorderProperties(SkColor4f* color,
float* width) const {
*color = DebugColors::SurfaceLayerBorderColor();
*width = DebugColors::SurfaceLayerBorderWidth(
@@ -233,7 +236,7 @@ void SurfaceLayerImpl::AppendRainbowDebugBorder(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state, contents_opaque());
- SkColor color;
+ SkColor4f color;
float border_width;
GetDebugBorderProperties(&color, &border_width);
diff --git a/chromium/cc/layers/surface_layer_impl.h b/chromium/cc/layers/surface_layer_impl.h
index 12174b65cbb..936028b65d9 100644
--- a/chromium/cc/layers/surface_layer_impl.h
+++ b/chromium/cc/layers/surface_layer_impl.h
@@ -75,7 +75,7 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
SurfaceLayerImpl(LayerTreeImpl* tree_impl, int id, UpdateSubmissionStateCB);
private:
- void GetDebugBorderProperties(SkColor* color, float* width) const override;
+ void GetDebugBorderProperties(SkColor4f* color, float* width) const override;
void AppendRainbowDebugBorder(viz::CompositorRenderPass* render_pass);
void AsValueInto(base::trace_event::TracedValue* dict) const override;
const char* LayerTypeAsString() const override;
diff --git a/chromium/cc/layers/surface_layer_impl_unittest.cc b/chromium/cc/layers/surface_layer_impl_unittest.cc
index dae84867f66..808aeea3fc9 100644
--- a/chromium/cc/layers/surface_layer_impl_unittest.cc
+++ b/chromium/cc/layers/surface_layer_impl_unittest.cc
@@ -97,7 +97,7 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) {
surface_layer_impl->SetBounds(layer_size);
surface_layer_impl->SetDrawsContent(true);
surface_layer_impl->SetRange(viz::SurfaceRange(surface_id2, surface_id1), 2u);
- surface_layer_impl->SetBackgroundColor(SK_ColorBLUE);
+ surface_layer_impl->SetBackgroundColor(SkColors::kBlue);
CopyProperties(impl.root_layer(), surface_layer_impl);
gfx::Size viewport_size(1000, 1000);
@@ -159,15 +159,15 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) {
ASSERT_TRUE(surface_draw_quad3);
EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.end());
- EXPECT_EQ(SK_ColorBLUE, surface_draw_quad1->default_background_color);
+ EXPECT_EQ(SkColors::kBlue, surface_draw_quad1->default_background_color);
EXPECT_EQ(surface_id2, surface_draw_quad1->surface_range.start());
EXPECT_EQ(surface_id1, surface_draw_quad2->surface_range.end());
- EXPECT_EQ(SK_ColorBLUE, surface_draw_quad2->default_background_color);
+ EXPECT_EQ(SkColors::kBlue, surface_draw_quad2->default_background_color);
EXPECT_EQ(absl::nullopt, surface_draw_quad2->surface_range.start());
EXPECT_EQ(surface_id1, surface_draw_quad3->surface_range.end());
- EXPECT_EQ(SK_ColorBLUE, surface_draw_quad3->default_background_color);
+ EXPECT_EQ(SkColors::kBlue, surface_draw_quad3->default_background_color);
EXPECT_EQ(surface_id2, surface_draw_quad3->surface_range.start());
}
@@ -235,7 +235,7 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) {
surface_layer_impl->SetDrawsContent(true);
surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 1u);
surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 2u);
- surface_layer_impl->SetBackgroundColor(SK_ColorBLUE);
+ surface_layer_impl->SetBackgroundColor(SkColors::kBlue);
CopyProperties(impl.root_layer(), surface_layer_impl);
gfx::Size viewport_size(1000, 1000);
@@ -254,7 +254,7 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) {
EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.end());
EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.start());
- EXPECT_EQ(SK_ColorBLUE, surface_draw_quad1->default_background_color);
+ EXPECT_EQ(SkColors::kBlue, surface_draw_quad1->default_background_color);
}
TEST(SurfaceLayerImplTest, GetEnclosingRectInTargetSpace) {
diff --git a/chromium/cc/layers/surface_layer_unittest.cc b/chromium/cc/layers/surface_layer_unittest.cc
index 2ba3751761c..f70a27470e8 100644
--- a/chromium/cc/layers/surface_layer_unittest.cc
+++ b/chromium/cc/layers/surface_layer_unittest.cc
@@ -138,7 +138,7 @@ TEST_F(SurfaceLayerTest, PushProperties) {
layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(2u));
layer->SetSurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
layer->SetOldestAcceptableFallback(primary_id);
- layer->SetBackgroundColor(SK_ColorBLUE);
+ layer->SetBackgroundColor(SkColors::kBlue);
layer->SetStretchContentToFillBounds(true);
EXPECT_TRUE(
@@ -166,7 +166,7 @@ TEST_F(SurfaceLayerTest, PushProperties) {
// Verify that the primary and fallback SurfaceIds are pushed through.
EXPECT_EQ(primary_id, layer_impl->range().end());
EXPECT_EQ(primary_id, layer_impl->range().start());
- EXPECT_EQ(SK_ColorBLUE, layer_impl->background_color());
+ EXPECT_EQ(SkColors::kBlue, layer_impl->background_color());
EXPECT_TRUE(layer_impl->stretch_content_to_fill_bounds());
EXPECT_EQ(2u, layer_impl->deadline_in_frames());
@@ -175,7 +175,7 @@ TEST_F(SurfaceLayerTest, PushProperties) {
viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
layer->SetOldestAcceptableFallback(fallback_id);
layer->SetSurfaceId(fallback_id, DeadlinePolicy::UseExistingDeadline());
- layer->SetBackgroundColor(SK_ColorGREEN);
+ layer->SetBackgroundColor(SkColors::kGreen);
layer->SetStretchContentToFillBounds(false);
// Verify that fallback surface id is not recorded on the layer tree host as
@@ -193,7 +193,7 @@ TEST_F(SurfaceLayerTest, PushProperties) {
// fallback viz::SurfaceId is pushed through.
EXPECT_EQ(fallback_id, layer_impl->range().end());
EXPECT_EQ(fallback_id, layer_impl->range().start());
- EXPECT_EQ(SK_ColorGREEN, layer_impl->background_color());
+ EXPECT_EQ(SkColors::kGreen, layer_impl->background_color());
// The deadline resets back to 0 (no deadline) after the first commit.
EXPECT_EQ(0u, layer_impl->deadline_in_frames());
EXPECT_FALSE(layer_impl->stretch_content_to_fill_bounds());
diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc
index 8b9bf91efff..a41414dbaf3 100644
--- a/chromium/cc/layers/texture_layer_impl.cc
+++ b/chromium/cc/layers/texture_layer_impl.cc
@@ -122,15 +122,14 @@ void TextureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
std::make_move_iterator(to_register_bitmaps_.end()));
to_register_bitmaps_.clear();
- SkColor bg_color =
- blend_background_color_ ? background_color() : SK_ColorTRANSPARENT;
+ SkColor4f bg_color =
+ blend_background_color_ ? background_color() : SkColors::kTransparent;
if (force_texture_to_opaque_) {
- bg_color = SK_ColorBLACK;
+ bg_color = SkColors::kBlack;
}
- bool are_contents_opaque =
- contents_opaque() || (SkColorGetA(bg_color) == 0xFF);
+ bool are_contents_opaque = contents_opaque() || bg_color.isOpaque();
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
@@ -148,11 +147,12 @@ void TextureLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
return;
float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, needs_blending,
resource_id_, premultiplied_alpha_, uv_top_left_,
- uv_bottom_right_, bg_color, vertex_opacity, flipped_,
- nearest_neighbor_, /*secure_output_only=*/false,
+ uv_bottom_right_, bg_color.toSkColor(), vertex_opacity, flipped_,
+ nearest_neighbor_, /*secure_output=*/false,
gfx::ProtectedVideoType::kClear);
quad->set_resource_size_in_pixels(transferable_resource_.size);
ValidateQuadResources(quad);
@@ -165,7 +165,7 @@ SimpleEnclosedRegion TextureLayerImpl::VisibleOpaqueRegion() const {
if (force_texture_to_opaque_)
return SimpleEnclosedRegion(visible_layer_rect());
- if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
+ if (blend_background_color_ && background_color().isOpaque())
return SimpleEnclosedRegion(visible_layer_rect());
return SimpleEnclosedRegion();
diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc
index 5ba92ea9c09..dc36daac534 100644
--- a/chromium/cc/layers/texture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/texture_layer_impl_unittest.cc
@@ -36,15 +36,15 @@ TEST(TextureLayerImplTest, VisibleOpaqueRegion) {
// Verify initial conditions.
EXPECT_FALSE(layer->contents_opaque());
- EXPECT_EQ(0u, layer->background_color());
+ EXPECT_EQ(SkColors::kTransparent, layer->background_color());
EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
// Opaque background.
- layer->SetBackgroundColor(SK_ColorWHITE);
+ layer->SetBackgroundColor(SkColors::kWhite);
EXPECT_EQ(layer_region.ToString(), layer->VisibleOpaqueRegion().ToString());
// Transparent background.
- layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
+ layer->SetBackgroundColor({1.0f, 1.0f, 1.0f, 0.5f});
EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
}
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index 945dec20616..3a8feebbfbf 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -1031,7 +1031,7 @@ class TextureLayerChangeInvisibleMailboxTest
solid_layer_ = SolidColorLayer::Create();
solid_layer_->SetBounds(gfx::Size(10, 10));
solid_layer_->SetIsDrawable(true);
- solid_layer_->SetBackgroundColor(SK_ColorWHITE);
+ solid_layer_->SetBackgroundColor(SkColors::kWhite);
root->AddChild(solid_layer_);
parent_layer_ = Layer::Create();
@@ -1067,7 +1067,7 @@ class TextureLayerChangeInvisibleMailboxTest
resource_changed_ = true;
texture_layer_->SetNeedsDisplay();
// Force a change to make sure we draw a frame.
- solid_layer_->SetBackgroundColor(SK_ColorGRAY);
+ solid_layer_->SetBackgroundColor(SkColors::kGray);
break;
case 3:
// Layer shouldn't have been updated.
@@ -1383,7 +1383,7 @@ class SoftwareTextureLayerTest : public LayerTreeTest {
// A drawable layer so that frames always get drawn.
solid_color_layer_ = SolidColorLayer::Create();
solid_color_layer_->SetIsDrawable(true);
- solid_color_layer_->SetBackgroundColor(SK_ColorRED);
+ solid_color_layer_->SetBackgroundColor(SkColors::kRed);
solid_color_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(solid_color_layer_);
diff --git a/chromium/cc/layers/tile_size_calculator.cc b/chromium/cc/layers/tile_size_calculator.cc
index ac95636f516..305ff973a97 100644
--- a/chromium/cc/layers/tile_size_calculator.cc
+++ b/chromium/cc/layers/tile_size_calculator.cc
@@ -121,7 +121,7 @@ gfx::Size CalculateGpuRawDrawTileSize(const gfx::Size& base_tile_size,
// AffectingParams.
bool TileSizeCalculator::AffectingParams::operator==(
- const AffectingParams& other) {
+ const AffectingParams& other) const {
return max_texture_size == other.max_texture_size &&
use_gpu_rasterization == other.use_gpu_rasterization &&
device_scale_factor == other.device_scale_factor &&
diff --git a/chromium/cc/layers/tile_size_calculator.h b/chromium/cc/layers/tile_size_calculator.h
index e4616b8c67d..c79bc2ba5f7 100644
--- a/chromium/cc/layers/tile_size_calculator.h
+++ b/chromium/cc/layers/tile_size_calculator.h
@@ -33,7 +33,7 @@ class CC_EXPORT TileSizeCalculator {
gfx::Size default_tile_size;
gfx::Size layer_content_bounds;
- bool operator==(const AffectingParams& other);
+ bool operator==(const AffectingParams& other) const;
};
PictureLayerImpl* layer_impl() const { return layer_impl_; }
diff --git a/chromium/cc/layers/video_frame_provider.h b/chromium/cc/layers/video_frame_provider.h
index 7ae08903b6b..7dff50c3ede 100644
--- a/chromium/cc/layers/video_frame_provider.h
+++ b/chromium/cc/layers/video_frame_provider.h
@@ -97,6 +97,10 @@ class CC_EXPORT VideoFrameProvider {
// the client.
virtual base::TimeDelta GetPreferredRenderInterval() = 0;
+ // Inform the provider that the context is lost. The provider need to reset
+ // the current frame if it's invald.
+ virtual void OnContextLost() = 0;
+
protected:
virtual ~VideoFrameProvider() {}
};
diff --git a/chromium/cc/metrics/begin_main_frame_metrics.h b/chromium/cc/metrics/begin_main_frame_metrics.h
index e9e479c2d5d..d12efb8c8f4 100644
--- a/chromium/cc/metrics/begin_main_frame_metrics.h
+++ b/chromium/cc/metrics/begin_main_frame_metrics.h
@@ -20,6 +20,7 @@ struct CC_EXPORT BeginMainFrameMetrics {
base::TimeDelta animate;
base::TimeDelta style_update;
base::TimeDelta layout_update;
+ base::TimeDelta accessibility;
base::TimeDelta prepaint;
base::TimeDelta compositing_inputs;
base::TimeDelta paint;
diff --git a/chromium/cc/metrics/compositor_frame_reporter.cc b/chromium/cc/metrics/compositor_frame_reporter.cc
index d3ecb6bb3d5..fb5bdb10ff0 100644
--- a/chromium/cc/metrics/compositor_frame_reporter.cc
+++ b/chromium/cc/metrics/compositor_frame_reporter.cc
@@ -21,6 +21,7 @@
#include "cc/base/rolling_time_delta_history.h"
#include "cc/metrics/dropped_frame_counter.h"
#include "cc/metrics/event_latency_tracing_recorder.h"
+#include "cc/metrics/event_latency_tracker.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "cc/metrics/latency_ukm_reporter.h"
#include "services/tracing/public/cpp/perfetto/macros.h"
@@ -180,6 +181,8 @@ CompositorFrameReporter::ProcessedBlinkBreakdown::ProcessedBlinkBreakdown(
blink_breakdown.style_update;
list_[static_cast<int>(BlinkBreakdown::kLayoutUpdate)] =
blink_breakdown.layout_update;
+ list_[static_cast<int>(BlinkBreakdown::kAccessibility)] =
+ blink_breakdown.accessibility;
list_[static_cast<int>(BlinkBreakdown::kPrepaint)] = blink_breakdown.prepaint;
list_[static_cast<int>(BlinkBreakdown::kCompositingInputs)] =
blink_breakdown.compositing_inputs;
@@ -320,18 +323,19 @@ CompositorFrameReporter::ProcessedVizBreakdown::CreateIterator(
CompositorFrameReporter::CompositorFrameReporter(
const ActiveTrackers& active_trackers,
const viz::BeginFrameArgs& args,
- bool should_report_metrics,
+ bool should_report_histograms,
SmoothThread smooth_thread,
FrameInfo::SmoothEffectDrivingThread scrolling_thread,
int layer_tree_host_id,
const GlobalMetricsTrackers& trackers)
- : should_report_metrics_(should_report_metrics),
+ : should_report_histograms_(should_report_histograms),
args_(args),
active_trackers_(active_trackers),
scrolling_thread_(scrolling_thread),
smooth_thread_(smooth_thread),
layer_tree_host_id_(layer_tree_host_id),
global_trackers_(trackers) {
+ DCHECK(global_trackers_.dropped_frame_counter);
global_trackers_.dropped_frame_counter->OnBeginFrame(
args, IsScrollActive(active_trackers_));
DCHECK(IsScrollActive(active_trackers_) ||
@@ -343,6 +347,16 @@ CompositorFrameReporter::CompositorFrameReporter(
DCHECK(smooth_thread_ == SmoothThread::kSmoothMain ||
smooth_thread_ == SmoothThread::kSmoothBoth);
}
+ // If we have a SET version of the animation, then we should also have a
+ // non-SET version of the same animation.
+ DCHECK(!active_trackers_.test(static_cast<size_t>(
+ FrameSequenceTrackerType::kSETCompositorAnimation)) ||
+ active_trackers_.test(static_cast<size_t>(
+ FrameSequenceTrackerType::kCompositorAnimation)));
+ DCHECK(!active_trackers_.test(static_cast<size_t>(
+ FrameSequenceTrackerType::kSETMainThreadAnimation)) ||
+ active_trackers_.test(static_cast<size_t>(
+ FrameSequenceTrackerType::kMainThreadAnimation)));
}
// static
@@ -374,6 +388,8 @@ const char* CompositorFrameReporter::GetStageName(
return "SendBeginMainFrameToCommit.StyleUpdate";
case BlinkBreakdown::kLayoutUpdate:
return "SendBeginMainFrameToCommit.LayoutUpdate";
+ case BlinkBreakdown::kAccessibility:
+ return "SendBeginMainFrameToCommit.AccessibiltyUpdate";
case BlinkBreakdown::kPrepaint:
return "SendBeginMainFrameToCommit.Prepaint";
case BlinkBreakdown::kCompositingInputs:
@@ -483,7 +499,7 @@ CompositorFrameReporter::CopyReporterAtBeginImplStage() {
return nullptr;
}
auto new_reporter = std::make_unique<CompositorFrameReporter>(
- active_trackers_, args_, should_report_metrics_, smooth_thread_,
+ active_trackers_, args_, should_report_histograms_, smooth_thread_,
scrolling_thread_, layer_tree_host_id_, global_trackers_);
new_reporter->did_finish_impl_frame_ = did_finish_impl_frame_;
new_reporter->impl_frame_finish_time_ = impl_frame_finish_time_;
@@ -604,6 +620,21 @@ EventMetrics::List CompositorFrameReporter::TakeEventsMetrics() {
return result;
}
+EventMetrics::List CompositorFrameReporter::TakeMainBlockedEventsMetrics() {
+ auto mid = std::partition(events_metrics_.begin(), events_metrics_.end(),
+ [](std::unique_ptr<EventMetrics>& metrics) {
+ DCHECK(metrics);
+ bool is_blocked_on_main =
+ metrics->requires_main_thread_update();
+ // Invert so we can take from the end.
+ return !is_blocked_on_main;
+ });
+ EventMetrics::List result(std::make_move_iterator(mid),
+ std::make_move_iterator(events_metrics_.end()));
+ events_metrics_.erase(mid, events_metrics_.end());
+ return result;
+}
+
void CompositorFrameReporter::TerminateReporter() {
if (frame_termination_status_ == FrameTerminationStatus::kUnknown)
TerminateFrame(FrameTerminationStatus::kUnknown, Now());
@@ -647,8 +678,10 @@ void CompositorFrameReporter::TerminateReporter() {
if (TestReportType(FrameReportType::kNonDroppedFrame))
ReportEventLatencyTraceEvents();
- // Only report compositor latency histograms if the frame was produced.
- if (should_report_metrics_ && report_types_.any()) {
+ // Only report compositor latency metrics if the frame was produced.
+ if (report_types_.any() &&
+ (should_report_histograms_ || global_trackers_.latency_ukm_reporter ||
+ global_trackers_.event_latency_tracker)) {
DCHECK(stage_history_.size());
DCHECK_EQ(SumOfStageHistory(), stage_history_.back().end_time -
stage_history_.front().start_time);
@@ -656,25 +689,22 @@ void CompositorFrameReporter::TerminateReporter() {
stage_history_.front().start_time,
stage_history_.back().end_time);
- ReportCompositorLatencyHistograms();
- // Only report event latency histograms if the frame was presented.
+ ReportCompositorLatencyMetrics();
+
+ // Only report event latency metrics if the frame was presented.
if (TestReportType(FrameReportType::kNonDroppedFrame))
- ReportEventLatencyHistograms();
+ ReportEventLatencyMetrics();
}
- auto* dropped_frame_counter = global_trackers_.dropped_frame_counter;
- if (dropped_frame_counter) {
- if (TestReportType(FrameReportType::kDroppedFrame)) {
- dropped_frame_counter->AddDroppedFrame();
- } else {
- if (has_partial_update_)
- dropped_frame_counter->AddPartialFrame();
- else
- dropped_frame_counter->AddGoodFrame();
- }
-
- dropped_frame_counter->OnEndFrame(args_, frame_info);
+ if (TestReportType(FrameReportType::kDroppedFrame)) {
+ global_trackers_.dropped_frame_counter->AddDroppedFrame();
+ } else {
+ if (has_partial_update_)
+ global_trackers_.dropped_frame_counter->AddPartialFrame();
+ else
+ global_trackers_.dropped_frame_counter->AddGoodFrame();
}
+ global_trackers_.dropped_frame_counter->OnEndFrame(args_, frame_info);
if (discarded_partial_update_dependents_count_ > 0)
UMA_HISTOGRAM_CUSTOM_COUNTS(
@@ -690,10 +720,20 @@ void CompositorFrameReporter::EndCurrentStage(base::TimeTicks end_time) {
current_stage_.start_time = base::TimeTicks();
}
-void CompositorFrameReporter::ReportCompositorLatencyHistograms() const {
+void CompositorFrameReporter::ReportCompositorLatencyMetrics() const {
static base::CpuReductionExperimentFilter filter;
if (!filter.ShouldLogHistograms())
return;
+
+ if (global_trackers_.latency_ukm_reporter) {
+ global_trackers_.latency_ukm_reporter->ReportCompositorLatencyUkm(
+ report_types_, stage_history_, active_trackers_,
+ *processed_blink_breakdown_, *processed_viz_breakdown_);
+ }
+
+ if (!should_report_histograms_)
+ return;
+
for (const StageData& stage : stage_history_) {
ReportStageHistogramWithBreakdown(stage);
@@ -708,12 +748,6 @@ void CompositorFrameReporter::ReportCompositorLatencyHistograms() const {
}
}
- if (global_trackers_.latency_ukm_reporter) {
- global_trackers_.latency_ukm_reporter->ReportCompositorLatencyUkm(
- report_types_, stage_history_, active_trackers_,
- *processed_blink_breakdown_, *processed_viz_breakdown_);
- }
-
for (size_t type = 0; type < report_types_.size(); ++type) {
if (!report_types_.test(type))
continue;
@@ -768,6 +802,14 @@ void CompositorFrameReporter::ReportCompositorLatencyHistograms() const {
UMA_HISTOGRAM_ENUMERATION("CompositorLatency.Type.JSAnimation",
report_type);
break;
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
+ UMA_HISTOGRAM_ENUMERATION(
+ "CompositorLatency.Type.SETCompositorAnimation", report_type);
+ break;
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
+ UMA_HISTOGRAM_ENUMERATION(
+ "CompositorLatency.Type.SETMainThreadAnimation", report_type);
+ break;
case FrameSequenceTrackerType::kCustom:
case FrameSequenceTrackerType::kMaxType:
NOTREACHED();
@@ -884,62 +926,84 @@ void CompositorFrameReporter::ReportCompositorLatencyHistogram(
}
}
-void CompositorFrameReporter::ReportEventLatencyHistograms() const {
+void CompositorFrameReporter::ReportEventLatencyMetrics() const {
const StageData& total_latency_stage = stage_history_.back();
DCHECK_EQ(StageType::kTotalLatency, total_latency_stage.stage_type);
- const std::string total_latency_stage_name =
- GetStageName(StageType::kTotalLatency);
- const std::string total_latency_histogram_name =
- "EventLatency." + total_latency_stage_name;
+ if (global_trackers_.latency_ukm_reporter) {
+ global_trackers_.latency_ukm_reporter->ReportEventLatencyUkm(
+ events_metrics_, stage_history_, *processed_blink_breakdown_,
+ *processed_viz_breakdown_);
+ }
+
+ std::vector<EventLatencyTracker::LatencyData> latencies;
for (const auto& event_metrics : events_metrics_) {
DCHECK(event_metrics);
- const std::string histogram_base_name =
- GetEventLatencyHistogramBaseName(*event_metrics);
- const int event_type_index = static_cast<int>(event_metrics->type());
auto* scroll_metrics = event_metrics->AsScroll();
auto* pinch_metrics = event_metrics->AsPinch();
- const int gesture_type_index =
- scroll_metrics
- ? static_cast<int>(scroll_metrics->scroll_type())
- : pinch_metrics ? static_cast<int>(pinch_metrics->pinch_type()) : 0;
- const int event_histogram_index =
- event_type_index * kEventLatencyGestureTypeCount + gesture_type_index;
const base::TimeTicks generated_timestamp =
event_metrics->GetDispatchStageTimestamp(
EventMetrics::DispatchStage::kGenerated);
- DCHECK_LT(generated_timestamp, total_latency_stage.end_time);
-
- // Report total latency up to presentation for the event.
+ // Generally, we expect that the event timestamp is strictly smaller than
+ // the end timestamp of the last stage (i.e. total latency is positive);
+ // however, at least in tests, it is possible that the timestamps are the
+ // same and total latency is zero.
+ DCHECK_LE(generated_timestamp, total_latency_stage.end_time);
const base::TimeDelta total_latency =
total_latency_stage.end_time - generated_timestamp;
- const std::string event_total_latency_histogram_name =
- base::StrCat({histogram_base_name, ".", total_latency_stage_name});
- // Note: There's a 1:1 mapping between `event_histogram_index` and
- // `event_total_latency_histogram_name` which allows the use of
- // `STATIC_HISTOGRAM_POINTER_GROUP()` to cache histogram objects.
- STATIC_HISTOGRAM_POINTER_GROUP(
- event_total_latency_histogram_name, event_histogram_index,
- kMaxEventLatencyHistogramIndex,
- AddTimeMicrosecondsGranularity(total_latency),
- base::Histogram::FactoryMicrosecondsTimeGet(
- event_total_latency_histogram_name, kEventLatencyHistogramMin,
- kEventLatencyHistogramMax, kEventLatencyHistogramBucketCount,
- base::HistogramBase::kUmaTargetedHistogramFlag));
- // Also, report total latency up to presentation for all event types in an
- // aggregate histogram.
- UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
- total_latency_histogram_name, total_latency, kEventLatencyHistogramMin,
- kEventLatencyHistogramMax, kEventLatencyHistogramBucketCount);
+ if (should_report_histograms_) {
+ const std::string histogram_base_name =
+ GetEventLatencyHistogramBaseName(*event_metrics);
+ const int event_type_index = static_cast<int>(event_metrics->type());
+ const int gesture_type_index =
+ scroll_metrics ? static_cast<int>(scroll_metrics->scroll_type())
+ : pinch_metrics ? static_cast<int>(pinch_metrics->pinch_type())
+ : 0;
+ const int event_histogram_index =
+ event_type_index * kEventLatencyGestureTypeCount + gesture_type_index;
+
+ const std::string total_latency_stage_name =
+ GetStageName(StageType::kTotalLatency);
+ const std::string event_total_latency_histogram_name =
+ base::StrCat({histogram_base_name, ".", total_latency_stage_name});
+ // Note: There's a 1:1 mapping between `event_histogram_index` and
+ // `event_total_latency_histogram_name` which allows the use of
+ // `STATIC_HISTOGRAM_POINTER_GROUP()` to cache histogram objects.
+ STATIC_HISTOGRAM_POINTER_GROUP(
+ event_total_latency_histogram_name, event_histogram_index,
+ kMaxEventLatencyHistogramIndex,
+ AddTimeMicrosecondsGranularity(total_latency),
+ base::Histogram::FactoryMicrosecondsTimeGet(
+ event_total_latency_histogram_name, kEventLatencyHistogramMin,
+ kEventLatencyHistogramMax, kEventLatencyHistogramBucketCount,
+ base::HistogramBase::kUmaTargetedHistogramFlag));
+
+ // Also, report total latency up to presentation for all event types in an
+ // aggregate histogram.
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "EventLatency." + total_latency_stage_name, total_latency,
+ kEventLatencyHistogramMin, kEventLatencyHistogramMax,
+ kEventLatencyHistogramBucketCount);
+ }
+
+ if (global_trackers_.event_latency_tracker) {
+ EventLatencyTracker::LatencyData& latency_data =
+ latencies.emplace_back(event_metrics->type(), total_latency);
+
+ if (scroll_metrics)
+ latency_data.input_type = scroll_metrics->scroll_type();
+ else if (pinch_metrics)
+ latency_data.input_type = pinch_metrics->pinch_type();
+ }
}
- if (global_trackers_.latency_ukm_reporter) {
- global_trackers_.latency_ukm_reporter->ReportEventLatencyUkm(
- events_metrics_, stage_history_, *processed_blink_breakdown_,
- *processed_viz_breakdown_);
+ if (!latencies.empty()) {
+ DCHECK(global_trackers_.event_latency_tracker);
+ global_trackers_.event_latency_tracker->ReportEventLatency(
+ std::move(latencies));
}
}
@@ -1049,6 +1113,9 @@ void CompositorFrameReporter::ReportCompositorLatencyTraceEvents(
case static_cast<int>(BlinkBreakdown::kLayoutUpdate):
reporter->set_layout_update_us(latency);
break;
+ case static_cast<int>(BlinkBreakdown::kAccessibility):
+ reporter->set_accessibility_update_us(latency);
+ break;
case static_cast<int>(BlinkBreakdown::kPrepaint):
reporter->set_prepaint_us(latency);
break;
@@ -1129,6 +1196,11 @@ void CompositorFrameReporter::AdoptReporter(
// update, then |this| should not have any such dependents.
DCHECK(!partial_update_decider_);
DCHECK(!partial_update_dependents_.empty());
+
+ // The adoptee tracks a partial update. If it has metrics that depend on the
+ // main thread update, move them into |this| reporter.
+ AddEventsMetrics(reporter->TakeMainBlockedEventsMetrics());
+
owned_partial_update_dependents_.push(std::move(reporter));
DiscardOldPartialUpdateReporters();
}
diff --git a/chromium/cc/metrics/compositor_frame_reporter.h b/chromium/cc/metrics/compositor_frame_reporter.h
index f903e3d2155..ad0b1084a34 100644
--- a/chromium/cc/metrics/compositor_frame_reporter.h
+++ b/chromium/cc/metrics/compositor_frame_reporter.h
@@ -31,14 +31,16 @@ struct FrameTimingDetails;
}
namespace cc {
-class FrameSequenceTrackerCollection;
class DroppedFrameCounter;
+class EventLatencyTracker;
+class FrameSequenceTrackerCollection;
class LatencyUkmReporter;
struct GlobalMetricsTrackers {
- DroppedFrameCounter* dropped_frame_counter = nullptr;
- LatencyUkmReporter* latency_ukm_reporter = nullptr;
- FrameSequenceTrackerCollection* frame_sequence_trackers = nullptr;
+ raw_ptr<DroppedFrameCounter> dropped_frame_counter = nullptr;
+ raw_ptr<LatencyUkmReporter> latency_ukm_reporter = nullptr;
+ raw_ptr<FrameSequenceTrackerCollection> frame_sequence_trackers = nullptr;
+ raw_ptr<EventLatencyTracker> event_latency_tracker = nullptr;
};
// This is used for tracing and reporting the duration of pipeline stages within
@@ -121,12 +123,13 @@ class CC_EXPORT CompositorFrameReporter {
kAnimate = 1,
kStyleUpdate = 2,
kLayoutUpdate = 3,
- kPrepaint = 4,
- kCompositingInputs = 5,
- kPaint = 6,
- kCompositeCommit = 7,
- kUpdateLayers = 8,
- kBeginMainSentToStarted = 9,
+ kAccessibility = 4,
+ kPrepaint = 5,
+ kCompositingInputs = 6,
+ kPaint = 7,
+ kCompositeCommit = 8,
+ kUpdateLayers = 9,
+ kBeginMainSentToStarted = 10,
kBreakdownCount
};
@@ -159,7 +162,7 @@ class CC_EXPORT CompositorFrameReporter {
base::TimeDelta GetLatency() const;
private:
- const ProcessedBlinkBreakdown* owner_;
+ raw_ptr<const ProcessedBlinkBreakdown> owner_;
size_t index_ = 0;
};
@@ -197,7 +200,7 @@ class CC_EXPORT CompositorFrameReporter {
base::TimeDelta GetDuration() const;
private:
- const ProcessedVizBreakdown* owner_;
+ raw_ptr<const ProcessedVizBreakdown> owner_;
const bool skip_swap_start_to_swap_end_;
size_t index_ = 0;
@@ -228,7 +231,7 @@ class CC_EXPORT CompositorFrameReporter {
CompositorFrameReporter(const ActiveTrackers& active_trackers,
const viz::BeginFrameArgs& args,
- bool should_report_metrics,
+ bool should_report_histograms,
SmoothThread smooth_thread,
FrameInfo::SmoothEffectDrivingThread scrolling_thread,
int layer_tree_host_id,
@@ -269,6 +272,8 @@ class CC_EXPORT CompositorFrameReporter {
void SetVizBreakdown(const viz::FrameTimingDetails& viz_breakdown);
void AddEventsMetrics(EventMetrics::List events_metrics);
+
+ // Erase and return all EventMetrics objects from our list.
EventMetrics::List TakeEventsMetrics();
size_t stage_history_size_for_testing() const {
@@ -350,7 +355,7 @@ class CC_EXPORT CompositorFrameReporter {
void TerminateReporter();
void EndCurrentStage(base::TimeTicks end_time);
- void ReportCompositorLatencyHistograms() const;
+ void ReportCompositorLatencyMetrics() const;
void ReportStageHistogramWithBreakdown(
const StageData& stage,
FrameSequenceTrackerType frame_sequence_tracker_type =
@@ -366,7 +371,7 @@ class CC_EXPORT CompositorFrameReporter {
absl::optional<BlinkBreakdown> blink_breakdown,
base::TimeDelta time_delta) const;
- void ReportEventLatencyHistograms() const;
+ void ReportEventLatencyMetrics() const;
void ReportCompositorLatencyTraceEvents(const FrameInfo& info) const;
void ReportEventLatencyTraceEvents() const;
@@ -389,7 +394,13 @@ class CC_EXPORT CompositorFrameReporter {
base::WeakPtr<CompositorFrameReporter> GetWeakPtr();
- const bool should_report_metrics_;
+ // Erase and return only the EventMetrics objects which depend on main thread
+ // updates (see comments on EventMetrics::requires_main_thread_update_).
+ EventMetrics::List TakeMainBlockedEventsMetrics();
+
+ // Whether UMA histograms should be reported or not.
+ const bool should_report_histograms_;
+
const viz::BeginFrameArgs args_;
StageData current_stage_;
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.cc b/chromium/cc/metrics/compositor_frame_reporting_controller.cc
index fbf02b198a3..c40ffcee3b5 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller.cc
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller.cc
@@ -26,12 +26,17 @@ constexpr char kTraceCategory[] = "cc,benchmark";
} // namespace
CompositorFrameReportingController::CompositorFrameReportingController(
- bool should_report_metrics,
+ bool should_report_histograms,
+ bool should_report_ukm,
int layer_tree_host_id)
- : should_report_metrics_(should_report_metrics),
+ : should_report_histograms_(should_report_histograms),
layer_tree_host_id_(layer_tree_host_id),
latency_ukm_reporter_(std::make_unique<LatencyUkmReporter>()) {
- global_trackers_.latency_ukm_reporter = latency_ukm_reporter_.get();
+ if (should_report_ukm) {
+ // UKM metrics should be reported if and only if `latency_ukm_reporter` is
+ // set on `global_trackers_`.
+ global_trackers_.latency_ukm_reporter = latency_ukm_reporter_.get();
+ }
}
CompositorFrameReportingController::~CompositorFrameReportingController() {
@@ -107,7 +112,7 @@ void CompositorFrameReportingController::WillBeginImplFrame(
}
}
auto reporter = std::make_unique<CompositorFrameReporter>(
- active_trackers_, args, should_report_metrics_, GetSmoothThread(),
+ active_trackers_, args, should_report_histograms_, GetSmoothThread(),
scrolling_thread_, layer_tree_host_id_, global_trackers_);
reporter->set_tick_clock(tick_clock_);
reporter->StartStage(StageType::kBeginImplFrameToSendBeginMainFrame,
@@ -145,7 +150,7 @@ void CompositorFrameReportingController::WillBeginMainFrame(
smooth_thread = last_started_compositor_frame_.smooth_thread;
}
auto reporter = std::make_unique<CompositorFrameReporter>(
- active_trackers, args, should_report_metrics_, smooth_thread,
+ active_trackers, args, should_report_histograms_, smooth_thread,
scrolling_thread, layer_tree_host_id_, global_trackers_);
reporter->set_tick_clock(tick_clock_);
reporter->StartStage(StageType::kSendBeginMainFrameToCommit, Now());
@@ -729,7 +734,7 @@ void CompositorFrameReportingController::CreateReportersForDroppedFrames(
// start time, but they were skipped and history of scrolling thread might
// change in the diff of start time and report time.
auto reporter = std::make_unique<CompositorFrameReporter>(
- active_trackers_, args, should_report_metrics_,
+ active_trackers_, args, should_report_histograms_,
GetSmoothThreadAtTime(timestamp),
FrameInfo::SmoothEffectDrivingThread::kUnknown, layer_tree_host_id_,
global_trackers_);
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.h b/chromium/cc/metrics/compositor_frame_reporting_controller.h
index ee9cfff939a..3d1640c395c 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller.h
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller.h
@@ -24,6 +24,7 @@ struct FrameTimingDetails;
namespace cc {
class DroppedFrameCounter;
+class EventLatencyTracker;
class UkmManager;
struct BeginMainFrameMetrics;
struct FrameInfo;
@@ -45,7 +46,8 @@ class CC_EXPORT CompositorFrameReportingController {
kNumPipelineStages
};
- CompositorFrameReportingController(bool should_report_metrics,
+ CompositorFrameReportingController(bool should_report_histograms,
+ bool should_report_ukm,
int layer_tree_host_id);
virtual ~CompositorFrameReportingController();
@@ -108,6 +110,10 @@ class CC_EXPORT CompositorFrameReportingController {
global_trackers_.frame_sequence_trackers = frame_sequence_trackers;
}
+ void set_event_latency_tracker(EventLatencyTracker* event_latency_tracker) {
+ global_trackers_.event_latency_tracker = event_latency_tracker;
+ }
+
void BeginMainFrameStarted(base::TimeTicks begin_main_frame_start_time) {
begin_main_frame_start_time_ = begin_main_frame_start_time;
}
@@ -166,7 +172,7 @@ class CC_EXPORT CompositorFrameReportingController {
void AddSortedFrame(const viz::BeginFrameArgs& args,
const FrameInfo& frame_info);
- const bool should_report_metrics_;
+ const bool should_report_histograms_;
const int layer_tree_host_id_;
viz::BeginFrameId last_submitted_frame_id_;
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
index 524f144dbac..c831d790240 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
@@ -34,7 +34,8 @@ class TestCompositorFrameReportingController
: public CompositorFrameReportingController {
public:
TestCompositorFrameReportingController()
- : CompositorFrameReportingController(/*should_report_metrics=*/true,
+ : CompositorFrameReportingController(/*should_report_histograms=*/true,
+ /*should_report_ukm=*/false,
/*layer_tree_host_id=*/1) {}
TestCompositorFrameReportingController(
@@ -1332,6 +1333,77 @@ TEST_F(CompositorFrameReportingControllerTest,
}
}
+TEST_F(CompositorFrameReportingControllerTest,
+ EventLatencyMainRepaintedScroll) {
+ base::HistogramTester histogram_tester;
+
+ // Set up two EventMetrics objects.
+ std::unique_ptr<EventMetrics> metrics_1 = CreateScrollUpdateEventMetrics(
+ false /* is_inertial */,
+ ScrollUpdateEventMetrics::ScrollUpdateType::kStarted);
+ metrics_1->set_requires_main_thread_update();
+ base::TimeTicks start_time_1 = metrics_1->GetDispatchStageTimestamp(
+ EventMetrics::DispatchStage::kGenerated);
+
+ // The second EventMetrics does not have set_requires_main_thread_update().
+ // (It's not very realistic for the same scroll gesture to produce two events
+ // with differing values for this bit, but let's test both conditions here.)
+ std::unique_ptr<EventMetrics> metrics_2 = CreateScrollUpdateEventMetrics(
+ false /* is_inertial */,
+ ScrollUpdateEventMetrics::ScrollUpdateType::kContinued);
+ base::TimeTicks start_time_2 = metrics_2->GetDispatchStageTimestamp(
+ EventMetrics::DispatchStage::kGenerated);
+
+ // Simulate a frame getting stuck in the main thread.
+ SimulateBeginImplFrame();
+ SimulateBeginMainFrame();
+ reporting_controller_.OnFinishImplFrame(current_id_);
+
+ // Submit a partial update with our events from the compositor thread.
+ EventMetrics::List metrics_list;
+ metrics_list.push_back(std::move(metrics_1));
+ metrics_list.push_back(std::move(metrics_2));
+ reporting_controller_.DidSubmitCompositorFrame(
+ *current_token_, AdvanceNowByMs(10), current_id_, {},
+ {{}, std::move(metrics_list)},
+ /*has_missing_content=*/false);
+
+ // Present the partial update.
+ viz::FrameTimingDetails details_1 = {};
+ details_1.presentation_feedback.timestamp = AdvanceNowByMs(10);
+ reporting_controller_.DidPresentCompositorFrame(*current_token_, details_1);
+
+ // Let the main thread finish its work.
+ SimulateCommit(nullptr);
+ SimulateActivate();
+
+ // Submit the final update.
+ SimulateBeginImplFrame();
+ reporting_controller_.OnFinishImplFrame(current_id_);
+ SimulateSubmitCompositorFrame({});
+
+ // Present the final update.
+ viz::FrameTimingDetails details_2 = {};
+ details_2.presentation_feedback.timestamp = AdvanceNowByMs(10);
+ reporting_controller_.DidPresentCompositorFrame(*current_token_, details_2);
+
+ // metrics_1 has requires_main_thread_update(), so its latency is based on the
+ // final-update presentation (details_2).
+ base::TimeDelta expected_latency_1 =
+ details_2.presentation_feedback.timestamp - start_time_1;
+ histogram_tester.ExpectBucketCount(
+ "EventLatency.FirstGestureScrollUpdate.Wheel.TotalLatency",
+ expected_latency_1.InMicroseconds(), 1);
+
+ // metrics_2 did NOT have requires_main_thread_update(), so its latency is
+ // based on the partial-update presentation (details_1).
+ base::TimeDelta expected_latency_2 =
+ details_1.presentation_feedback.timestamp - start_time_2;
+ histogram_tester.ExpectBucketCount(
+ "EventLatency.GestureScrollUpdate.Wheel.TotalLatency",
+ expected_latency_2.InMicroseconds(), 1);
+}
+
// Tests that EventLatency total latency histograms are reported properly for
// pinch events when a frame is presented to the user.
TEST_F(CompositorFrameReportingControllerTest,
diff --git a/chromium/cc/metrics/compositor_timing_history.cc b/chromium/cc/metrics/compositor_timing_history.cc
index 1eb6fe1645c..a9c16c24319 100644
--- a/chromium/cc/metrics/compositor_timing_history.cc
+++ b/chromium/cc/metrics/compositor_timing_history.cc
@@ -442,7 +442,6 @@ CompositorTimingHistory::CompositorTimingHistory(
: using_synchronous_renderer_compositor_(
using_synchronous_renderer_compositor),
enabled_(false),
- did_send_begin_main_frame_(false),
compositor_drawing_continuously_(false),
begin_main_frame_queue_duration_history_(kDurationHistorySize),
begin_main_frame_queue_duration_critical_history_(kDurationHistorySize),
@@ -466,7 +465,6 @@ CompositorTimingHistory::CompositorTimingHistory(
bmf_queue_to_activate_critical_history_(kDurationHistorySize),
bmf_queue_to_activate_critical_percentile_(
BeginMainFrameQueueToActivateCriticalPercentile()),
- begin_main_frame_on_critical_path_(false),
uma_reporter_(CreateUMAReporter(uma_category)),
rendering_stats_instrumentation_(rendering_stats_instrumentation) {}
@@ -598,8 +596,6 @@ void CompositorTimingHistory::WillBeginImplFrame(
if (frame_type == viz::BeginFrameArgs::NORMAL)
uma_reporter_->AddBeginImplFrameLatency(now - frame_time);
-
- did_send_begin_main_frame_ = false;
}
void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) {
@@ -617,8 +613,6 @@ void CompositorTimingHistory::WillBeginMainFrame(
begin_main_frame_on_critical_path_ = args.on_critical_path;
begin_main_frame_sent_time_ = Now();
-
- did_send_begin_main_frame_ = true;
}
void CompositorTimingHistory::BeginMainFrameStarted(
@@ -635,18 +629,20 @@ void CompositorTimingHistory::BeginMainFrameAborted() {
void CompositorTimingHistory::NotifyReadyToCommit() {
DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
+ base::TimeTicks begin_main_frame_end_time = Now();
+ base::TimeDelta begin_main_frame_queue_duration =
+ begin_main_frame_start_time_ - begin_main_frame_sent_time_;
begin_main_frame_start_to_ready_to_commit_duration_history_.InsertSample(
- Now() - begin_main_frame_start_time_);
+ begin_main_frame_end_time - begin_main_frame_start_time_);
if (duration_estimates_enabled_) {
- bmf_start_to_activate_duration_ = Now() - begin_main_frame_start_time_;
if (begin_main_frame_on_critical_path_) {
bmf_start_to_ready_to_commit_critical_history_.InsertSample(
- (Now() - begin_main_frame_start_time_) +
- begin_main_frame_queue_duration_);
+ (begin_main_frame_end_time - begin_main_frame_start_time_) +
+ begin_main_frame_queue_duration);
} else {
bmf_start_to_ready_to_commit_not_critical_history_.InsertSample(
- (Now() - begin_main_frame_start_time_) +
- begin_main_frame_queue_duration_);
+ (begin_main_frame_end_time - begin_main_frame_start_time_) +
+ begin_main_frame_queue_duration);
}
}
}
@@ -660,17 +656,18 @@ void CompositorTimingHistory::DidCommit() {
DCHECK_EQ(pending_tree_creation_time_, base::TimeTicks());
DCHECK_NE(commit_start_time_, base::TimeTicks());
- base::TimeTicks begin_main_frame_end_time = Now();
- DidBeginMainFrame(begin_main_frame_end_time);
- commit_duration_history_.InsertSample(begin_main_frame_end_time -
- commit_start_time_);
-
+ base::TimeTicks commit_end_time = Now();
if (enabled_ && duration_estimates_enabled_) {
- bmf_start_to_activate_duration_ +=
- begin_main_frame_end_time - commit_start_time_;
+ pending_tree_on_critical_path_ = begin_main_frame_on_critical_path_;
+ bmf_start_to_ready_to_activate_duration_ =
+ commit_end_time - begin_main_frame_start_time_;
}
+ DidBeginMainFrame(commit_end_time);
+ commit_duration_history_.InsertSample(commit_end_time - commit_start_time_);
+
pending_tree_is_impl_side_ = false;
- pending_tree_creation_time_ = begin_main_frame_end_time;
+ pending_tree_creation_time_ = commit_end_time;
+ pending_tree_bmf_queue_duration_ = begin_main_frame_queue_duration_;
}
void CompositorTimingHistory::DidBeginMainFrame(
@@ -718,6 +715,8 @@ void CompositorTimingHistory::WillInvalidateOnImplSide() {
DCHECK_EQ(pending_tree_creation_time_, base::TimeTicks());
pending_tree_is_impl_side_ = true;
+ pending_tree_on_critical_path_ = false;
+ pending_tree_bmf_queue_duration_ = base::TimeDelta();
pending_tree_creation_time_ = base::TimeTicks::Now();
}
@@ -765,7 +764,7 @@ void CompositorTimingHistory::ReadyToActivate() {
commit_to_ready_to_activate_duration_history_.InsertSample(
time_since_commit);
if (duration_estimates_enabled_)
- bmf_start_to_activate_duration_ += time_since_commit;
+ bmf_start_to_ready_to_activate_duration_ += time_since_commit;
}
}
}
@@ -777,25 +776,30 @@ void CompositorTimingHistory::WillActivate() {
pending_tree_is_impl_side_ = false;
pending_tree_creation_time_ = base::TimeTicks();
- pending_tree_ready_to_activate_time_ = base::TimeTicks();
}
void CompositorTimingHistory::DidActivate() {
DCHECK_NE(base::TimeTicks(), activate_start_time_);
- base::TimeDelta activate_duration = Now() - activate_start_time_;
+ base::TimeTicks activate_end_time = Now();
+ base::TimeDelta activate_duration = activate_end_time - activate_start_time_;
if (enabled_) {
activate_duration_history_.InsertSample(activate_duration);
if (duration_estimates_enabled_) {
- if (begin_main_frame_on_critical_path_) {
+ if (pending_tree_on_critical_path_) {
+ base::TimeDelta time_since_ready_to_activate =
+ activate_end_time - pending_tree_ready_to_activate_time_;
+ DCHECK_NE(pending_tree_bmf_queue_duration_, base::TimeDelta());
bmf_queue_to_activate_critical_history_.InsertSample(
- bmf_start_to_activate_duration_ + activate_duration +
- begin_main_frame_queue_duration_);
+ bmf_start_to_ready_to_activate_duration_ +
+ time_since_ready_to_activate + pending_tree_bmf_queue_duration_);
}
+ bmf_start_to_ready_to_activate_duration_ = base::TimeDelta();
}
}
+ pending_tree_ready_to_activate_time_ = base::TimeTicks();
activate_start_time_ = base::TimeTicks();
}
diff --git a/chromium/cc/metrics/compositor_timing_history.h b/chromium/cc/metrics/compositor_timing_history.h
index d8ad8df66a1..83bd3475a2e 100644
--- a/chromium/cc/metrics/compositor_timing_history.h
+++ b/chromium/cc/metrics/compositor_timing_history.h
@@ -112,7 +112,6 @@ class CC_EXPORT CompositorTimingHistory {
bool enabled_;
// Used to calculate frame rates of Main and Impl threads.
- bool did_send_begin_main_frame_;
bool compositor_drawing_continuously_;
base::TimeTicks new_active_tree_draw_end_time_prev_;
base::TimeTicks draw_end_time_prev_;
@@ -142,10 +141,18 @@ class CC_EXPORT CompositorTimingHistory {
RollingTimeDeltaHistory bmf_queue_to_activate_critical_history_;
double bmf_queue_to_activate_critical_percentile_;
+ // The time between when BMF was posted to the main thread task queue, and the
+ // timestamp taken on the main thread when the BMF started running.
base::TimeDelta begin_main_frame_queue_duration_;
- base::TimeDelta bmf_start_to_activate_duration_;
-
- bool begin_main_frame_on_critical_path_;
+ // The value of begin_main_frame_queue_duration_ that was measured for the
+ // pending tree.
+ base::TimeDelta pending_tree_bmf_queue_duration_;
+ // The time between when BMF was posted to the main thread task queue, and
+ // when the result of the BMF finished activation.
+ base::TimeDelta bmf_start_to_ready_to_activate_duration_;
+
+ bool begin_main_frame_on_critical_path_ = false;
+ bool pending_tree_on_critical_path_ = false;
base::TimeTicks begin_main_frame_sent_time_;
base::TimeTicks begin_main_frame_start_time_;
base::TimeTicks commit_start_time_;
diff --git a/chromium/cc/metrics/compositor_timing_history_unittest.cc b/chromium/cc/metrics/compositor_timing_history_unittest.cc
index ee60812fc35..05b8d895464 100644
--- a/chromium/cc/metrics/compositor_timing_history_unittest.cc
+++ b/chromium/cc/metrics/compositor_timing_history_unittest.cc
@@ -6,7 +6,9 @@
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
+#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
+#include "cc/base/features.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/metrics/dropped_frame_counter.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,6 +29,19 @@ class TestCompositorTimingHistory : public CompositorTimingHistory {
TestCompositorTimingHistory& operator=(const TestCompositorTimingHistory&) =
delete;
+ const RollingTimeDeltaHistory& bmf_start_to_ready_to_commit_critical_history()
+ const {
+ return bmf_start_to_ready_to_commit_critical_history_;
+ }
+ const RollingTimeDeltaHistory&
+ bmf_start_to_ready_to_commit_not_critical_history() const {
+ return bmf_start_to_ready_to_commit_not_critical_history_;
+ }
+ const RollingTimeDeltaHistory& bmf_queue_to_activate_critical_history()
+ const {
+ return bmf_queue_to_activate_critical_history_;
+ }
+
protected:
base::TimeTicks Now() const override;
@@ -36,7 +51,8 @@ class TestCompositorTimingHistory : public CompositorTimingHistory {
class CompositorTimingHistoryTest : public testing::Test {
public:
CompositorTimingHistoryTest()
- : rendering_stats_(RenderingStatsInstrumentation::Create()),
+ : feature_list(features::kDurationEstimatesInCompositorTimingHistory),
+ rendering_stats_(RenderingStatsInstrumentation::Create()),
timing_history_(this, rendering_stats_.get()) {
AdvanceNowBy(base::Milliseconds(1));
timing_history_.SetRecordingEnabled(true);
@@ -47,6 +63,7 @@ class CompositorTimingHistoryTest : public testing::Test {
base::TimeTicks Now() { return now_; }
protected:
+ base::test::ScopedFeatureList feature_list;
std::unique_ptr<RenderingStatsInstrumentation> rendering_stats_;
TestCompositorTimingHistory timing_history_;
base::TimeTicks now_;
@@ -276,5 +293,128 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
}
+TEST_F(CompositorTimingHistoryTest, BeginMainFrameToActivateDuration) {
+ viz::BeginFrameArgs args_ = GetFakeBeginFrameArg(true);
+ timing_history_.WillBeginMainFrame(args_);
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.BeginMainFrameStarted(Now());
+ AdvanceNowBy(base::Milliseconds(2));
+ timing_history_.NotifyReadyToCommit();
+ AdvanceNowBy(base::Milliseconds(3));
+ timing_history_.WillCommit();
+ AdvanceNowBy(base::Milliseconds(4));
+ timing_history_.DidCommit();
+ AdvanceNowBy(base::Milliseconds(5));
+ timing_history_.ReadyToActivate();
+ AdvanceNowBy(base::Milliseconds(6));
+ timing_history_.WillActivate();
+ AdvanceNowBy(base::Milliseconds(7));
+ timing_history_.DidActivate();
+ EXPECT_EQ(
+ 1u,
+ timing_history_.bmf_queue_to_activate_critical_history().sample_count());
+ EXPECT_EQ(
+ base::Milliseconds(1 + 2 + 3 + 4 + 5 + 6 + 7),
+ timing_history_.bmf_queue_to_activate_critical_history().Percentile(0.));
+}
+
+TEST_F(CompositorTimingHistoryTest, OnCriticalPath) {
+ viz::BeginFrameArgs bmf_args = GetFakeBeginFrameArg(true);
+ timing_history_.WillBeginMainFrame(bmf_args);
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.BeginMainFrameStarted(Now());
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.NotifyReadyToCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.WillCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.DidCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.ReadyToActivate();
+ AdvanceNowBy(base::Milliseconds(1));
+
+ // The previous frame should still be treated as on_critical_path
+ bmf_args = GetFakeBeginFrameArg(false);
+ timing_history_.WillBeginMainFrame(bmf_args);
+
+ timing_history_.WillActivate();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.DidActivate();
+
+ EXPECT_EQ(1u, timing_history_.bmf_start_to_ready_to_commit_critical_history()
+ .sample_count());
+ EXPECT_EQ(base::Milliseconds(2),
+ timing_history_.bmf_start_to_ready_to_commit_critical_history()
+ .Percentile(0.));
+ EXPECT_EQ(0u,
+ timing_history_.bmf_start_to_ready_to_commit_not_critical_history()
+ .sample_count());
+ EXPECT_EQ(
+ 1u,
+ timing_history_.bmf_queue_to_activate_critical_history().sample_count());
+ EXPECT_EQ(
+ base::Milliseconds(7),
+ timing_history_.bmf_queue_to_activate_critical_history().Percentile(0.));
+
+ timing_history_.BeginMainFrameStarted(Now());
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.NotifyReadyToCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.WillCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.DidCommit();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.ReadyToActivate();
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.WillActivate();
+ AdvanceNowBy(base::Milliseconds(1));
+
+ // The previous frame should still be treated as not on_critical_path
+ bmf_args = GetFakeBeginFrameArg(true);
+ timing_history_.WillBeginMainFrame(bmf_args);
+ timing_history_.DidActivate();
+
+ EXPECT_EQ(1u, timing_history_.bmf_start_to_ready_to_commit_critical_history()
+ .sample_count());
+ EXPECT_EQ(1u,
+ timing_history_.bmf_start_to_ready_to_commit_not_critical_history()
+ .sample_count());
+ EXPECT_EQ(
+ 1u,
+ timing_history_.bmf_queue_to_activate_critical_history().sample_count());
+}
+
+TEST_F(CompositorTimingHistoryTest, BeginMainFrameQueueDuration) {
+ viz::BeginFrameArgs args_ = GetFakeBeginFrameArg(true);
+ timing_history_.WillBeginMainFrame(args_);
+ AdvanceNowBy(base::Milliseconds(1));
+ timing_history_.BeginMainFrameStarted(Now());
+ AdvanceNowBy(base::Milliseconds(2));
+ timing_history_.NotifyReadyToCommit();
+ AdvanceNowBy(base::Milliseconds(3));
+ timing_history_.WillCommit();
+ AdvanceNowBy(base::Milliseconds(4));
+ timing_history_.DidCommit();
+ AdvanceNowBy(base::Milliseconds(5));
+ timing_history_.ReadyToActivate();
+ AdvanceNowBy(base::Milliseconds(6));
+ timing_history_.WillBeginMainFrame(args_);
+ AdvanceNowBy(base::Milliseconds(7));
+ timing_history_.BeginMainFrameStarted(Now());
+ AdvanceNowBy(base::Milliseconds(8));
+ timing_history_.BeginMainFrameAborted();
+ AdvanceNowBy(base::Milliseconds(9));
+ timing_history_.WillActivate();
+ AdvanceNowBy(base::Milliseconds(10));
+ timing_history_.DidActivate();
+ EXPECT_EQ(
+ 1u,
+ timing_history_.bmf_queue_to_activate_critical_history().sample_count());
+ // The bmf queueing duration should be 1ms, not the 7ms for the aborted frame.
+ EXPECT_EQ(
+ base::Milliseconds(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10),
+ timing_history_.bmf_queue_to_activate_critical_history().Percentile(0.));
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/metrics/custom_metrics_recorder.cc b/chromium/cc/metrics/custom_metrics_recorder.cc
new file mode 100644
index 00000000000..5b25f11401a
--- /dev/null
+++ b/chromium/cc/metrics/custom_metrics_recorder.cc
@@ -0,0 +1,31 @@
+// Copyright 2020 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/custom_metrics_recorder.h"
+
+#include "base/check_op.h"
+
+namespace cc {
+namespace {
+
+CustomMetricRecorder* g_instance = nullptr;
+
+} // namespace
+
+// static
+CustomMetricRecorder* CustomMetricRecorder::Get() {
+ return g_instance;
+}
+
+CustomMetricRecorder::CustomMetricRecorder() {
+ DCHECK_EQ(nullptr, g_instance);
+ g_instance = this;
+}
+
+CustomMetricRecorder::~CustomMetricRecorder() {
+ DCHECK_EQ(this, g_instance);
+ g_instance = nullptr;
+}
+
+} // namespace cc
diff --git a/chromium/cc/metrics/custom_metrics_recorder.h b/chromium/cc/metrics/custom_metrics_recorder.h
new file mode 100644
index 00000000000..fa4f8ad36a6
--- /dev/null
+++ b/chromium/cc/metrics/custom_metrics_recorder.h
@@ -0,0 +1,27 @@
+// Copyright 2022 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_CUSTOM_METRICS_RECORDER_H_
+#define CC_METRICS_CUSTOM_METRICS_RECORDER_H_
+
+#include "cc/cc_export.h"
+
+namespace cc {
+
+// Customize cc metric recording. E.g. reporting metrics under different names.
+class CC_EXPORT CustomMetricRecorder {
+ public:
+ static CustomMetricRecorder* Get();
+
+ // Invoked to report "PercentDroppedFrames_1sWindow".
+ virtual void ReportPercentDroppedFramesInOneSecoundWindow(double percent) = 0;
+
+ protected:
+ CustomMetricRecorder();
+ virtual ~CustomMetricRecorder();
+};
+
+} // namespace cc
+
+#endif // CC_METRICS_CUSTOM_METRICS_RECORDER_H_
diff --git a/chromium/cc/metrics/dropped_frame_counter.cc b/chromium/cc/metrics/dropped_frame_counter.cc
index e7fd9cffec1..3ad8364c7a0 100644
--- a/chromium/cc/metrics/dropped_frame_counter.cc
+++ b/chromium/cc/metrics/dropped_frame_counter.cc
@@ -15,6 +15,7 @@
#include "base/trace_event/trace_event.h"
#include "build/chromeos_buildflags.h"
#include "cc/base/features.h"
+#include "cc/metrics/custom_metrics_recorder.h"
#include "cc/metrics/frame_sorter.h"
#include "cc/metrics/total_frame_counter.h"
#include "cc/metrics/ukm_smoothness_data.h"
@@ -397,10 +398,13 @@ void DroppedFrameCounter::ReportFrames() {
void DroppedFrameCounter::ReportFramesForUI() {
DCHECK(report_for_ui_);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- UMA_HISTOGRAM_PERCENTAGE("Ash.Smoothness.PercentDroppedFrames_1sWindow",
- sliding_window_current_percent_dropped_);
-#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+
+ auto* recorder = CustomMetricRecorder::Get();
+ if (!recorder)
+ return;
+
+ recorder->ReportPercentDroppedFramesInOneSecoundWindow(
+ sliding_window_current_percent_dropped_);
}
double DroppedFrameCounter::GetMostRecentAverageSmoothness() const {
diff --git a/chromium/cc/metrics/dropped_frame_counter_unittest.cc b/chromium/cc/metrics/dropped_frame_counter_unittest.cc
index cc48999db8e..92167651cc8 100644
--- a/chromium/cc/metrics/dropped_frame_counter_unittest.cc
+++ b/chromium/cc/metrics/dropped_frame_counter_unittest.cc
@@ -9,10 +9,10 @@
#include "base/memory/raw_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
-#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "build/chromeos_buildflags.h"
#include "cc/animation/animation_host.h"
+#include "cc/metrics/custom_metrics_recorder.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_frame_info.h"
#include "cc/test/fake_picture_layer.h"
@@ -29,6 +29,31 @@ FrameInfo CreateStubFrameInfo(bool is_dropped) {
: FrameInfo::FrameFinalState::kPresentedAll);
}
+class TestCustomMetricsRecorder : public CustomMetricRecorder {
+ public:
+ TestCustomMetricsRecorder() = default;
+ ~TestCustomMetricsRecorder() override = default;
+
+ // CustomMetricRecorder:
+ void ReportPercentDroppedFramesInOneSecoundWindow(
+ double percentage) override {
+ ++percent_dropped_frames_count_;
+ last_percent_dropped_frames_ = percentage;
+ }
+
+ int percent_dropped_frames_count() const {
+ return percent_dropped_frames_count_;
+ }
+
+ double last_percent_dropped_frames() const {
+ return last_percent_dropped_frames_;
+ }
+
+ private:
+ int percent_dropped_frames_count_ = 0;
+ double last_percent_dropped_frames_ = 0;
+};
+
class DroppedFrameCounterTestBase : public LayerTreeTest {
public:
DroppedFrameCounterTestBase() = default;
@@ -917,7 +942,6 @@ TEST_F(DroppedFrameCounterTest, WorstSmoothnessTiming) {
EXPECT_FLOAT_EQ(MaxPercentDroppedFrameAfter5Sec(), 100);
}
-#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(DroppedFrameCounterTest, ReportForUI) {
constexpr auto kInterval = base::Milliseconds(10);
constexpr size_t kFps = base::Seconds(1) / kInterval;
@@ -927,17 +951,15 @@ TEST_F(DroppedFrameCounterTest, ReportForUI) {
SetInterval(kInterval);
dropped_frame_counter_.EnableReporForUI();
- base::HistogramTester histogram_tester;
+ TestCustomMetricsRecorder recorder;
// 4 seconds with 20% dropped frames.
SimulateFrameSequence({false, false, false, false, true}, (kFps / 5) * 4);
// Recorded more than 1 samples of 20% dropped frame percentage.
- EXPECT_GE(histogram_tester.GetBucketCount(
- "Ash.Smoothness.PercentDroppedFrames_1sWindow", 20),
- 1);
+ EXPECT_GE(recorder.percent_dropped_frames_count(), 1);
+ EXPECT_EQ(recorder.last_percent_dropped_frames(), 20.0f);
}
-#endif // BUILDFLAG(IS_CHROMEOS_ASH)
} // namespace
} // namespace cc
diff --git a/chromium/cc/metrics/event_latency_tracing_recorder.cc b/chromium/cc/metrics/event_latency_tracing_recorder.cc
index 96586cf52d0..57dce582e1f 100644
--- a/chromium/cc/metrics/event_latency_tracing_recorder.cc
+++ b/chromium/cc/metrics/event_latency_tracing_recorder.cc
@@ -35,7 +35,7 @@ constexpr const char* GetDispatchBreakdownName(
return "RendererCompositorToMain";
default:
NOTREACHED();
- return nullptr;
+ return "";
}
case EventMetrics::DispatchStage::kRendererCompositorStarted:
DCHECK_EQ(end_stage,
@@ -49,7 +49,7 @@ constexpr const char* GetDispatchBreakdownName(
return "RendererMainProcessing";
case EventMetrics::DispatchStage::kRendererMainFinished:
NOTREACHED();
- return nullptr;
+ return "";
}
}
@@ -80,7 +80,7 @@ constexpr const char* GetDispatchToCompositorBreakdownName(
return "RendererCompositorFinishedToSubmitCompositorFrame";
default:
NOTREACHED();
- return nullptr;
+ return "";
}
case EventMetrics::DispatchStage::kRendererMainFinished:
switch (compositor_stage) {
@@ -103,11 +103,11 @@ constexpr const char* GetDispatchToCompositorBreakdownName(
return "RendererMainFinishedToSubmitCompositorFrame";
default:
NOTREACHED();
- return nullptr;
+ return "";
}
default:
NOTREACHED();
- return nullptr;
+ return "";
}
}
@@ -128,7 +128,7 @@ constexpr const char* GetDispatchToTerminationBreakdownName(
return "RendererMainFinishedToTermination";
default:
NOTREACHED();
- return nullptr;
+ return "";
}
}
@@ -176,8 +176,7 @@ void EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
const std::vector<CompositorFrameReporter::StageData>* stage_history,
const CompositorFrameReporter::ProcessedVizBreakdown* viz_breakdown) {
DCHECK(event_metrics);
- DCHECK(!event_metrics->is_tracing_recorded());
- event_metrics->set_tracing_recorded();
+ DCHECK(event_metrics->should_record_tracing());
const base::TimeTicks generated_timestamp =
event_metrics->GetDispatchStageTimestamp(
@@ -227,68 +226,68 @@ void EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
}
if (stage_history) {
DCHECK(viz_breakdown);
- // Find the first compositor stage that happens after the final dispatch
- // stage.
+ // Find the first compositor stage that starts at the same time or after the
+ // end of the final event dispatch stage.
auto stage_it = std::find_if(
stage_history->begin(), stage_history->end(),
[dispatch_timestamp](const CompositorFrameReporter::StageData& stage) {
- return stage.start_time > dispatch_timestamp;
+ return stage.start_time >= dispatch_timestamp;
});
- // TODO(crbug.com/1079116): Ideally, at least the start time of
+ // TODO(crbug.com/1330903): Ideally, at least the start time of
// SubmitCompositorFrameToPresentationCompositorFrame stage should be
- // greater than the final event dispatch timestamp, but apparently, this is
- // not always the case (see crbug.com/1093698). For now, skip to the next
- // event in such cases. Hopefully, the work to reduce discrepancies between
- // the new EventLatency and the old Event.Latency metrics would fix this
- // issue. If not, we need to reconsider investigating this issue.
- if (stage_it == stage_history->end())
- return;
+ // greater than or equal to the final event dispatch timestamp, but
+ // apparently, this is not always the case (see crbug.com/1330903). Skip
+ // recording compositor stages for now until we investigate the issue.
+ if (stage_it != stage_history->end()) {
+ DCHECK(dispatch_stage ==
+ EventMetrics::DispatchStage::kRendererCompositorFinished ||
+ dispatch_stage ==
+ EventMetrics::DispatchStage::kRendererMainFinished);
- DCHECK(dispatch_stage ==
- EventMetrics::DispatchStage::kRendererCompositorFinished ||
- dispatch_stage ==
- EventMetrics::DispatchStage::kRendererMainFinished);
-
- const char* d2c_breakdown_name = GetDispatchToCompositorBreakdownName(
- dispatch_stage, stage_it->stage_type);
- TRACE_EVENT_BEGIN(kTracingCategory,
- perfetto::StaticString{d2c_breakdown_name}, trace_track,
- dispatch_timestamp);
- TRACE_EVENT_END(kTracingCategory, trace_track, stage_it->start_time);
+ // Record dispatch-to-compositor stage only if it has non-zero duration.
+ if (dispatch_timestamp < stage_it->start_time) {
+ const char* d2c_breakdown_name = GetDispatchToCompositorBreakdownName(
+ dispatch_stage, stage_it->stage_type);
+ TRACE_EVENT_BEGIN(kTracingCategory,
+ perfetto::StaticString{d2c_breakdown_name},
+ trace_track, dispatch_timestamp);
+ TRACE_EVENT_END(kTracingCategory, trace_track, stage_it->start_time);
+ }
- // Compositor stages.
- for (; stage_it != stage_history->end(); ++stage_it) {
- if (stage_it->start_time >= termination_time)
- break;
- DCHECK_GE(stage_it->end_time, stage_it->start_time);
- if (stage_it->start_time == stage_it->end_time)
- continue;
- const char* stage_name =
- CompositorFrameReporter::GetStageName(stage_it->stage_type);
+ // Compositor stages.
+ for (; stage_it != stage_history->end(); ++stage_it) {
+ if (stage_it->start_time >= termination_time)
+ break;
+ DCHECK_GE(stage_it->end_time, stage_it->start_time);
+ if (stage_it->start_time == stage_it->end_time)
+ continue;
+ const char* stage_name =
+ CompositorFrameReporter::GetStageName(stage_it->stage_type);
- TRACE_EVENT_BEGIN(kTracingCategory, perfetto::StaticString{stage_name},
- trace_track, stage_it->start_time);
+ TRACE_EVENT_BEGIN(kTracingCategory, perfetto::StaticString{stage_name},
+ trace_track, stage_it->start_time);
- if (stage_it->stage_type ==
- CompositorFrameReporter::StageType::
- kSubmitCompositorFrameToPresentationCompositorFrame) {
- DCHECK(viz_breakdown);
- for (auto it = viz_breakdown->CreateIterator(true); it.IsValid();
- it.Advance()) {
- base::TimeTicks start_time = it.GetStartTime();
- base::TimeTicks end_time = it.GetEndTime();
- if (start_time >= end_time)
- continue;
- const char* breakdown_name =
- CompositorFrameReporter::GetVizBreakdownName(it.GetBreakdown());
- TRACE_EVENT_BEGIN(kTracingCategory,
- perfetto::StaticString{breakdown_name}, trace_track,
- start_time);
- TRACE_EVENT_END(kTracingCategory, trace_track, end_time);
+ if (stage_it->stage_type ==
+ CompositorFrameReporter::StageType::
+ kSubmitCompositorFrameToPresentationCompositorFrame) {
+ DCHECK(viz_breakdown);
+ for (auto it = viz_breakdown->CreateIterator(true); it.IsValid();
+ it.Advance()) {
+ base::TimeTicks start_time = it.GetStartTime();
+ base::TimeTicks end_time = it.GetEndTime();
+ if (start_time >= end_time)
+ continue;
+ const char* breakdown_name =
+ CompositorFrameReporter::GetVizBreakdownName(it.GetBreakdown());
+ TRACE_EVENT_BEGIN(kTracingCategory,
+ perfetto::StaticString{breakdown_name},
+ trace_track, start_time);
+ TRACE_EVENT_END(kTracingCategory, trace_track, end_time);
+ }
}
- }
- TRACE_EVENT_END(kTracingCategory, trace_track, stage_it->end_time);
+ TRACE_EVENT_END(kTracingCategory, trace_track, stage_it->end_time);
+ }
}
} else {
DCHECK(!viz_breakdown);
@@ -300,6 +299,8 @@ void EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
TRACE_EVENT_END(kTracingCategory, trace_track, termination_time);
}
TRACE_EVENT_END(kTracingCategory, trace_track, termination_time);
+
+ event_metrics->tracing_recorded();
}
} // namespace cc
diff --git a/chromium/cc/metrics/event_latency_tracker.cc b/chromium/cc/metrics/event_latency_tracker.cc
new file mode 100644
index 00000000000..17e4cf4cb01
--- /dev/null
+++ b/chromium/cc/metrics/event_latency_tracker.cc
@@ -0,0 +1,23 @@
+// Copyright 2022 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/event_latency_tracker.h"
+
+namespace cc {
+
+EventLatencyTracker::LatencyData::LatencyData(
+ EventMetrics::EventType event_type,
+ base::TimeDelta total_latency)
+ : event_type(event_type), total_latency(total_latency) {}
+
+EventLatencyTracker::LatencyData::~LatencyData() = default;
+
+EventLatencyTracker::LatencyData::LatencyData(LatencyData&&) = default;
+EventLatencyTracker::LatencyData& EventLatencyTracker::LatencyData::operator=(
+ LatencyData&&) = default;
+
+EventLatencyTracker::EventLatencyTracker() = default;
+EventLatencyTracker::~EventLatencyTracker() = default;
+
+} // namespace cc
diff --git a/chromium/cc/metrics/event_latency_tracker.h b/chromium/cc/metrics/event_latency_tracker.h
new file mode 100644
index 00000000000..1d42588c343
--- /dev/null
+++ b/chromium/cc/metrics/event_latency_tracker.h
@@ -0,0 +1,54 @@
+// Copyright 2022 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_EVENT_LATENCY_TRACKER_H_
+#define CC_METRICS_EVENT_LATENCY_TRACKER_H_
+
+#include <vector>
+
+#include "base/time/time.h"
+#include "cc/cc_export.h"
+#include "cc/metrics/event_metrics.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+namespace cc {
+
+// Used by `CompositorFrameReporter` to report event latency information back to
+// `LayerTreeHostImpl` and eventually to UI compositor.
+class CC_EXPORT EventLatencyTracker {
+ public:
+ struct CC_EXPORT LatencyData {
+ LatencyData(EventMetrics::EventType event_type,
+ base::TimeDelta total_latency);
+ ~LatencyData();
+
+ LatencyData(const LatencyData&) = delete;
+ LatencyData& operator=(const LatencyData&) = delete;
+
+ LatencyData(LatencyData&&);
+ LatencyData& operator=(LatencyData&&);
+
+ EventMetrics::EventType event_type;
+ base::TimeDelta total_latency;
+
+ // Type of the input device if the event is a scroll or a pinch event.
+ absl::variant<absl::monostate,
+ ScrollEventMetrics::ScrollType,
+ PinchEventMetrics::PinchType>
+ input_type;
+ };
+
+ EventLatencyTracker();
+ virtual ~EventLatencyTracker();
+
+ EventLatencyTracker(const EventLatencyTracker&) = delete;
+ EventLatencyTracker& operator=(const EventLatencyTracker&) = delete;
+
+ // Called every time a frame has latency metrics to report for events.
+ virtual void ReportEventLatency(std::vector<LatencyData> latencies) = 0;
+};
+
+} // namespace cc
+
+#endif // CC_METRICS_EVENT_LATENCY_TRACKER_H_
diff --git a/chromium/cc/metrics/event_metrics.cc b/chromium/cc/metrics/event_metrics.cc
index a2ad67a8be9..aff7043c15f 100644
--- a/chromium/cc/metrics/event_metrics.cc
+++ b/chromium/cc/metrics/event_metrics.cc
@@ -255,12 +255,14 @@ EventMetrics::EventMetrics(EventType type,
}
EventMetrics::EventMetrics(const EventMetrics& other)
- : type_(other.type_), tick_clock_(other.tick_clock_) {
+ : type_(other.type_),
+ tick_clock_(other.tick_clock_),
+ should_record_tracing_(false) {
CopyTimestampsFrom(other, DispatchStage::kMaxValue);
}
EventMetrics::~EventMetrics() {
- if (!is_tracing_recorded()) {
+ if (should_record_tracing()) {
EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
this, base::TimeTicks::Now(), nullptr, nullptr);
}
@@ -428,7 +430,7 @@ ScrollEventMetrics::ScrollEventMetrics(EventType type,
ScrollEventMetrics::ScrollEventMetrics(const ScrollEventMetrics&) = default;
ScrollEventMetrics::~ScrollEventMetrics() {
- if (!is_tracing_recorded()) {
+ if (should_record_tracing()) {
EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
this, base::TimeTicks::Now(), nullptr, nullptr);
}
@@ -561,7 +563,7 @@ ScrollUpdateEventMetrics::ScrollUpdateEventMetrics(
const ScrollUpdateEventMetrics&) = default;
ScrollUpdateEventMetrics::~ScrollUpdateEventMetrics() {
- if (!is_tracing_recorded()) {
+ if (should_record_tracing()) {
EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
this, base::TimeTicks::Now(), nullptr, nullptr);
}
@@ -648,7 +650,7 @@ PinchEventMetrics::PinchEventMetrics(EventType type,
PinchEventMetrics::PinchEventMetrics(const PinchEventMetrics&) = default;
PinchEventMetrics::~PinchEventMetrics() {
- if (!is_tracing_recorded()) {
+ if (should_record_tracing()) {
EventLatencyTracingRecorder::RecordEventLatencyTraceEvent(
this, base::TimeTicks::Now(), nullptr, nullptr);
}
diff --git a/chromium/cc/metrics/event_metrics.h b/chromium/cc/metrics/event_metrics.h
index 6cd48a69f32..b8c43eab201 100644
--- a/chromium/cc/metrics/event_metrics.h
+++ b/chromium/cc/metrics/event_metrics.h
@@ -126,16 +126,29 @@ class CC_EXPORT EventMetrics {
virtual std::unique_ptr<EventMetrics> Clone() const;
- bool is_tracing_recorded() const { return is_tracing_recorded_; }
- void set_tracing_recorded() {
- DCHECK(!is_tracing_recorded_);
- is_tracing_recorded_ = true;
+ bool should_record_tracing() const { return should_record_tracing_; }
+ void tracing_recorded() {
+ DCHECK(should_record_tracing_);
+ should_record_tracing_ = false;
+ }
+
+ bool requires_main_thread_update() const {
+ return requires_main_thread_update_;
+ }
+ void set_requires_main_thread_update() {
+ DCHECK(!requires_main_thread_update_);
+ requires_main_thread_update_ = true;
}
protected:
EventMetrics(EventType type,
base::TimeTicks timestamp,
const base::TickClock* tick_clock);
+
+ // Creates a clone of `other` that might be used in creating `EventMetrics`
+ // objects for some injected events. Since this object itself does not
+ // directly correspond to an event, it won't be used in recording trace
+ // events.
EventMetrics(const EventMetrics& other);
// Copy timestamps of dispatch stages (up to and including
@@ -163,7 +176,17 @@ class CC_EXPORT EventMetrics {
dispatch_stage_timestamps_[static_cast<int>(DispatchStage::kMaxValue) +
1];
- bool is_tracing_recorded_ = false;
+ // Determines whether a tracing event should be recorded for this object or
+ // not. This is `true` by default and set to `false` after a tracing event is
+ // recorded to avoid multiple recordings. Also, it is `false` for cloned
+ // objects as they are not meant to be recorded in tracings.
+ bool should_record_tracing_ = true;
+
+ // This is set on an EventMetrics object that comes from the impl thread, if
+ // the visual update from the event requires the main thread. Currently used
+ // for GestureScrollUpdate with scroll unification, when the scroller isn't
+ // composited or has main-thread scrolling reasons on the ScrollNode.
+ bool requires_main_thread_update_ = false;
};
class CC_EXPORT ScrollEventMetrics : public EventMetrics {
diff --git a/chromium/cc/metrics/frame_info.cc b/chromium/cc/metrics/frame_info.cc
index 94fcef7a2db..003cc67a9cb 100644
--- a/chromium/cc/metrics/frame_info.cc
+++ b/chromium/cc/metrics/frame_info.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "base/check.h"
#include "build/build_config.h"
namespace cc {
@@ -179,6 +180,10 @@ bool FrameInfo::WasSmoothMainUpdateDropped() const {
return false;
}
+bool FrameInfo::WasSmoothMainUpdateExpected() const {
+ return final_state != FrameFinalState::kNoUpdateDesired;
+}
+
bool FrameInfo::IsScrollPrioritizeFrameDropped() const {
// If any scroll is active the dropped frame for only the scrolling thread is
// reported. If no scroll is active then reports if dropped frames is
diff --git a/chromium/cc/metrics/frame_info.h b/chromium/cc/metrics/frame_info.h
index 1ebdfd87a78..6fbbeb3819b 100644
--- a/chromium/cc/metrics/frame_info.h
+++ b/chromium/cc/metrics/frame_info.h
@@ -70,6 +70,7 @@ struct CC_EXPORT FrameInfo {
// whether the update was part of a smooth sequence.
bool WasSmoothCompositorUpdateDropped() const;
bool WasSmoothMainUpdateDropped() const;
+ bool WasSmoothMainUpdateExpected() const;
bool IsScrollPrioritizeFrameDropped() const;
diff --git a/chromium/cc/metrics/frame_sequence_metrics.cc b/chromium/cc/metrics/frame_sequence_metrics.cc
index 1f4c2a5f717..5d3938153e7 100644
--- a/chromium/cc/metrics/frame_sequence_metrics.cc
+++ b/chromium/cc/metrics/frame_sequence_metrics.cc
@@ -25,6 +25,10 @@ using SmoothEffectDrivingThread = FrameInfo::SmoothEffectDrivingThread;
bool ShouldReportForAnimation(FrameSequenceTrackerType sequence_type,
SmoothEffectDrivingThread thread_type) {
+ // kSETMainThreadAnimation and kSETCompositorAnimation sequences are a subset
+ // of kMainThreadAnimation and kCompositorAnimation sequences. So these are
+ // excluded from the AllAnimation metric to avoid double counting.
+
if (sequence_type == FrameSequenceTrackerType::kCompositorAnimation)
return thread_type == SmoothEffectDrivingThread::kCompositor;
@@ -91,6 +95,13 @@ std::string GetThroughputV2HistogramName(FrameSequenceTrackerType type,
FrameSequenceTracker::GetFrameSequenceTrackerTypeName(type)});
}
+std::string GetThroughputV3HistogramName(FrameSequenceTrackerType type,
+ const char* thread_name) {
+ return base::StrCat(
+ {"Graphics.Smoothness.PercentDroppedFrames3.", thread_name, ".",
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(type)});
+}
+
std::string GetMissedDeadlineHistogramName(FrameSequenceTrackerType type,
const char* thread_name) {
return base::StrCat(
@@ -149,11 +160,13 @@ void FrameSequenceMetrics::SetCustomReporter(CustomReporter custom_reporter) {
SmoothEffectDrivingThread FrameSequenceMetrics::GetEffectiveThread() const {
switch (type_) {
case FrameSequenceTrackerType::kCompositorAnimation:
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
case FrameSequenceTrackerType::kPinchZoom:
case FrameSequenceTrackerType::kVideo:
return SmoothEffectDrivingThread::kCompositor;
case FrameSequenceTrackerType::kMainThreadAnimation:
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
case FrameSequenceTrackerType::kRAF:
case FrameSequenceTrackerType::kCanvasAnimation:
case FrameSequenceTrackerType::kJSAnimation:
@@ -186,6 +199,9 @@ void FrameSequenceMetrics::Merge(
v2_.frames_expected += metrics->v2_.frames_expected;
v2_.frames_dropped += metrics->v2_.frames_dropped;
+ v3_.frames_expected += metrics->v3_.frames_expected;
+ v3_.frames_dropped += metrics->v3_.frames_dropped;
+
if (jank_reporter_)
jank_reporter_->Merge(std::move(metrics->jank_reporter_));
@@ -198,12 +214,14 @@ void FrameSequenceMetrics::Merge(
bool FrameSequenceMetrics::HasEnoughDataForReporting() const {
return impl_throughput_.frames_expected >= kMinFramesForThroughputMetric ||
- main_throughput_.frames_expected >= kMinFramesForThroughputMetric;
+ main_throughput_.frames_expected >= kMinFramesForThroughputMetric ||
+ v2_.frames_expected >= kMinFramesForThroughputMetric ||
+ v3_.frames_expected >= kMinFramesForThroughputMetric;
}
bool FrameSequenceMetrics::HasDataLeftForReporting() const {
- return impl_throughput_.frames_expected > 0 ||
- main_throughput_.frames_expected > 0;
+ return impl_throughput_.frames_expected > 0 || v2_.frames_expected > 0 ||
+ main_throughput_.frames_expected > 0 || v3_.frames_expected > 0;
}
void FrameSequenceMetrics::AdoptTrace(FrameSequenceMetrics* adopt_from) {
@@ -263,11 +281,12 @@ void FrameSequenceMetrics::ReportMetrics() {
const bool compositor_report = ThroughputData::CanReportHistogram(
this, SmoothEffectDrivingThread::kCompositor, impl_throughput_);
+ const auto thread_type = GetEffectiveThread();
+ const bool is_animation = ShouldReportForAnimation(type(), thread_type);
+ const bool is_interaction =
+ ShouldReportForInteraction(type(), thread_type, thread_type);
+
if (v2_.frames_expected >= kMinFramesForThroughputMetric) {
- const auto thread_type = GetEffectiveThread();
- const bool is_animation = ShouldReportForAnimation(type(), thread_type);
- const bool is_interaction =
- ShouldReportForInteraction(type(), thread_type, thread_type);
int percent = v2_.frames_expected == 0
? 0
: std::ceil(100. * v2_.frames_dropped /
@@ -298,10 +317,44 @@ void FrameSequenceMetrics::ReportMetrics() {
base::LinearHistogram::FactoryGet(
GetThroughputV2HistogramName(type(), thread_name), 1, 100, 101,
base::HistogramBase::kUmaTargetedHistogramFlag));
-
v2_ = {};
}
+ if (v3_.frames_expected >= kMinFramesForThroughputMetric) {
+ int percent = v3_.frames_expected == 0
+ ? 0
+ : std::ceil(100. * v3_.frames_dropped /
+ static_cast<double>(v3_.frames_expected));
+
+ if (is_animation) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ "Graphics.Smoothness.PercentDroppedFrames3.AllAnimations", percent);
+ }
+ if (is_interaction) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ "Graphics.Smoothness.PercentDroppedFrames3.AllInteractions", percent);
+ }
+ if (is_animation || is_interaction) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ "Graphics.Smoothness.PercentDroppedFrames3.AllSequences", percent);
+ }
+
+ const char* thread_name =
+ thread_type == SmoothEffectDrivingThread::kCompositor
+ ? "CompositorThread"
+ : "MainThread";
+
+ STATIC_HISTOGRAM_POINTER_GROUP(
+ GetThroughputV3HistogramName(type(), thread_name),
+ GetIndexForMetric(thread_type, type_), kMaximumHistogramIndex,
+ Add(percent),
+ base::LinearHistogram::FactoryGet(
+ GetThroughputV3HistogramName(type(), thread_name), 1, 100, 101,
+ base::HistogramBase::kUmaTargetedHistogramFlag));
+
+ v3_ = {};
+ }
+
absl::optional<int> impl_throughput_percent_dropped;
absl::optional<int> impl_throughput_percent_missed;
absl::optional<int> main_throughput_percent_dropped;
@@ -465,14 +518,16 @@ bool FrameSequenceMetrics::ThroughputData::CanReportHistogram(
const auto sequence_type = metrics->type();
DCHECK_LT(sequence_type, FrameSequenceTrackerType::kMaxType);
- // All video frames are compositor thread only.
- if (sequence_type == FrameSequenceTrackerType::kVideo &&
+ // All video frames and SET compositor animations are compositor thread only.
+ if ((sequence_type == FrameSequenceTrackerType::kVideo ||
+ sequence_type == FrameSequenceTrackerType::kSETCompositorAnimation) &&
thread_type == SmoothEffectDrivingThread::kMain)
return false;
- // RAF and CanvasAnimation are main thread only.
+ // RAF, CanvasAnimation and SET main thread animations are main thread only.
if ((sequence_type == FrameSequenceTrackerType::kRAF ||
- sequence_type == FrameSequenceTrackerType::kCanvasAnimation) &&
+ sequence_type == FrameSequenceTrackerType::kCanvasAnimation ||
+ sequence_type == FrameSequenceTrackerType::kSETMainThreadAnimation) &&
thread_type == SmoothEffectDrivingThread::kCompositor)
return false;
@@ -485,7 +540,9 @@ bool FrameSequenceMetrics::ThroughputData::CanReportHistogram(
return is_animation || IsInteractionType(sequence_type) ||
sequence_type == FrameSequenceTrackerType::kVideo ||
sequence_type == FrameSequenceTrackerType::kRAF ||
- sequence_type == FrameSequenceTrackerType::kCanvasAnimation;
+ sequence_type == FrameSequenceTrackerType::kCanvasAnimation ||
+ sequence_type == FrameSequenceTrackerType::kSETMainThreadAnimation ||
+ sequence_type == FrameSequenceTrackerType::kSETCompositorAnimation;
}
int FrameSequenceMetrics::ThroughputData::ReportDroppedFramePercentHistogram(
@@ -692,10 +749,18 @@ void FrameSequenceMetrics::AddSortedFrame(const viz::BeginFrameArgs& args,
case SmoothEffectDrivingThread::kCompositor:
if (frame_info.WasSmoothCompositorUpdateDropped()) {
++v2_.frames_dropped;
+ ++v3_.frames_dropped;
}
++v2_.frames_expected;
+ ++v3_.frames_expected;
break;
case SmoothEffectDrivingThread::kMain:
+ if (frame_info.WasSmoothMainUpdateExpected()) {
+ if (frame_info.WasSmoothMainUpdateDropped()) {
+ ++v3_.frames_dropped;
+ }
+ ++v3_.frames_expected;
+ }
if (frame_info.WasSmoothMainUpdateDropped()) {
++v2_.frames_dropped;
}
diff --git a/chromium/cc/metrics/frame_sequence_metrics.h b/chromium/cc/metrics/frame_sequence_metrics.h
index 671fc9ff578..33fa2b8ae30 100644
--- a/chromium/cc/metrics/frame_sequence_metrics.h
+++ b/chromium/cc/metrics/frame_sequence_metrics.h
@@ -6,9 +6,11 @@
#define CC_METRICS_FRAME_SEQUENCE_METRICS_H_
#include <bitset>
+#include <cmath>
#include <memory>
#include "base/callback.h"
+#include "base/check.h"
#include "base/memory/raw_ptr.h"
#include "base/trace_event/traced_value.h"
#include "cc/cc_export.h"
@@ -38,6 +40,8 @@ enum class FrameSequenceTrackerType {
// and instead are dispatched back to the LayerTreeHostClient.
kCanvasAnimation = 10,
kJSAnimation = 11,
+ kSETMainThreadAnimation = 12,
+ kSETCompositorAnimation = 13,
kMaxType
};
@@ -233,6 +237,12 @@ class CC_EXPORT FrameSequenceMetrics {
uint32_t frames_dropped = 0;
} v2_;
+ // Track state for measuring the PercentDroppedFrames v3 metrics.
+ struct {
+ uint32_t frames_expected = 0;
+ uint32_t frames_dropped = 0;
+ } v3_;
+
ThroughputData impl_throughput_;
ThroughputData main_throughput_;
diff --git a/chromium/cc/metrics/frame_sequence_metrics_unittest.cc b/chromium/cc/metrics/frame_sequence_metrics_unittest.cc
index cbef003b39b..c5729bd4883 100644
--- a/chromium/cc/metrics/frame_sequence_metrics_unittest.cc
+++ b/chromium/cc/metrics/frame_sequence_metrics_unittest.cc
@@ -233,4 +233,50 @@ TEST(FrameSequenceMetricsTest, ScrollingThreadMetricsReportedForInteractions) {
}
}
+TEST(FrameSequenceMetricsTest, CompositorSharedElementTransitionReported) {
+ base::HistogramTester histograms;
+
+ auto metrics = std::make_unique<FrameSequenceMetrics>(
+ FrameSequenceTrackerType::kSETCompositorAnimation, nullptr);
+ metrics->impl_throughput().frames_expected = 100;
+ metrics->impl_throughput().frames_produced = 80;
+ metrics->impl_throughput().frames_ontime = 70;
+ metrics->main_throughput().frames_expected = 100;
+ metrics->main_throughput().frames_produced = 60;
+ metrics->main_throughput().frames_ontime = 50;
+ EXPECT_TRUE(metrics->HasEnoughDataForReporting());
+ metrics->ReportMetrics();
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.PercentDroppedFrames.CompositorThread."
+ "SETCompositorAnimation",
+ 1u);
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.PercentDroppedFrames.MainThread."
+ "SETCompositorAnimation",
+ 0u);
+}
+
+TEST(FrameSequenceMetricsTest, MainThreadSharedElementTransitionReported) {
+ base::HistogramTester histograms;
+
+ auto metrics = std::make_unique<FrameSequenceMetrics>(
+ FrameSequenceTrackerType::kSETMainThreadAnimation, nullptr);
+ metrics->impl_throughput().frames_expected = 100;
+ metrics->impl_throughput().frames_produced = 80;
+ metrics->impl_throughput().frames_ontime = 70;
+ metrics->main_throughput().frames_expected = 100;
+ metrics->main_throughput().frames_produced = 60;
+ metrics->main_throughput().frames_ontime = 50;
+ EXPECT_TRUE(metrics->HasEnoughDataForReporting());
+ metrics->ReportMetrics();
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.PercentDroppedFrames.CompositorThread."
+ "SETMainThreadAnimation",
+ 0u);
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.PercentDroppedFrames.MainThread."
+ "SETMainThreadAnimation",
+ 1u);
+}
+
} // namespace cc
diff --git a/chromium/cc/metrics/frame_sequence_tracker.cc b/chromium/cc/metrics/frame_sequence_tracker.cc
index baf282b87d7..8db69731d27 100644
--- a/chromium/cc/metrics/frame_sequence_tracker.cc
+++ b/chromium/cc/metrics/frame_sequence_tracker.cc
@@ -74,6 +74,10 @@ const char* FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
return "CanvasAnimation";
case FrameSequenceTrackerType::kJSAnimation:
return "JSAnimation";
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
+ return "SETMainThreadAnimation";
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
+ return "SETCompositorAnimation";
case FrameSequenceTrackerType::kMaxType:
return "";
}
diff --git a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
index cb3c6d72cfd..e1f7b45cad7 100644
--- a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
+++ b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -13,9 +13,6 @@
#include "base/test/metrics/histogram_tester.h"
#include "cc/metrics/compositor_frame_reporting_controller.h"
#include "cc/metrics/frame_sequence_tracker_collection.h"
-#include "cc/metrics/throughput_ukm_reporter.h"
-#include "cc/trees/ukm_manager.h"
-#include "components/ukm/test_ukm_recorder.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,7 +42,8 @@ class FrameSequenceTrackerTest : public testing::Test {
FrameSequenceTrackerTest()
: compositor_frame_reporting_controller_(
std::make_unique<CompositorFrameReportingController>(
- /*should_report_metrics=*/true,
+ /*should_report_histograms=*/true,
+ /*should_report_ukm=*/false,
/*layer_tree_host_id=*/1)),
collection_(/*is_single_threaded=*/false,
compositor_frame_reporting_controller_.get()) {
diff --git a/chromium/cc/metrics/total_frame_counter.cc b/chromium/cc/metrics/total_frame_counter.cc
index 1d07e354b20..7acec184658 100644
--- a/chromium/cc/metrics/total_frame_counter.cc
+++ b/chromium/cc/metrics/total_frame_counter.cc
@@ -4,6 +4,8 @@
#include "cc/metrics/total_frame_counter.h"
+#include <cmath>
+
#include "base/logging.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
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 060ab11ba52..7df43281b36 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
@@ -179,7 +179,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListEmpty) {
auto pass = viz::CompositorRenderPass::Create();
pass->id = viz::CompositorRenderPassId{1};
pass->output_rect = display_rect_;
- pass_list.push_back(move(pass));
+ pass_list.push_back(std::move(pass));
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
@@ -194,7 +194,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
auto pass1 = viz::CompositorRenderPass::Create();
pass1->id = viz::CompositorRenderPassId{1};
pass1->output_rect = display_rect_;
- pass_list.push_back(move(pass1));
+ pass_list.push_back(std::move(pass1));
viz::HitTestRegionList region_list1;
region_list1.flags = viz::HitTestRegionFlags::kHitTestMine;
@@ -209,7 +209,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
auto pass2 = viz::CompositorRenderPass::Create();
pass2->id = viz::CompositorRenderPassId{2};
pass2->output_rect = display_rect_;
- pass_list.push_back(move(pass2));
+ pass_list.push_back(std::move(pass2));
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
@@ -221,7 +221,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
auto pass3 = viz::CompositorRenderPass::Create();
pass3->id = viz::CompositorRenderPassId{3};
pass3->output_rect = display_rect_;
- pass_list.push_back(move(pass3));
+ pass_list.push_back(std::move(pass3));
viz::HitTestRegionList region_list2;
region_list2.flags = viz::HitTestRegionFlags::kHitTestMine;
@@ -242,7 +242,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest,
auto pass1 = viz::CompositorRenderPass::Create();
pass1->id = viz::CompositorRenderPassId{1};
pass1->output_rect = display_rect_;
- pass_list.push_back(move(pass1));
+ pass_list.push_back(std::move(pass1));
viz::HitTestRegionList region_list1;
region_list1.flags = viz::HitTestRegionFlags::kHitTestMine;
@@ -276,7 +276,7 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest,
auto pass3 = viz::CompositorRenderPass::Create();
pass3->id = viz::CompositorRenderPassId{3};
pass3->output_rect = display_rect_;
- pass_list.push_back(move(pass3));
+ pass_list.push_back(std::move(pass3));
viz::HitTestRegionList region_list3;
region_list3.flags = viz::HitTestRegionFlags::kHitTestChildSurface;
diff --git a/chromium/cc/mojom/render_frame_metadata.mojom b/chromium/cc/mojom/render_frame_metadata.mojom
index aa861674703..3ee3462988e 100644
--- a/chromium/cc/mojom/render_frame_metadata.mojom
+++ b/chromium/cc/mojom/render_frame_metadata.mojom
@@ -4,6 +4,7 @@
module cc.mojom;
+import "mojo/public/mojom/base/time.mojom";
import "services/viz/public/mojom/compositing/local_surface_id.mojom";
import "services/viz/public/mojom/compositing/selection.mojom";
import "services/viz/public/mojom/compositing/vertical_scroll_direction.mojom";
@@ -79,6 +80,14 @@ struct RenderFrameMetadata {
viz.mojom.VerticalScrollDirection new_vertical_scroll_direction;
+ // The cumulative time spent performing visual updates since the last commit.
+ // Tracked for all `local_surface_id` before this one.
+ mojo_base.mojom.TimeDelta previous_surfaces_visual_update_duration;
+
+ // The cumulative time spend performing visual updates for the current
+ // `local_surface_id` since the last commit.
+ mojo_base.mojom.TimeDelta current_surface_visual_update_duration;
+
// Used to position Android bottom bar, whose position is computed by the
// renderer compositor.
[EnableIf=is_android]
diff --git a/chromium/cc/mojom/render_frame_metadata_mojom_traits.cc b/chromium/cc/mojom/render_frame_metadata_mojom_traits.cc
index 46df44bc5de..3e4cdf17c6b 100644
--- a/chromium/cc/mojom/render_frame_metadata_mojom_traits.cc
+++ b/chromium/cc/mojom/render_frame_metadata_mojom_traits.cc
@@ -5,6 +5,7 @@
#include "cc/mojom/render_frame_metadata_mojom_traits.h"
#include "build/build_config.h"
+#include "mojo/public/cpp/base/time_mojom_traits.h"
#include "services/viz/public/cpp/compositing/selection_mojom_traits.h"
#include "services/viz/public/cpp/compositing/vertical_scroll_direction_mojom_traits.h"
#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
@@ -55,7 +56,11 @@ bool StructTraits<
data.ReadViewportSizeInPixels(&out->viewport_size_in_pixels) &&
data.ReadLocalSurfaceId(&out->local_surface_id) &&
data.ReadNewVerticalScrollDirection(
- &out->new_vertical_scroll_direction);
+ &out->new_vertical_scroll_direction) &&
+ data.ReadPreviousSurfacesVisualUpdateDuration(
+ &out->previous_surfaces_visual_update_duration) &&
+ data.ReadCurrentSurfaceVisualUpdateDuration(
+ &out->current_surface_visual_update_duration);
}
} // namespace mojo
diff --git a/chromium/cc/mojom/render_frame_metadata_mojom_traits.h b/chromium/cc/mojom/render_frame_metadata_mojom_traits.h
index 18fef4ff5e6..8631acd1a6e 100644
--- a/chromium/cc/mojom/render_frame_metadata_mojom_traits.h
+++ b/chromium/cc/mojom/render_frame_metadata_mojom_traits.h
@@ -96,6 +96,16 @@ struct COMPONENT_EXPORT(CC_SHARED_MOJOM_TRAITS)
return metadata.new_vertical_scroll_direction;
}
+ static base::TimeDelta previous_surfaces_visual_update_duration(
+ const cc::RenderFrameMetadata& metadata) {
+ return metadata.previous_surfaces_visual_update_duration;
+ }
+
+ static base::TimeDelta current_surface_visual_update_duration(
+ const cc::RenderFrameMetadata& metadata) {
+ return metadata.current_surface_visual_update_duration;
+ }
+
#if BUILDFLAG(IS_ANDROID)
static float bottom_controls_height(const cc::RenderFrameMetadata& metadata) {
return metadata.bottom_controls_height;
diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc
index f26af0ff065..12767243365 100644
--- a/chromium/cc/paint/discardable_image_map_unittest.cc
+++ b/chromium/cc/paint/discardable_image_map_unittest.cc
@@ -917,7 +917,7 @@ TEST_F(DiscardableImageMapTest, CapturesImagesInSaveLayers) {
scoped_refptr<DisplayItemList> display_list = new DisplayItemList();
display_list->StartPaint();
display_list->push<SaveLayerOp>(nullptr, &flags);
- display_list->push<DrawColorOp>(SK_ColorBLUE, SkBlendMode::kSrc);
+ display_list->push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc);
display_list->EndPaintOfUnpaired(visible_rect);
display_list->Finalize();
diff --git a/chromium/cc/paint/display_item_list.cc b/chromium/cc/paint/display_item_list.cc
index 68648556c39..9ba516eb5fa 100644
--- a/chromium/cc/paint/display_item_list.cc
+++ b/chromium/cc/paint/display_item_list.cc
@@ -322,7 +322,7 @@ sk_sp<PaintRecord> DisplayItemList::ReleaseAsRecord() {
}
bool DisplayItemList::GetColorIfSolidInRect(const gfx::Rect& rect,
- SkColor* color,
+ SkColor4f* color,
int max_ops_to_analyze) {
DCHECK(usage_hint_ == kTopLevelDisplayItemList);
std::vector<size_t>* offsets_to_use = nullptr;
@@ -336,7 +336,7 @@ bool DisplayItemList::GetColorIfSolidInRect(const gfx::Rect& rect,
SolidColorAnalyzer::DetermineIfSolidColor(
&paint_op_buffer_, rect, max_ops_to_analyze, offsets_to_use);
if (solid_color) {
- *color = solid_color->toSkColor();
+ *color = *solid_color;
return true;
}
return false;
diff --git a/chromium/cc/paint/display_item_list.h b/chromium/cc/paint/display_item_list.h
index 2bd510b99ea..0a52e86b7fe 100644
--- a/chromium/cc/paint/display_item_list.h
+++ b/chromium/cc/paint/display_item_list.h
@@ -183,7 +183,7 @@ class CC_PAINT_EXPORT DisplayItemList
// indicates the maximum number of draw ops we consider when determining if a
// rectangle is solid color.
bool GetColorIfSolidInRect(const gfx::Rect& rect,
- SkColor* color,
+ SkColor4f* color,
int max_ops_to_analyze = 1);
std::string ToString() const;
diff --git a/chromium/cc/paint/display_item_list_unittest.cc b/chromium/cc/paint/display_item_list_unittest.cc
index 3246ef6de76..90608ac939f 100644
--- a/chromium/cc/paint/display_item_list_unittest.cc
+++ b/chromium/cc/paint/display_item_list_unittest.cc
@@ -31,6 +31,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/skia_conversions.h"
+#include "ui/gfx/geometry/transform.h"
namespace cc {
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index 0a83b7597e7..7fdce720233 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -296,7 +296,8 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
// 4-byte boundary.
safe_size += 4;
safe_size += pixmap_->computeByteSize();
- size_ = safe_size.ValueOrDefault(0);
+ size_ = base::bits::AlignUp(safe_size.ValueOrDefault(0),
+ PaintOpWriter::Alignment());
}
ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
@@ -345,7 +346,8 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
safe_size += decoded_color_space_size + align; // SkColorSpace for YUVA image
for (size_t i = 0; i < num_yuva_pixmaps; ++i)
safe_size += SafeSizeForPixmap(*yuv_pixmaps_->at(i));
- size_ = safe_size.ValueOrDefault(0);
+ size_ = base::bits::AlignUp(safe_size.ValueOrDefault(0),
+ PaintOpWriter::Alignment());
}
ClientImageTransferCacheEntry::~ClientImageTransferCacheEntry() = default;
diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc
index ef935c0bd73..57c8bf8ff07 100644
--- a/chromium/cc/paint/oop_pixeltest.cc
+++ b/chromium/cc/paint/oop_pixeltest.cc
@@ -80,7 +80,7 @@ scoped_refptr<DisplayItemList> MakeNoopDisplayItemList() {
}
// Creates a bitmap of |size| filled with pixels of |color|.
-SkBitmap MakeSolidColorBitmap(gfx::Size size, SkColor color) {
+SkBitmap MakeSolidColorBitmap(gfx::Size size, SkColor4f color) {
SkBitmap bitmap;
bitmap.allocPixels(SkImageInfo::MakeN32Premul(size.width(), size.height()));
bitmap.eraseColor(color);
@@ -96,9 +96,9 @@ sk_sp<SkImage> MakeSkImage(const gfx::Size& size,
SkBitmap::kZeroPixels_AllocFlag);
SkCanvas canvas(bitmap, SkSurfaceProps{});
- canvas.drawColor(SK_ColorMAGENTA);
+ canvas.drawColor(SkColors::kMagenta);
SkPaint green;
- green.setColor(SK_ColorGREEN);
+ green.setColor(SkColors::kGreen);
canvas.drawRect(SkRect::MakeXYWH(10, 20, 30, 40), green);
return SkImage::MakeFromBitmap(bitmap);
@@ -141,7 +141,7 @@ class OopPixelTest : public testing::Test,
oop_image_cache_ = std::make_unique<GpuImageDecodeCache>(
raster_context_provider_.get(), true, kRGBA_8888_SkColorType,
kWorkingSetSize, raster_max_texture_size,
- PaintImage::kDefaultGeneratorClientId, nullptr);
+ PaintImage::GetNextGeneratorClientId(), nullptr);
}
class RasterOptions {
@@ -154,7 +154,7 @@ class OopPixelTest : public testing::Test,
playback_rect = gfx::Rect(playback_size);
}
- SkColor background_color = SK_ColorBLACK;
+ SkColor4f background_color = SkColors::kBlack;
int msaa_sample_count = 0;
bool use_lcd_text = false;
PlaybackImageProvider::RasterMode image_provider_raster_mode =
@@ -168,7 +168,7 @@ class OopPixelTest : public testing::Test,
TargetColorParams target_color_params;
bool requires_clear = false;
bool preclear = false;
- SkColor preclear_color;
+ SkColor4f preclear_color;
raw_ptr<ImageDecodeCache> image_cache = nullptr;
std::vector<scoped_refptr<DisplayItemList>> additional_lists;
raw_ptr<PaintShader> shader_with_animated_images = nullptr;
@@ -216,8 +216,9 @@ class OopPixelTest : public testing::Test,
if (options.preclear) {
raster_implementation->BeginRasterCHROMIUM(
- options.preclear_color, /*needs_clear=*/options.preclear,
- options.msaa_sample_count, msaa_mode, options.use_lcd_text,
+ options.preclear_color,
+ /*needs_clear=*/options.preclear, options.msaa_sample_count,
+ msaa_mode, options.use_lcd_text,
/*visible=*/true, options.target_color_params.color_space,
mailbox.name);
raster_implementation->EndRasterCHROMIUM();
@@ -228,8 +229,9 @@ class OopPixelTest : public testing::Test,
// the BeginRasterCHROMIUM call above, and we want to test that it is indeed
// cleared, so set |needs_clear| to false here.
raster_implementation->BeginRasterCHROMIUM(
- options.background_color, /*needs_clear=*/!options.preclear,
- options.msaa_sample_count, msaa_mode, options.use_lcd_text,
+ options.background_color,
+ /*needs_clear=*/!options.preclear, options.msaa_sample_count, msaa_mode,
+ options.use_lcd_text,
/*visible=*/true, options.target_color_params.color_space,
mailbox.name);
size_t max_op_size_limit =
@@ -384,11 +386,11 @@ TEST_F(OopPixelTest, DrawColor) {
gfx::Rect rect(10, 10);
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorBLUE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
- SkBitmap expected = MakeSolidColorBitmap(rect.size(), SK_ColorBLUE);
+ SkBitmap expected = MakeSolidColorBitmap(rect.size(), SkColors::kBlue);
auto actual = Raster(display_item_list, rect.size());
ExpectEquals(actual, expected);
@@ -398,7 +400,7 @@ TEST_F(OopPixelTest, DrawColorWithTargetColorSpace) {
gfx::Rect rect(10, 10);
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorBLUE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
@@ -407,8 +409,8 @@ TEST_F(OopPixelTest, DrawColorWithTargetColorSpace) {
RasterOptions options(rect.size());
options.target_color_params.color_space = target_color_space;
- SkBitmap expected =
- MakeSolidColorBitmap(rect.size(), SkColorSetARGB(255, 38, 15, 221));
+ SkBitmap expected = MakeSolidColorBitmap(
+ rect.size(), SkColor4f::FromColor(SkColorSetARGB(255, 38, 15, 221)));
auto actual = Raster(display_item_list, options);
ExpectEquals(actual, expected);
@@ -466,7 +468,7 @@ TEST_F(OopPixelTest, DrawRecordPaintFilterTranslatedBounds) {
// green, but its record bounds are configured to clip it to the bottom right
// quarter of the output.
PaintFlags internal_flags;
- internal_flags.setColor(SK_ColorGREEN);
+ internal_flags.setColor(SkColors::kGreen);
sk_sp<PaintOpBuffer> filter_buffer(new PaintOpBuffer);
filter_buffer->push<DrawRectOp>(
SkRect::MakeLTRB(output_size.width() / 2.f, 0.f, output_size.width(),
@@ -482,7 +484,7 @@ TEST_F(OopPixelTest, DrawRecordPaintFilterTranslatedBounds) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
display_item_list->push<SaveLayerOp>(nullptr, &record_flags);
display_item_list->push<RestoreOp>();
display_item_list->EndPaintOfUnpaired(gfx::Rect(output_size));
@@ -492,9 +494,9 @@ TEST_F(OopPixelTest, DrawRecordPaintFilterTranslatedBounds) {
SkImageInfo::MakeN32Premul(output_size.width(), output_size.height());
SkBitmap expected;
expected.allocPixels(ii, ii.minRowBytes());
- expected.eraseColor(SK_ColorWHITE);
+ expected.eraseColor(SkColors::kWhite);
expected.erase(
- SK_ColorGREEN,
+ SkColors::kGreen.toSkColor(),
SkIRect::MakeLTRB(output_size.width() / 2, output_size.height() / 2,
output_size.width(), output_size.height()));
@@ -615,7 +617,7 @@ TEST_F(OopPixelTest, DrawRecordShaderTranslatedTileRect) {
// tiling starts from the origin, so starting at 2,1 in the offset_rect
// below cuts off part of that, leaving two green i's.
PaintFlags internal_flags;
- internal_flags.setColor(SK_ColorGREEN);
+ internal_flags.setColor(SkColors::kGreen);
sk_sp<PaintOpBuffer> shader_buffer(new PaintOpBuffer);
shader_buffer->push<DrawRectOp>(SkRect::MakeXYWH(x_offset, y_offset, 1, 2),
internal_flags);
@@ -633,7 +635,7 @@ TEST_F(OopPixelTest, DrawRecordShaderTranslatedTileRect) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
display_item_list->push<ScaleOp>(2.f, 2.f);
PaintFlags raster_flags;
raster_flags.setShader(paint_record_shader);
@@ -681,7 +683,7 @@ TEST_F(OopPixelTest, DrawImageWithTargetColorSpace) {
comparator);
// Verify some conversion occurred here and that actual != bitmap.
- EXPECT_NE(actual.getColor(0, 0), SK_ColorMAGENTA);
+ EXPECT_NE(actual.getColor(0, 0), SkColors::kMagenta.toSkColor());
}
TEST_F(OopPixelTest, DrawImageWithSourceColorSpace) {
@@ -823,9 +825,9 @@ TEST_F(OopPixelTest, DrawMailboxBackedImage) {
expected_bitmap.allocPixels(backing_info);
SkCanvas canvas(expected_bitmap, SkSurfaceProps{});
- canvas.drawColor(SK_ColorMAGENTA);
+ canvas.drawColor(SkColors::kMagenta);
SkPaint green;
- green.setColor(SK_ColorGREEN);
+ green.setColor(SkColors::kGreen);
canvas.drawRect(SkRect::MakeXYWH(1, 2, 3, 4), green);
auto* ri = raster_context_provider_->RasterInterface();
@@ -866,13 +868,13 @@ TEST_F(OopPixelTest, Preclear) {
options.resource_size = rect.size();
options.full_raster_rect = rect;
options.playback_rect = rect;
- options.background_color = SK_ColorMAGENTA;
+ options.background_color = SkColors::kMagenta;
options.preclear = true;
- options.preclear_color = SK_ColorGREEN;
+ options.preclear_color = SkColors::kGreen;
auto actual = Raster(display_item_list, options);
- auto expected = MakeSolidColorBitmap(rect.size(), SK_ColorGREEN);
+ auto expected = MakeSolidColorBitmap(rect.size(), SkColors::kGreen);
ExpectEquals(actual, expected);
}
@@ -894,12 +896,12 @@ TEST_P(OopClearPixelTest, ClearingOpaqueCorner) {
} else {
options.playback_rect = options.full_raster_rect;
}
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
float arbitrary_scale = 0.25f;
options.post_scale = arbitrary_scale;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -942,12 +944,12 @@ TEST_F(OopPixelTest, ClearingOpaqueCornerExactEdge) {
options.content_size = gfx::Size(options.full_raster_rect.right(),
options.full_raster_rect.bottom());
options.playback_rect = options.full_raster_rect;
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
float arbitrary_scale = 0.25f;
options.post_scale = arbitrary_scale;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -983,10 +985,10 @@ TEST_F(OopPixelTest, ClearingOpaqueCornerPartialRaster) {
options.full_raster_rect.bottom());
options.playback_rect =
gfx::Rect(arbitrary_offset.x() + 5, arbitrary_offset.y() + 3, 2, 3);
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Verify this is internal.
EXPECT_NE(options.playback_rect.right(), options.full_raster_rect.right());
@@ -1031,11 +1033,11 @@ TEST_P(OopClearPixelTest, ClearingOpaqueLeftEdge) {
options.playback_rect = options.full_raster_rect;
}
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
options.post_translate = gfx::Vector2dF(0.3f, 0.7f);
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1085,12 +1087,12 @@ TEST_P(OopClearPixelTest, ClearingOpaqueRightEdge) {
options.playback_rect = options.full_raster_rect;
}
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
float arbitrary_scale = 0.25f;
options.post_scale = arbitrary_scale;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1140,11 +1142,11 @@ TEST_P(OopClearPixelTest, ClearingOpaqueTopEdge) {
} else {
options.playback_rect = options.full_raster_rect;
}
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
options.post_translate = gfx::Vector2dF(0.3f, 0.7f);
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1195,12 +1197,12 @@ TEST_P(OopClearPixelTest, ClearingOpaqueBottomEdge) {
} else {
options.playback_rect = options.full_raster_rect;
}
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
float arbitrary_scale = 0.25f;
options.post_scale = arbitrary_scale;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1240,13 +1242,13 @@ TEST_F(OopPixelTest, ClearingOpaqueInternal) {
// Very large content rect to make this an internal tile.
options.content_size = gfx::Size(1000, 1000);
options.playback_rect = options.full_raster_rect;
- options.background_color = SK_ColorGREEN;
+ options.background_color = SkColors::kGreen;
options.post_translate = gfx::Vector2dF(0.3f, 0.7f);
float arbitrary_scale = 1.2345f;
options.post_scale = arbitrary_scale;
options.requires_clear = false;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1275,12 +1277,12 @@ TEST_F(OopPixelTest, ClearingTransparentCorner) {
options.content_size = gfx::Size(options.full_raster_rect.right(),
options.full_raster_rect.bottom());
options.playback_rect = options.full_raster_rect;
- options.background_color = SK_ColorTRANSPARENT;
+ options.background_color = SkColors::kTransparent;
float arbitrary_scale = 3.7f;
options.post_scale = arbitrary_scale;
options.requires_clear = true;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1296,7 +1298,7 @@ TEST_F(OopPixelTest, ClearingTransparentCorner) {
SkBitmap::kZeroPixels_AllocFlag);
SkCanvas canvas(bitmap, SkSurfaceProps{});
- canvas.drawColor(SK_ColorTRANSPARENT);
+ canvas.drawColor(SkColors::kTransparent);
ExpectEquals(oop_result, bitmap);
}
@@ -1310,12 +1312,12 @@ TEST_F(OopPixelTest, ClearingTransparentInternalTile) {
options.full_raster_rect = gfx::Rect(arbitrary_offset, options.resource_size);
options.content_size = gfx::Size(1000, 1000);
options.playback_rect = options.full_raster_rect;
- options.background_color = SK_ColorTRANSPARENT;
+ options.background_color = SkColors::kTransparent;
float arbitrary_scale = 3.7f;
options.post_scale = arbitrary_scale;
options.requires_clear = true;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Note that clearing of the tile should supersede any early outs due to an
// empty display list. This is due to the fact that partial raster may in fact
@@ -1334,7 +1336,7 @@ TEST_F(OopPixelTest, ClearingTransparentInternalTile) {
SkBitmap::kZeroPixels_AllocFlag);
SkCanvas canvas(bitmap, SkSurfaceProps{});
- canvas.drawColor(SK_ColorTRANSPARENT);
+ canvas.drawColor(SkColors::kTransparent);
ExpectEquals(oop_result, bitmap);
}
@@ -1348,12 +1350,12 @@ TEST_F(OopPixelTest, ClearingTransparentCornerPartialRaster) {
options.full_raster_rect.bottom());
options.playback_rect =
gfx::Rect(arbitrary_offset.x() + 5, arbitrary_offset.y() + 3, 2, 4);
- options.background_color = SK_ColorTRANSPARENT;
+ options.background_color = SkColors::kTransparent;
float arbitrary_scale = 0.23f;
options.post_scale = arbitrary_scale;
options.requires_clear = true;
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
// Make a non-empty but noop display list to avoid early outs.
auto display_item_list = MakeNoopDisplayItemList();
@@ -1372,7 +1374,7 @@ TEST_F(OopPixelTest, ClearingTransparentCornerPartialRaster) {
canvas.drawColor(options.preclear_color);
canvas.translate(-arbitrary_offset.x(), -arbitrary_offset.y());
canvas.clipRect(gfx::RectToSkRect(options.playback_rect));
- canvas.drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+ canvas.drawColor(SkColors::kTransparent, SkBlendMode::kSrc);
ExpectEquals(oop_result, bitmap);
}
@@ -1395,7 +1397,7 @@ TEST_F(OopPixelTest, DrawRectPlaybackRect) {
options.content_size = gfx::Size(options.full_raster_rect.right(),
options.full_raster_rect.bottom());
options.playback_rect = gfx::Rect(4, 2, 5, 6);
- options.background_color = SK_ColorMAGENTA;
+ options.background_color = SkColors::kMagenta;
auto actual = Raster(display_item_list, options);
ExpectEquals(actual, FILE_PATH_LITERAL("oop_draw_rect_playback_rect.png"));
@@ -1423,7 +1425,7 @@ TEST_F(OopPixelTest, DrawRectScaleTransformOptions) {
options.content_size = {25, 25};
options.full_raster_rect = {5, 5, 20, 20};
options.playback_rect = {5, 5, 13, 9};
- options.background_color = SK_ColorCYAN;
+ options.background_color = SkColors::kCyan;
options.post_translate = {0.5f, 0.25f};
options.post_scale = 2.f;
@@ -1455,13 +1457,14 @@ TEST_F(OopPixelTest, DrawRectTransformOptionsFullRaster) {
options.full_raster_rect = {5, 5, 20, 20};
options.playback_rect = {5, 5, 20, 20};
options.preclear = true;
- options.preclear_color = SK_ColorRED;
+ options.preclear_color = SkColors::kRed;
options.post_translate = {0.5f, 0.25f};
options.post_scale = 2.f;
auto actual = Raster(display_item_list, options);
- auto expected = MakeSolidColorBitmap(options.resource_size,
- SkColorSetARGB(255, 64, 128, 32));
+ auto expected = MakeSolidColorBitmap(
+ options.resource_size,
+ SkColor4f::FromColor(SkColorSetARGB(255, 64, 128, 32)));
ExpectEquals(actual, expected);
}
@@ -1490,7 +1493,7 @@ TEST_F(OopPixelTest, DrawRectQueryMiddleOfDisplayList) {
options.content_size = {20, 20};
options.full_raster_rect = {0, 10, 1, 10};
options.playback_rect = {0, 10, 1, 10};
- options.background_color = SK_ColorGRAY;
+ options.background_color = SkColors::kGray;
options.post_translate = {0.f, 0.f};
options.post_scale = 2.f;
@@ -1511,14 +1514,15 @@ TEST_F(OopPixelTest, DrawRectColorSpace) {
display_item_list->StartPaint();
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
+ flags.setColor(SkColors::kGreen);
display_item_list->push<DrawRectOp>(
gfx::RectToSkRect(gfx::Rect(options.resource_size)), flags);
display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
display_item_list->Finalize();
- SkBitmap expected = MakeSolidColorBitmap(options.resource_size,
- SkColorSetARGB(255, 117, 251, 76));
+ SkBitmap expected = MakeSolidColorBitmap(
+ options.resource_size,
+ SkColor4f::FromColor(SkColorSetARGB(255, 117, 251, 76)));
auto actual = Raster(display_item_list, options);
ExpectEquals(actual, expected);
@@ -1730,7 +1734,7 @@ class OopTextBlobPixelTest
kTopLeft_GrSurfaceOrigin, &surface_props);
SkCanvas* canvas = surface->getCanvas();
- canvas->clear(SK_ColorBLACK);
+ canvas->clear(SkColors::kBlack);
DrawExpectedToCanvas(*canvas);
surface->flushAndSubmit();
@@ -1769,7 +1773,7 @@ class OopTextBlobPixelTest
}
SkPaint text_paint;
- text_paint.setColor(SK_ColorGREEN);
+ text_paint.setColor(SkColors::kGreen);
if (filter && (strategy == TextBlobStrategy::kDirect ||
strategy == TextBlobStrategy::kDrawRecord)) {
text_paint.setImageFilter(std::move(filter));
@@ -1868,7 +1872,7 @@ class OopTextBlobPixelTest
PaintFlags text_flags;
text_flags.setStyle(PaintFlags::kFill_Style);
- text_flags.setColor(SK_ColorGREEN);
+ text_flags.setColor(SkColors::kGreen);
if (filter && (strategy == TextBlobStrategy::kDirect ||
strategy == TextBlobStrategy::kDrawRecord)) {
// If there's a filter, the only PaintFlags that are available for these
@@ -2044,7 +2048,7 @@ TEST_F(OopPixelTest, DrawTextMultipleRasterCHROMIUM) {
display_item_list->StartPaint();
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
+ flags.setColor(SkColors::kGreen);
display_item_list->push<DrawTextBlobOp>(BuildTextBlob(sk_typeface_1), 0.0f,
kTextBlobY, flags);
display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
@@ -2085,7 +2089,7 @@ TEST_F(OopPixelTest, DrawTextBlobPersistentShaderCache) {
display_item_list->StartPaint();
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
+ flags.setColor(SkColors::kGreen);
display_item_list->push<DrawTextBlobOp>(BuildTextBlob(), 0.0f, kTextBlobY,
flags);
display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
@@ -2096,11 +2100,11 @@ TEST_F(OopPixelTest, DrawTextBlobPersistentShaderCache) {
// Perform the same operations on a software SkCanvas to produce an expected
// bitmap.
SkBitmap expected =
- MakeSolidColorBitmap(options.resource_size, SK_ColorBLACK);
+ MakeSolidColorBitmap(options.resource_size, SkColors::kBlack);
SkCanvas canvas(expected, SkSurfaceProps{});
- canvas.drawColor(SK_ColorBLACK);
+ canvas.drawColor(SkColors::kBlack);
SkPaint paint;
- paint.setColor(SK_ColorGREEN);
+ paint.setColor(SkColors::kGreen);
canvas.drawTextBlob(BuildTextBlob(), 0, kTextBlobY, paint);
// Allow 1% of pixels to be off by 1 due to differences between software and
@@ -2254,9 +2258,9 @@ TEST_F(OopPixelTest, ReadbackImagePixels) {
expected_bitmap.allocPixels(dest_info);
SkCanvas canvas(expected_bitmap, SkSurfaceProps{});
- canvas.drawColor(SK_ColorMAGENTA);
+ canvas.drawColor(SkColors::kMagenta);
SkPaint green;
- green.setColor(SK_ColorGREEN);
+ green.setColor(SkColors::kGreen);
canvas.drawRect(SkRect::MakeXYWH(1, 2, 3, 4), green);
auto* ri = raster_context_provider_->RasterInterface();
@@ -2384,14 +2388,14 @@ class OopPathPixelTest : public OopPixelTest,
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
+ flags.setColor(SkColors::kGreen);
SkPath path;
path.addCircle(20, 20, 10);
display_item_list->push<DrawPathOp>(path, flags);
- flags.setColor(SK_ColorBLUE);
+ flags.setColor(SkColors::kBlue);
display_item_list->push<DrawRectOp>(SkRect::MakeWH(10, 10), flags);
display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
display_item_list->Finalize();
@@ -2420,10 +2424,10 @@ TEST_F(OopPixelTest, RecordShaderExceedsMaxTextureSize) {
const SkRect rect = SkRect::MakeWH(max_texture_size + 10, 10);
auto shader_record = sk_make_sp<PaintRecord>();
- shader_record->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ shader_record->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
+ flags.setColor(SkColors::kGreen);
shader_record->push<DrawRectOp>(rect, flags);
auto shader = PaintShader::MakePaintRecord(
shader_record, rect, SkTileMode::kRepeat, SkTileMode::kRepeat, nullptr);
@@ -2437,7 +2441,7 @@ TEST_F(OopPixelTest, RecordShaderExceedsMaxTextureSize) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ display_item_list->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
flags.setShader(shader);
display_item_list->push<DrawRectOp>(rect, flags);
display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
diff --git a/chromium/cc/paint/paint_filter.cc b/chromium/cc/paint/paint_filter.cc
index 50124905cd5..705aa95dabe 100644
--- a/chromium/cc/paint/paint_filter.cc
+++ b/chromium/cc/paint/paint_filter.cc
@@ -671,7 +671,8 @@ AlphaThresholdPaintFilter::~AlphaThresholdPaintFilter() = default;
size_t AlphaThresholdPaintFilter::SerializedSize() const {
size_t region_size = region_.writeToMemory(nullptr);
base::CheckedNumeric<size_t> total_size;
- total_size = BaseSerializedSize() + sizeof(uint64_t) + region_size +
+ total_size = BaseSerializedSize() + sizeof(uint64_t) +
+ base::bits::AlignUp(region_size, PaintOpWriter::Alignment()) +
sizeof(inner_min_) + sizeof(outer_max_);
total_size += GetFilterSize(input_.get());
return total_size.ValueOrDefault(0u);
diff --git a/chromium/cc/paint/paint_flags.cc b/chromium/cc/paint/paint_flags.cc
index 29918c7a796..c80d3cc0680 100644
--- a/chromium/cc/paint/paint_flags.cc
+++ b/chromium/cc/paint/paint_flags.cc
@@ -144,7 +144,7 @@ SkPaint PaintFlags::ToSkPaint() const {
paint.setColorFilter(color_filter_);
if (image_filter_)
paint.setImageFilter(image_filter_->cached_sk_filter_);
- paint.setColor4f(color_);
+ paint.setColor(color_);
paint.setStrokeWidth(width_);
paint.setStrokeMiter(miter_limit_);
paint.setBlendMode(getBlendMode());
diff --git a/chromium/cc/paint/paint_flags.h b/chromium/cc/paint/paint_flags.h
index d3a850d2417..537c13f9b2c 100644
--- a/chromium/cc/paint/paint_flags.h
+++ b/chromium/cc/paint/paint_flags.h
@@ -41,12 +41,13 @@ class CC_PAINT_EXPORT PaintFlags {
return static_cast<Style>(bitfields_.style_);
}
ALWAYS_INLINE void setStyle(Style style) { bitfields_.style_ = style; }
+ // TODO(crbug.com/1308932): Remove this function
ALWAYS_INLINE SkColor getColor() const { return color_.toSkColor(); }
ALWAYS_INLINE SkColor4f getColor4f() const { return color_; }
ALWAYS_INLINE void setColor(SkColor color) {
color_ = SkColor4f::FromColor(color);
}
- ALWAYS_INLINE void setColor4f(SkColor4f color) { color_ = color; }
+ ALWAYS_INLINE void setColor(SkColor4f color) { color_ = color; }
ALWAYS_INLINE uint8_t getAlpha() const {
return SkColorGetA(color_.toSkColor());
}
@@ -205,7 +206,7 @@ class CC_PAINT_EXPORT PaintFlags {
// Match(ish) SkPaint defaults. SkPaintDefaults is not public, so this
// just uses these values and ignores any SkUserConfig overrides.
- SkColor4f color_ = SkColor4f::FromColor(SK_ColorBLACK);
+ SkColor4f color_ = SkColors::kBlack;
float width_ = 0.f;
float miter_limit_ = 4.f;
uint32_t blend_mode_ = static_cast<uint32_t>(SkBlendMode::kSrcOver);
diff --git a/chromium/cc/paint/paint_image_unittest.cc b/chromium/cc/paint/paint_image_unittest.cc
index 45103e503d7..66289c6c32d 100644
--- a/chromium/cc/paint/paint_image_unittest.cc
+++ b/chromium/cc/paint/paint_image_unittest.cc
@@ -35,7 +35,7 @@ TEST(PaintImageTest, DecodesCorrectFrames) {
SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
std::vector<size_t> memory(info.computeMinByteSize());
image.Decode(memory.data(), &info, nullptr, 1u,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
generator->reset_frames_decoded();
@@ -44,7 +44,7 @@ TEST(PaintImageTest, DecodesCorrectFrames) {
info.makeColorType(kRGB_565_SkColorType);
memory = std::vector<size_t>(info.computeMinByteSize());
image.Decode(memory.data(), &info, nullptr, 1u,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
generator->reset_frames_decoded();
@@ -99,7 +99,7 @@ TEST(PaintImageTest, DecodeToYuv420NoAlpha) {
ASSERT_EQ(yuva_pixmap_info, image_yuva_pixmap_info);
image.DecodeYuv(pixmaps, 1u /* frame_index */,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
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 683420ef063..1081d238920 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -84,6 +84,42 @@ SkRect MapRect(const SkMatrix& matrix, const SkRect& src) {
matrix.mapRect(&dst, src);
return dst;
}
+
+void DrawImageRect(SkCanvas* canvas,
+ const SkImage* image,
+ const SkRect& src,
+ const SkRect& dst,
+ const SkSamplingOptions& options,
+ const SkPaint* paint,
+ SkCanvas::SrcRectConstraint constraint) {
+ if (!image)
+ return;
+ if (constraint == SkCanvas::kStrict_SrcRectConstraint &&
+ options.mipmap != SkMipmapMode::kNone &&
+ src.contains(SkRect::Make(image->dimensions()))) {
+ SkMatrix m;
+ m.setRectToRect(src, dst, SkMatrix::ScaleToFit::kFill_ScaleToFit);
+ canvas->save();
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, options, paint);
+ canvas->restore();
+ return;
+ }
+ canvas->drawImageRect(image, src, dst, options, paint, constraint);
+}
+
+bool GrSlugAreEqual(sk_sp<GrSlug> left, sk_sp<GrSlug> right) {
+ if (!left && !right) {
+ return true;
+ }
+ if (left && right) {
+ auto left_data = left->serialize();
+ auto right_data = right->serialize();
+ return left_data->equals(right_data.get());
+ }
+ return false;
+}
+
} // namespace
#define TYPES(M) \
@@ -350,8 +386,7 @@ PlaybackParams::PlaybackParams(ImageProvider* image_provider,
: image_provider(image_provider),
original_ctm(original_ctm),
custom_callback(custom_callback),
- did_draw_op_callback(did_draw_op_callback),
- raw_draw_analysis(false) {}
+ did_draw_op_callback(did_draw_op_callback) {}
PlaybackParams::~PlaybackParams() {}
@@ -368,8 +403,7 @@ PaintOp::SerializeOptions::SerializeOptions(
SkottieSerializationHistory* skottie_serialization_history,
bool can_use_lcd_text,
bool context_supports_distance_field_text,
- int max_texture_size,
- bool raw_draw)
+ int max_texture_size)
: image_provider(image_provider),
transfer_cache(transfer_cache),
paint_cache(paint_cache),
@@ -379,8 +413,7 @@ PaintOp::SerializeOptions::SerializeOptions(
can_use_lcd_text(can_use_lcd_text),
context_supports_distance_field_text(
context_supports_distance_field_text),
- max_texture_size(max_texture_size),
- raw_draw(raw_draw) {}
+ max_texture_size(max_texture_size) {}
PaintOp::SerializeOptions::SerializeOptions() = default;
PaintOp::SerializeOptions::SerializeOptions(const SerializeOptions&) = default;
@@ -538,7 +571,7 @@ size_t DrawImageOp::Serialize(const PaintOp* base_op,
helper.Write(
CreateDrawImage(op->image, flags_to_serialize, op->sampling, current_ctm),
&scale_adjustment);
- helper.AlignMemory(alignof(SkScalar));
+ helper.AssertAlignment(alignof(SkScalar));
helper.Write(scale_adjustment.width());
helper.Write(scale_adjustment.height());
@@ -569,7 +602,7 @@ size_t DrawImageRectOp::Serialize(const PaintOp* base_op,
helper.Write(
CreateDrawImage(op->image, flags_to_serialize, op->sampling, matrix),
&scale_adjustment);
- helper.AlignMemory(alignof(SkScalar));
+ helper.AssertAlignment(alignof(SkScalar));
helper.Write(scale_adjustment.width());
helper.Write(scale_adjustment.height());
@@ -608,7 +641,7 @@ size_t DrawLineOp::Serialize(const PaintOp* base_op,
if (!flags_to_serialize)
flags_to_serialize = &op->flags;
helper.Write(*flags_to_serialize, current_ctm);
- helper.AlignMemory(alignof(SkScalar));
+ helper.AssertAlignment(alignof(SkScalar));
helper.Write(op->x0);
helper.Write(op->y0);
helper.Write(op->x1);
@@ -717,11 +750,14 @@ void SerializeSkottieFrameData(const SkM44& current_ctm,
// |scale_adjustment| is not ultimately used; Skottie handles image
// scale adjustment internally when rastering.
SkSize scale_adjustment = SkSize::MakeEmpty();
- helper.Write(DrawImage(frame_data.image, /*use_dark_mode=*/false,
- SkIRect::MakeWH(frame_data.image.width(),
- frame_data.image.height()),
- frame_data.quality, current_ctm),
- &scale_adjustment);
+ DrawImage draw_image;
+ if (frame_data.image) {
+ draw_image = DrawImage(
+ frame_data.image, /*use_dark_mode=*/false,
+ SkIRect::MakeWH(frame_data.image.width(), frame_data.image.height()),
+ frame_data.quality, current_ctm);
+ }
+ helper.Write(draw_image, &scale_adjustment);
helper.Write(frame_data.quality);
}
@@ -783,18 +819,11 @@ size_t DrawTextBlobOp::Serialize(const PaintOp* base_op,
if (!flags_to_serialize)
flags_to_serialize = &op->flags;
helper.Write(*flags_to_serialize, current_ctm);
- helper.AlignMemory(alignof(SkScalar));
- helper.Write(op->x);
- helper.Write(op->y);
- unsigned int count = options.raw_draw ? (op->extra_slugs.size() + 1) : 0;
+ unsigned int count = op->extra_slugs.size() + 1;
helper.Write(count);
- if (options.raw_draw) {
- helper.Write(op->slug);
- for (const auto& slug : op->extra_slugs) {
- helper.Write(slug);
- }
- } else {
- helper.Write(op->blob);
+ helper.Write(op->slug);
+ for (const auto& slug : op->extra_slugs) {
+ helper.Write(slug);
}
return helper.size();
}
@@ -988,7 +1017,7 @@ class PaintOpDeserializer {
void ReadSize(size_t* size) { reader_.ReadSize(size); }
- void AlignMemory(size_t alignment) { reader_.AlignMemory(alignment); }
+ void AssertAlignment(size_t alignment) { reader_.AssertAlignment(alignment); }
private:
PaintOpReader reader_;
@@ -1115,7 +1144,7 @@ PaintOp* DrawImageOp::Deserialize(const volatile void* input,
deserializer.Read(&deserializer->flags);
deserializer.Read(&deserializer->image);
- deserializer.AlignMemory(alignof(SkScalar));
+ deserializer.AssertAlignment(alignof(SkScalar));
deserializer.Read(&deserializer->scale_adjustment.fWidth);
deserializer.Read(&deserializer->scale_adjustment.fHeight);
@@ -1136,7 +1165,7 @@ PaintOp* DrawImageRectOp::Deserialize(const volatile void* input,
deserializer.Read(&deserializer->flags);
deserializer.Read(&deserializer->image);
- deserializer.AlignMemory(alignof(SkScalar));
+ deserializer.AssertAlignment(alignof(SkScalar));
deserializer.Read(&deserializer->scale_adjustment.fWidth);
deserializer.Read(&deserializer->scale_adjustment.fHeight);
@@ -1169,7 +1198,7 @@ PaintOp* DrawLineOp::Deserialize(const volatile void* input,
PaintOpDeserializer<DrawLineOp> deserializer(input, input_size, options,
new (output) DrawLineOp);
deserializer.Read(&deserializer->flags);
- deserializer.AlignMemory(alignof(SkScalar));
+ deserializer.AssertAlignment(alignof(SkScalar));
deserializer.Read(&deserializer->x0);
deserializer.Read(&deserializer->y0);
deserializer.Read(&deserializer->x1);
@@ -1284,9 +1313,6 @@ absl::optional<SkottieFrameData> DeserializeSkottieFrameData(
PaintOpDeserializer<DrawSkottieOp>& deserializer) {
SkottieFrameData frame_data;
deserializer.Read(&frame_data.image);
- if (!frame_data.image)
- return absl::nullopt;
-
deserializer.Read(&frame_data.quality);
return frame_data;
}
@@ -1359,19 +1385,12 @@ PaintOp* DrawTextBlobOp::Deserialize(const volatile void* input,
PaintOpDeserializer<DrawTextBlobOp> deserializer(input, input_size, options,
new (output) DrawTextBlobOp);
deserializer.Read(&deserializer->flags);
- deserializer.AlignMemory(alignof(SkScalar));
- deserializer.Read(&deserializer->x);
- deserializer.Read(&deserializer->y);
unsigned int count = 0;
deserializer.Read(&count);
- if (count) {
- deserializer.Read(&deserializer->slug);
- deserializer->extra_slugs.resize(count - 1);
- for (auto& slug : deserializer->extra_slugs) {
- deserializer.Read(&slug);
- }
- } else {
- deserializer.Read(&deserializer->blob);
+ deserializer.Read(&deserializer->slug);
+ deserializer->extra_slugs.resize(count - 1);
+ for (auto& slug : deserializer->extra_slugs) {
+ deserializer.Read(&slug);
}
return deserializer.FinalizeOp();
}
@@ -1661,8 +1680,8 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
}
if (!sk_image)
sk_image = op->image.GetSwSkImage();
- c->drawImageRect(sk_image.get(), adjusted_src, op->dst, op->sampling, &p,
- op->constraint);
+ DrawImageRect(c, sk_image.get(), adjusted_src, op->dst, op->sampling, &p,
+ op->constraint);
});
return;
}
@@ -1695,8 +1714,8 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
const SkPaint& p) {
SkSamplingOptions options = PaintFlags::FilterQualityToSkSamplingOptions(
decoded_image.filter_quality());
- c->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst,
- options, &p, op->constraint);
+ DrawImageRect(c, decoded_image.image().get(), adjusted_src, op->dst,
+ options, &p, op->constraint);
});
}
@@ -1788,7 +1807,9 @@ SkottieWrapper::FrameDataFetchResult DrawSkottieOp::GetImageAssetForRaster(
return SkottieWrapper::FrameDataFetchResult::NO_UPDATE;
const SkottieFrameData& frame_data = images_iter->second;
- if (params.image_provider) {
+ if (!frame_data.image) {
+ sk_image = nullptr;
+ } else if (params.image_provider) {
// There is no use case for applying dark mode filters to skottie images
// currently.
DrawImage draw_image(
@@ -1808,8 +1829,6 @@ SkottieWrapper::FrameDataFetchResult DrawSkottieOp::GetImageAssetForRaster(
if (!sk_image)
sk_image = frame_data.image.GetSwSkImage();
}
- DCHECK(sk_image) << "Failed to fetch SkImage for Skottie image asset "
- << asset_id;
sampling_out =
PaintFlags::FilterQualityToSkSamplingOptions(frame_data.quality);
return SkottieWrapper::FrameDataFetchResult::NEW_DATA_AVAILABLE;
@@ -1825,7 +1844,7 @@ void DrawTextBlobOp::RasterWithFlags(const DrawTextBlobOp* op,
// The PaintOpBuffer could be rasterized with different global matrix. It is
// used for over scall on Android. So we cannot reuse slugs, they have to be
// recreated.
- if (params.raw_draw_analysis) {
+ if (params.is_analyzing) {
const_cast<DrawTextBlobOp*>(op)->slug.reset();
const_cast<DrawTextBlobOp*>(op)->extra_slugs.clear();
}
@@ -1836,7 +1855,7 @@ void DrawTextBlobOp::RasterWithFlags(const DrawTextBlobOp* op,
flags->DrawToSk(canvas, [op, &params, &i](SkCanvas* c, const SkPaint& p) {
if (op->blob) {
c->drawTextBlob(op->blob.get(), op->x, op->y, p);
- if (params.raw_draw_analysis) {
+ if (params.is_analyzing) {
auto s = GrSlug::ConvertBlob(c, *op->blob, {op->x, op->y}, p);
if (i == 0) {
const_cast<DrawTextBlobOp*>(op)->slug = std::move(s);
@@ -1845,7 +1864,7 @@ void DrawTextBlobOp::RasterWithFlags(const DrawTextBlobOp* op,
}
}
} else if (i < 1 + op->extra_slugs.size()) {
- DCHECK(!params.raw_draw_analysis);
+ DCHECK(!params.is_analyzing);
const auto& draw_slug = i == 0 ? op->slug : op->extra_slugs[i - 1];
if (draw_slug)
draw_slug->draw(c);
@@ -2310,10 +2329,7 @@ bool DrawTextBlobOp::AreEqual(const PaintOp* base_left,
return false;
if (left->node_id != right->node_id)
return false;
-
- SkSerialProcs default_procs;
- return left->blob->serialize(default_procs)
- ->equals(right->blob->serialize(default_procs).get());
+ return GrSlugAreEqual(left->slug, right->slug);
}
bool NoopOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) {
@@ -2995,7 +3011,7 @@ PaintOpBuffer::PlaybackFoldingIterator::PlaybackFoldingIterator(
const PaintOpBuffer* buffer,
const std::vector<size_t>* offsets)
: iter_(buffer, offsets),
- folded_draw_color_(SK_ColorTRANSPARENT, SkBlendMode::kSrcOver) {
+ folded_draw_color_(SkColors::kTransparent, SkBlendMode::kSrcOver) {
DCHECK(!buffer->are_ops_destroyed());
FindNextOp();
}
@@ -3042,10 +3058,9 @@ void PaintOpBuffer::PlaybackFoldingIterator::FindNextOp() {
static_cast<const DrawColorOp*>(draw_op)->mode ==
SkBlendMode::kSrcOver) {
auto* draw_color_op = static_cast<const DrawColorOp*>(draw_op);
- SkColor color = draw_color_op->color;
- folded_draw_color_.color = SkColorSetARGB(
- SkMulDiv255Round(save_op->alpha, SkColorGetA(color)),
- SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
+ SkColor4f color = draw_color_op->color;
+ folded_draw_color_.color = {color.fR, color.fG, color.fB,
+ save_op->alpha / 255 * color.fA};
current_op_ = &folded_draw_color_;
break;
}
@@ -3108,6 +3123,7 @@ void PaintOpBuffer::Playback(SkCanvas* canvas,
params.did_draw_op_callback);
new_params.save_layer_alpha_should_preserve_lcd_text =
save_layer_alpha_should_preserve_lcd_text;
+ new_params.is_analyzing = params.is_analyzing;
for (PlaybackFoldingIterator iter(this, offsets); iter; ++iter) {
const PaintOp* op = *iter;
diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h
index 1fb68e9240f..37f9aaad81c 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -35,9 +35,9 @@
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPath.h"
+#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "ui/gfx/geometry/rect.h"
@@ -145,13 +145,13 @@ struct CC_PAINT_EXPORT PlaybackParams {
// `image_provider` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- ImageProvider* image_provider;
+ RAW_PTR_EXCLUSION ImageProvider* image_provider;
SkM44 original_ctm;
CustomDataRasterCallback custom_callback;
DidDrawOpCallback did_draw_op_callback;
absl::optional<bool> save_layer_alpha_should_preserve_lcd_text;
- bool raw_draw_analysis;
+ bool is_analyzing = false;
};
class CC_PAINT_EXPORT PaintOp {
@@ -184,8 +184,7 @@ class CC_PAINT_EXPORT PaintOp {
SkottieSerializationHistory* skottie_serialization_history,
bool can_use_lcd_text,
bool context_supports_distance_field_text,
- int max_texture_size,
- bool raw_draw = false);
+ int max_texture_size);
SerializeOptions(const SerializeOptions&);
SerializeOptions& operator=(const SerializeOptions&);
~SerializeOptions();
@@ -201,7 +200,6 @@ class CC_PAINT_EXPORT PaintOp {
bool can_use_lcd_text = false;
bool context_supports_distance_field_text = true;
int max_texture_size = 0;
- bool raw_draw = false;
// TODO(crbug.com/1096123): Cleanup after study completion.
//
@@ -522,7 +520,7 @@ class CC_PAINT_EXPORT DrawColorOp final : public PaintOp {
public:
static constexpr PaintOpType kType = PaintOpType::DrawColor;
static constexpr bool kIsDrawOp = true;
- DrawColorOp(SkColor color, SkBlendMode mode)
+ DrawColorOp(SkColor4f color, SkBlendMode mode)
: PaintOp(kType), color(color), mode(mode) {}
static void Raster(const DrawColorOp* op,
SkCanvas* canvas,
@@ -531,7 +529,7 @@ class CC_PAINT_EXPORT DrawColorOp final : public PaintOp {
static bool AreEqual(const PaintOp* left, const PaintOp* right);
HAS_SERIALIZATION_FUNCTIONS();
- SkColor color;
+ SkColor4f color;
SkBlendMode mode;
private:
@@ -1276,8 +1274,8 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
// `buffer_` and `ptr_` are not a raw_ptr<...> for performance reasons
// (based on analysis of sampling profiler data and tab_search:top100:2020).
- const PaintOpBuffer* buffer_ = nullptr;
- char* ptr_ = nullptr;
+ RAW_PTR_EXCLUSION const PaintOpBuffer* buffer_ = nullptr;
+ RAW_PTR_EXCLUSION char* ptr_ = nullptr;
size_t op_offset_ = 0;
};
@@ -1345,9 +1343,9 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
// `buffer_`, `ptr_`, and `offsets_` are not a raw_ptr<...> for performance
// reasons (based on analysis of sampling profiler data and
// tab_search:top100:2020).
- const PaintOpBuffer* buffer_ = nullptr;
- char* ptr_ = nullptr;
- const std::vector<size_t>* offsets_;
+ RAW_PTR_EXCLUSION const PaintOpBuffer* buffer_ = nullptr;
+ RAW_PTR_EXCLUSION char* ptr_ = nullptr;
+ RAW_PTR_EXCLUSION const std::vector<size_t>* offsets_;
size_t op_offset_ = 0;
size_t offsets_index_ = 0;
@@ -1424,7 +1422,7 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
// `current_op_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- const PaintOp* current_op_ = nullptr;
+ RAW_PTR_EXCLUSION const PaintOp* current_op_ = nullptr;
uint8_t current_alpha_ = 255;
};
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index 9f5fd58efa0..3324ae0afaf 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -11,6 +11,7 @@
#include "base/test/test_discardable_memory_allocator.h"
#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_op_buffer.h"
+#include "cc/paint/paint_op_writer.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "components/viz/test/test_context_provider.h"
#include "gpu/command_buffer/common/buffer.h"
@@ -128,6 +129,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
uint32_t bytes_for_fonts = data[0];
if (bytes_for_fonts > size)
bytes_for_fonts = size / 2;
+ // PaintOpBuffer only accepts 4 bytes aligned buffer.
+ bytes_for_fonts =
+ base::bits::AlignDown(bytes_for_fonts, cc::PaintOpWriter::Alignment());
FontSupport font_support;
scoped_refptr<gpu::ServiceFontManager> font_manager(
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.cc b/chromium/cc/paint/paint_op_buffer_serializer.cc
index b4e479f6634..b57a7309556 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.cc
+++ b/chromium/cc/paint/paint_op_buffer_serializer.cc
@@ -20,11 +20,11 @@
namespace cc {
namespace {
-PlaybackParams MakeParams(const SkCanvas* canvas, bool raw_draw) {
+PlaybackParams MakeParams(const SkCanvas* canvas) {
// We don't use an ImageProvider here since the ops are played onto a no-draw
// canvas for state tracking and don't need decoded images.
PlaybackParams params(nullptr, canvas->getLocalToDevice());
- params.raw_draw_analysis = raw_draw;
+ params.is_analyzing = true;
return params;
}
@@ -64,7 +64,7 @@ void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
// only used for serializing the preamble and the initial save / final restore
// SerializeBuffer will create its own PlaybackParams based on the
// post-preamble canvas.
- PlaybackParams params = MakeParams(canvas.get(), options_.raw_draw);
+ PlaybackParams params = MakeParams(canvas.get());
int saveCount = canvas->getSaveCount();
Save(canvas.get(), params);
@@ -83,7 +83,7 @@ void PaintOpBufferSerializer::SerializeAndDestroy(
// only used for serializing the preamble and the initial save / final restore
// SerializeBuffer will create its own PlaybackParams based on the
// post-preamble canvas.
- PlaybackParams params = MakeParams(canvas.get(), options_.raw_draw);
+ PlaybackParams params = MakeParams(canvas.get());
int saveCount = canvas->getSaveCount();
Save(canvas.get(), params);
@@ -102,7 +102,7 @@ void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
const gfx::SizeF& post_scale) {
std::unique_ptr<SkCanvas> canvas = MakeAnalysisCanvas(options_);
- PlaybackParams params = MakeParams(canvas.get(), options_.raw_draw);
+ PlaybackParams params = MakeParams(canvas.get());
// TODO(khushalsagar): remove this clip rect if it's not needed.
if (!playback_rect.IsEmpty()) {
@@ -142,7 +142,8 @@ void PaintOpBufferSerializer::ClearForOpaqueRaster(
SkClipOp::kDifference, false);
SerializeOp(canvas, &inner_clip_op, nullptr, params);
}
- DrawColorOp clear_op(preamble.background_color, SkBlendMode::kSrc);
+ DrawColorOp clear_op(SkColor4f::FromColor(preamble.background_color),
+ SkBlendMode::kSrc);
SerializeOp(canvas, &clear_op, nullptr, params);
RestoreToCount(canvas, 1, params);
}
@@ -165,7 +166,7 @@ void PaintOpBufferSerializer::SerializePreamble(SkCanvas* canvas,
// There's not enough information at this point to know if this texture is
// being reused from another tile, so the external texels could have been
// cleared to some wrong value.
- DrawColorOp clear(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+ DrawColorOp clear(SkColors::kTransparent, SkBlendMode::kSrc);
SerializeOp(canvas, &clear, nullptr, params);
}
@@ -196,7 +197,7 @@ void PaintOpBufferSerializer::SerializePreamble(SkCanvas* canvas,
// section that is being rastered. If this is opaque, trust the raster
// to write all the pixels inside of the full_raster_rect.
if (preamble.requires_clear && is_partial_raster) {
- DrawColorOp clear_op(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+ DrawColorOp clear_op(SkColors::kTransparent, SkBlendMode::kSrc);
SerializeOp(canvas, &clear_op, nullptr, params);
}
}
@@ -277,7 +278,7 @@ void PaintOpBufferSerializer::SerializeBuffer(
DCHECK(buffer);
// This updates the original_ctm to reflect the canvas transformation at
// start of this call to SerializeBuffer.
- PlaybackParams params = MakeParams(canvas, options_.raw_draw);
+ PlaybackParams params = MakeParams(canvas);
for (PaintOpBuffer::PlaybackFoldingIterator iter(buffer, offsets); iter;
++iter) {
@@ -295,7 +296,7 @@ void PaintOpBufferSerializer::SerializeBufferAndDestroy(
DCHECK(buffer);
// This updates the original_ctm to reflect the canvas transformation at
// start of this call to SerializeBuffer.
- PlaybackParams params = MakeParams(canvas, options_.raw_draw);
+ PlaybackParams params = MakeParams(canvas);
bool destroy_op_only = false;
for (PaintOpBuffer::PlaybackFoldingIterator iter(buffer, offsets); iter;
diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc
index 460f28d8251..802675a4d1c 100644
--- a/chromium/cc/paint/paint_op_buffer_unittest.cc
+++ b/chromium/cc/paint/paint_op_buffer_unittest.cc
@@ -158,7 +158,7 @@ class PaintOpAppendTest : public ::testing::Test {
private:
SkRect rect_;
PaintFlags flags_;
- SkColor draw_color_ = SK_ColorRED;
+ SkColor4f draw_color_ = SkColors::kRed;
SkBlendMode blend_ = SkBlendMode::kSrc;
};
@@ -433,7 +433,8 @@ TEST(PaintOpBufferTest, SaveLayerRestore_DrawColor) {
SkColor original = SkColorSetA(50, SK_ColorRED);
buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
- buffer.push<DrawColorOp>(original, SkBlendMode::kSrcOver);
+ buffer.push<DrawColorOp>(SkColor4f::FromColor(original),
+ SkBlendMode::kSrcOver);
buffer.push<RestoreOp>();
SaveCountingCanvas canvas;
@@ -732,11 +733,11 @@ TEST_F(PaintOpBufferOffsetsTest, EmptyClipRectShouldRejectAnOp) {
TEST_F(PaintOpBufferOffsetsTest, ContiguousIndices) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Plays all items.
testing::Sequence s;
@@ -751,11 +752,11 @@ TEST_F(PaintOpBufferOffsetsTest, ContiguousIndices) {
TEST_F(PaintOpBufferOffsetsTest, NonContiguousIndices) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Plays 0, 1, 3, 4 indices.
testing::Sequence s;
@@ -769,11 +770,11 @@ TEST_F(PaintOpBufferOffsetsTest, NonContiguousIndices) {
TEST_F(PaintOpBufferOffsetsTest, FirstTwoIndices) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Plays first two indices.
testing::Sequence s;
@@ -785,11 +786,11 @@ TEST_F(PaintOpBufferOffsetsTest, FirstTwoIndices) {
TEST_F(PaintOpBufferOffsetsTest, MiddleIndex) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Plays index 2.
testing::Sequence s;
@@ -800,11 +801,11 @@ TEST_F(PaintOpBufferOffsetsTest, MiddleIndex) {
TEST_F(PaintOpBufferOffsetsTest, LastTwoElements) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Plays last two elements.
testing::Sequence s;
@@ -816,14 +817,14 @@ TEST_F(PaintOpBufferOffsetsTest, LastTwoElements) {
TEST_F(PaintOpBufferOffsetsTest, ContiguousIndicesWithSaveLayerAlphaRestore) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
uint8_t alpha = 100;
push_op<SaveLayerAlphaOp>(nullptr, alpha);
push_op<RestoreOp>();
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Items are {0, 1, save, restore, 2, 3, 4}.
@@ -842,14 +843,14 @@ TEST_F(PaintOpBufferOffsetsTest,
NonContiguousIndicesWithSaveLayerAlphaRestore) {
testing::StrictMock<MockCanvas> canvas;
- push_op<DrawColorOp>(0u, SkBlendMode::kClear);
- push_op<DrawColorOp>(1u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
uint8_t alpha = 100;
push_op<SaveLayerAlphaOp>(nullptr, alpha);
- push_op<DrawColorOp>(2u, SkBlendMode::kClear);
- push_op<DrawColorOp>(3u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
push_op<RestoreOp>();
- push_op<DrawColorOp>(4u, SkBlendMode::kClear);
+ push_op<DrawColorOp>(SkColor4f::FromColor(4u), SkBlendMode::kClear);
// Items are {0, 1, save, 2, 3, restore, 4}.
@@ -1205,10 +1206,9 @@ std::vector<PaintFlags> test_flags = {
PaintFlags(),
};
-std::vector<SkColor> test_colors = {
- SkColorSetARGB(0, 0, 0, 0), SkColorSetARGB(255, 255, 255, 255),
- SkColorSetARGB(0, 255, 10, 255), SkColorSetARGB(255, 0, 20, 255),
- SkColorSetARGB(30, 255, 0, 255), SkColorSetARGB(255, 40, 0, 0),
+std::vector<SkColor4f> test_colors = {
+ {0, 0, 0, 0}, {1, 1, 1, 1}, {1, 0.04, 1, 0},
+ {0, 0.08, 1, 1}, {1, 0, 1, 0.12}, {0.16, 0, 0, 1},
};
std::vector<std::string> test_strings = {
@@ -1547,10 +1547,23 @@ SkottieFrameDataMap GetTestImagesForSkottie(SkottieWrapper& skottie,
return images;
}
+SkottieFrameDataMap GetNullImagesForSkottie(SkottieWrapper& skottie, float t) {
+ SkottieFrameDataMap images;
+ skottie.Seek(
+ t, base::BindLambdaForTesting(
+ [&](SkottieResourceIdHash asset_id, float t_frame,
+ sk_sp<SkImage>& image_out, SkSamplingOptions& sampling_out) {
+ images[asset_id] = SkottieFrameData();
+ return SkottieWrapper::FrameDataFetchResult::NO_UPDATE;
+ }));
+ return images;
+}
+
void PushDrawSkottieOps(PaintOpBuffer* buffer) {
std::vector<scoped_refptr<SkottieWrapper>> test_skotties;
std::vector<float> test_skottie_floats;
std::vector<SkRect> test_skottie_rects;
+ std::vector<SkottieFrameDataMap> test_skottie_images;
std::vector<SkottieColorMap> test_skottie_color_maps;
std::vector<SkottieTextPropertyValueMap> test_skottie_text_maps;
if (kIsSkottieSupported) {
@@ -1559,12 +1572,22 @@ void PushDrawSkottieOps(PaintOpBuffer* buffer) {
CreateSkottie(gfx::Size(100, 40), 5),
CreateSkottie(gfx::Size(80, 70), 6),
CreateSkottieFromString(kLottieDataWith2Assets),
+ CreateSkottieFromString(kLottieDataWith2Assets),
CreateSkottieFromTestDataDir(kLottieDataWith2TextFileName)};
- test_skottie_floats = {0, 0.1f, 1.f, 0.2f, 0.3f};
+ test_skottie_floats = {0, 0.1f, 1.f, 0.2f, 0.2f, 0.3f};
test_skottie_rects = {
- SkRect::MakeXYWH(10, 20, 30, 40), SkRect::MakeXYWH(0, 5, 10, 20),
- SkRect::MakeXYWH(6, 0, 3, 50), SkRect::MakeXYWH(10, 10, 100, 100),
- SkRect::MakeXYWH(5, 5, 50, 50)};
+ SkRect::MakeXYWH(10, 20, 30, 40), SkRect::MakeXYWH(0, 5, 10, 20),
+ SkRect::MakeXYWH(6, 0, 3, 50), SkRect::MakeXYWH(10, 10, 100, 100),
+ SkRect::MakeXYWH(10, 10, 100, 100), SkRect::MakeXYWH(5, 5, 50, 50)};
+ test_skottie_images = {
+ SkottieFrameDataMap(),
+ SkottieFrameDataMap(),
+ SkottieFrameDataMap(),
+ GetTestImagesForSkottie(*test_skotties[3], test_skottie_rects[3],
+ PaintFlags::FilterQuality::kHigh,
+ test_skottie_floats[3]),
+ GetNullImagesForSkottie(*test_skotties[4], test_skottie_floats[4]),
+ SkottieFrameDataMap()};
test_skottie_color_maps = {
{SkottieMapColor("green", SK_ColorGREEN),
SkottieMapColor("yellow", SK_ColorYELLOW),
@@ -1573,12 +1596,14 @@ void PushDrawSkottieOps(PaintOpBuffer* buffer) {
{},
{SkottieMapColor("green", SK_ColorGREEN)},
{SkottieMapColor("transparent", SK_ColorTRANSPARENT)},
+ {},
{}};
test_skottie_text_maps = {
{},
{},
{},
{},
+ {},
{{HashSkottieResourceId(kLottieDataWith2TextNode1),
SkottieTextPropertyValue(
std::string(kLottieDataWith2TextNode1Text.data()),
@@ -1591,11 +1616,10 @@ void PushDrawSkottieOps(PaintOpBuffer* buffer) {
size_t len = std::min(test_skotties.size(), test_flags.size());
for (size_t i = 0; i < len; i++) {
- buffer->push<DrawSkottieOp>(
- test_skotties[i], test_skottie_rects[i], test_skottie_floats[i],
- GetTestImagesForSkottie(*test_skotties[i], test_skottie_rects[i],
- PaintFlags::FilterQuality::kHigh, /*t=*/0),
- test_skottie_color_maps[i], test_skottie_text_maps[i]);
+ buffer->push<DrawSkottieOp>(test_skotties[i], test_skottie_rects[i],
+ test_skottie_floats[i], test_skottie_images[i],
+ test_skottie_color_maps[i],
+ test_skottie_text_maps[i]);
}
ValidateOps<DrawSkottieOp>(buffer);
}
@@ -1797,7 +1821,8 @@ class PaintOpSerializationTest : public ::testing::TestWithParam<uint8_t> {
PushDrawSkottieOps(&buffer_);
break;
case PaintOpType::DrawTextBlob:
- PushDrawTextBlobOps(&buffer_);
+ // TODO(crbug.com/1321150): fix the test for DrawTextBlobs
+ // PushDrawTextBlobOps(&buffer_);
break;
case PaintOpType::Noop:
PushNoopOps(&buffer_);
@@ -1841,6 +1866,10 @@ class PaintOpSerializationTest : public ::testing::TestWithParam<uint8_t> {
}
bool IsTypeSupported() {
+ // TODO(crbug.com/1321150): fix the test for DrawTextBlobs
+ if (GetParamType() == PaintOpType::DrawTextBlob)
+ return false;
+
// DrawRecordOps must be flattened and are not currently serialized. All
// other types must push non-zero amounts of ops in PushTestOps.
return GetParamType() != PaintOpType::DrawRecord &&
@@ -1870,6 +1899,21 @@ TEST_P(PaintOpSerializationTest, SmokeTest) {
ResizeOutputBuffer();
SimpleSerializer serializer(output_.get(), output_size_);
+
+ auto canvas =
+ serializer.options_provider()->strike_server()->makeAnalysisCanvas(
+ 1024, 768, {}, nullptr, true);
+ PlaybackParams params(nullptr, canvas->getLocalToDevice());
+ params.is_analyzing = true;
+ buffer_.Playback(canvas.get(), params);
+
+ std::vector<uint8_t> strike_data;
+ serializer.options_provider()->strike_server()->writeStrikeData(&strike_data);
+
+ if (!strike_data.empty()) {
+ serializer.options_provider()->strike_client()->readStrikeData(
+ strike_data.data(), strike_data.size());
+ }
serializer.Serialize(buffer_);
// Expect all ops to write more than 0 bytes.
@@ -1917,6 +1961,8 @@ TEST_P(PaintOpSerializationTest, SerializationFailures) {
"%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), op_idx));
size_t expected_bytes = bytes_written[op_idx];
EXPECT_GT(expected_bytes, 0u);
+ EXPECT_EQ(expected_bytes,
+ base::bits::AlignUp(expected_bytes, PaintOpWriter::Alignment()));
// Attempt to write op into a buffer of size |i|, and only expect
// it to succeed if the buffer is large enough.
@@ -2036,6 +2082,10 @@ TEST_P(PaintOpSerializationTest, UsesOverridenFlags) {
if (!PaintOp::TypeHasFlags(GetParamType()))
return;
+ // TODO(crbug.com/1321150): fix the test for DrawTextBlobs
+ if (GetParamType() == PaintOpType::DrawTextBlob)
+ return;
+
PushTestOps(GetParamType());
ResizeOutputBuffer();
@@ -2179,7 +2229,7 @@ TEST(PaintOpSerializationTest, Preamble) {
preamble.requires_clear = true;
PaintOpBuffer buffer;
- buffer.push<DrawColorOp>(SK_ColorBLUE, SkBlendMode::kSrc);
+ buffer.push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc);
std::unique_ptr<char, base::AlignedFreeDeleter> memory(
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
@@ -2254,7 +2304,7 @@ TEST(PaintOpSerializationTest, Preamble) {
ASSERT_EQ(op->GetType(), PaintOpType::DrawColor)
<< PaintOpTypeToString(op->GetType());
const auto* draw_color_op = static_cast<const DrawColorOp*>(op);
- EXPECT_EQ(draw_color_op->color, SK_ColorTRANSPARENT);
+ EXPECT_EQ(draw_color_op->color, SkColors::kTransparent);
EXPECT_EQ(draw_color_op->mode, SkBlendMode::kSrc);
continue;
}
@@ -2464,7 +2514,7 @@ TEST(PaintOpBufferTest, PaintOpDeserialize) {
static_cast<char*>(base::AlignedAlloc(kSize, kAlign)));
PaintOpBuffer buffer;
- buffer.push<DrawColorOp>(SK_ColorMAGENTA, SkBlendMode::kSrc);
+ buffer.push<DrawColorOp>(SkColors::kMagenta, SkBlendMode::kSrc);
PaintOpBuffer::Iterator iter(&buffer);
PaintOp* op = *iter;
@@ -2580,7 +2630,7 @@ TEST(PaintOpBufferTest, ValidateSkBlendMode) {
PaintOpBuffer buffer;
// Successful first two ops.
- buffer.push<DrawColorOp>(SK_ColorMAGENTA, SkBlendMode::kDstIn);
+ buffer.push<DrawColorOp>(SkColors::kMagenta, SkBlendMode::kDstIn);
PaintFlags good_flags = test_flags[0];
good_flags.setBlendMode(SkBlendMode::kColorBurn);
buffer.push<DrawRectOp>(test_rects[0], good_flags);
@@ -2613,7 +2663,7 @@ TEST(PaintOpBufferTest, ValidateSkBlendMode) {
};
for (size_t i = 0; i < std::size(bad_modes_for_draw_color); ++i) {
- buffer.push<DrawColorOp>(SK_ColorMAGENTA, bad_modes_for_draw_color[i]);
+ buffer.push<DrawColorOp>(SkColors::kMagenta, bad_modes_for_draw_color[i]);
}
for (size_t i = 0; i < std::size(bad_modes_for_flags); ++i) {
@@ -2932,7 +2982,7 @@ TEST(PaintOpBufferTest, SkipsOpsWithFailedDecodes) {
image_flags.setShader(PaintShader::MakeImage(paint_image, SkTileMode::kRepeat,
SkTileMode::kRepeat, nullptr));
buffer.push<DrawRectOp>(SkRect::MakeXYWH(110, 110, 100, 100), image_flags);
- buffer.push<DrawColorOp>(SK_ColorRED, SkBlendMode::kSrcOver);
+ buffer.push<DrawColorOp>(SkColors::kRed, SkBlendMode::kSrcOver);
testing::StrictMock<MockCanvas> canvas;
testing::Sequence s;
@@ -3553,6 +3603,23 @@ TEST(PaintOpBufferTest, DrawSkottieOpRasterWithoutImageAssets) {
}
}
+TEST(PaintOpBufferTest, DrawSkottieOpRasterWithNullImages) {
+ scoped_refptr<SkottieWrapper> skottie =
+ CreateSkottieFromString(kLottieDataWith2Assets);
+ SkRect skottie_rect = SkRect::MakeWH(100, 100);
+
+ SkottieFrameDataMap images_in = GetNullImagesForSkottie(*skottie, /*t=*/0.1f);
+ ASSERT_FALSE(images_in.empty());
+ DrawSkottieOp skottie_op(skottie, skottie_rect, /*t=*/0.1, images_in,
+ SkottieColorMap(), SkottieTextPropertyValueMap());
+ PlaybackParams playback_params(/*image_provider=*/nullptr);
+ {
+ NiceMock<MockCanvas> canvas;
+ EXPECT_CALL(canvas, onDrawImage2(_, _, _, _, _)).Times(0);
+ DrawSkottieOp::Raster(&skottie_op, &canvas, playback_params);
+ }
+}
+
TEST(PaintOpBufferTest, DrawSkottieOpRasterWithoutImageProvider) {
scoped_refptr<SkottieWrapper> skottie =
CreateSkottieFromString(kLottieDataWith2Assets);
diff --git a/chromium/cc/paint/paint_op_helper_unittest.cc b/chromium/cc/paint/paint_op_helper_unittest.cc
index e7f7fc93768..8a4aa431d23 100644
--- a/chromium/cc/paint/paint_op_helper_unittest.cc
+++ b/chromium/cc/paint/paint_op_helper_unittest.cc
@@ -56,9 +56,11 @@ TEST(PaintOpHelper, ConcatToString) {
}
TEST(PaintOpHelper, DrawColorToString) {
- DrawColorOp op(SkColorSetARGB(11, 22, 33, 44), SkBlendMode::kSrc);
+ DrawColorOp op({0.1, 0.2, 0.3, 0.4}, SkBlendMode::kSrc);
std::string str = PaintOpHelper::ToString(&op);
- EXPECT_EQ(str, "DrawColorOp(color=rgba(22, 33, 44, 11), mode=kSrc)");
+ EXPECT_EQ(str,
+ "DrawColorOp(color=rgba(0.100000, 0.200000, 0.300000, 0.400000), "
+ "mode=kSrc)");
}
TEST(PaintOpHelper, DrawDRRectToString) {
diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc
index 39584797d3b..26278227497 100644
--- a/chromium/cc/paint/paint_op_reader.cc
+++ b/chromium/cc/paint/paint_op_reader.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <memory>
+#include <type_traits>
#include <utility>
#include <vector>
@@ -35,7 +36,6 @@
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/private/chromium/GrSlug.h"
#include "third_party/skia/include/private/chromium/SkChromeRemoteGlyphCache.h"
@@ -52,24 +52,6 @@ bool IsValidPaintShaderScalingBehavior(PaintShader::ScalingBehavior behavior) {
behavior == PaintShader::ScalingBehavior::kFixedScale;
}
-struct TypefaceCtx {
- explicit TypefaceCtx(SkStrikeClient* client) : client(client) {}
- bool invalid_typeface = false;
- raw_ptr<SkStrikeClient> client = nullptr;
-};
-
-sk_sp<SkTypeface> DeserializeTypeface(const void* data,
- size_t length,
- void* ctx) {
- auto* typeface_ctx = static_cast<TypefaceCtx*>(ctx);
- auto tf = typeface_ctx->client->deserializeTypeface(data, length);
- if (tf)
- return tf;
-
- typeface_ctx->invalid_typeface = true;
- return nullptr;
-}
-
} // namespace
// static
@@ -104,15 +86,16 @@ bool PaintOpReader::ReadAndValidateOpHeader(const volatile void* input,
template <typename T>
void PaintOpReader::ReadSimple(T* val) {
- static_assert(base::is_trivially_copyable<T>::value,
- "Not trivially copyable");
+ static_assert(std::is_trivially_copyable_v<T>);
+ DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
// Align everything to 4 bytes, as the writer does.
- static constexpr size_t kAlign = 4;
- size_t size = base::bits::AlignUp(sizeof(T), kAlign);
+ static constexpr size_t size =
+ base::bits::AlignUp(sizeof(T), PaintOpWriter::Alignment());
if (remaining_bytes_ < size)
SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadSimple);
+
if (!valid_)
return;
@@ -143,38 +126,43 @@ void PaintOpReader::ReadFlattenable(
DeserializationError error_on_factory_failure) {
size_t bytes = 0;
ReadSize(&bytes);
- if (remaining_bytes_ < bytes)
+ if (remaining_bytes_ < bytes) {
SetInvalid(
DeserializationError::kInsufficientRemainingBytes_ReadFlattenable);
- if (!valid_)
return;
+ }
+
if (bytes == 0)
return;
auto* scratch = CopyScratchSpace(bytes);
val->reset(factory(scratch, bytes, nullptr).release());
- if (!val)
+ if (!val) {
SetInvalid(error_on_factory_failure);
+ return;
+ }
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ DidRead(bytes);
}
void PaintOpReader::ReadData(size_t bytes, void* data) {
- if (remaining_bytes_ < bytes)
- SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadData);
- if (!valid_)
- return;
+ DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
if (bytes == 0)
return;
+ if (remaining_bytes_ < bytes) {
+ SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadData);
+ return;
+ }
+
memcpy(data, const_cast<const char*>(memory_), bytes);
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ DidRead(bytes);
}
void PaintOpReader::ReadSize(size_t* size) {
AlignMemory(8);
+ if (!valid_)
+ return;
uint64_t size64 = 0;
ReadSimple(&size64);
*size = size64;
@@ -213,6 +201,10 @@ void PaintOpReader::Read(SkRRect* rect) {
ReadSimple(rect);
}
+void PaintOpReader::Read(SkColor4f* color) {
+ ReadSimple(color);
+}
+
void PaintOpReader::Read(SkPath* path) {
uint32_t path_id;
ReadSimple(&path_id);
@@ -260,8 +252,7 @@ void PaintOpReader::Read(SkPath* path) {
// do any caching either.
path->setIsVolatile(true);
}
- memory_ += path_bytes;
- remaining_bytes_ -= path_bytes;
+ DidRead(path_bytes);
return;
}
}
@@ -458,9 +449,7 @@ void PaintOpReader::Read(sk_sp<SkData>* data) {
// This is safe to cast away the volatile as it is just a memcpy internally.
*data = SkData::MakeWithCopy(const_cast<const char*>(memory_), bytes);
-
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ DidRead(bytes);
}
void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
@@ -477,78 +466,32 @@ void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
if (!color_space)
SetInvalid(DeserializationError::kSkColorSpaceDeserializeFailure);
- memory_ += size;
- remaining_bytes_ -= size;
+ DidRead(size);
}
+
void PaintOpReader::Read(sk_sp<GrSlug>* slug) {
- AlignMemory(4);
+ AssertAlignment(PaintOpWriter::Alignment());
size_t data_bytes = 0u;
ReadSize(&data_bytes);
-
if (data_bytes == 0) {
*slug = nullptr;
return;
}
- if (remaining_bytes_ < data_bytes)
- SetInvalid(
- DeserializationError::kInsufficientRemainingBytes_Read_SkTextBlob);
- if (!valid_)
+
+ if (remaining_bytes_ < data_bytes) {
+ SetInvalid(DeserializationError::kInsufficientRemainingBytes_Read_GrSlug);
return;
+ }
*slug = GrSlug::Deserialize(const_cast<const char*>(memory_), data_bytes,
options_.strike_client);
- memory_ += data_bytes;
- remaining_bytes_ -= data_bytes;
-}
+ DidRead(data_bytes);
-void PaintOpReader::Read(sk_sp<SkTextBlob>* blob) {
- AlignMemory(4);
- uint32_t blob_id = 0u;
- Read(&blob_id);
- if (!valid_)
- return;
-
- size_t data_bytes = 0u;
- ReadSize(&data_bytes);
- if (remaining_bytes_ < data_bytes)
- SetInvalid(
- DeserializationError::kInsufficientRemainingBytes_Read_SkTextBlob);
- if (!valid_)
- return;
-
- if (data_bytes == 0u) {
- auto cached_blob = options_.paint_cache->GetTextBlob(blob_id);
- if (!cached_blob) {
- SetInvalid(DeserializationError::kMissingPaintCacheTextBlobEntry);
- return;
- }
-
- *blob = std::move(cached_blob);
- return;
- }
-
- DCHECK(options_.strike_client);
- SkDeserialProcs procs;
- TypefaceCtx typeface_ctx(options_.strike_client);
- procs.fTypefaceProc = &DeserializeTypeface;
- procs.fTypefaceCtx = &typeface_ctx;
- auto* scratch = CopyScratchSpace(data_bytes);
- sk_sp<SkTextBlob> deserialized_blob =
- SkTextBlob::Deserialize(scratch, data_bytes, procs);
- if (!deserialized_blob) {
- SetInvalid(DeserializationError::kSkTextBlobDeserializeFailure);
- return;
- }
- if (typeface_ctx.invalid_typeface) {
- SetInvalid(DeserializationError::kInvalidTypeface);
+ if (!*slug) {
+ SetInvalid(DeserializationError::kGrSlugDeserializeFailure);
return;
}
- options_.paint_cache->PutTextBlob(blob_id, deserialized_blob);
-
- *blob = std::move(deserialized_blob);
- memory_ += data_bytes;
- remaining_bytes_ -= data_bytes;
}
void PaintOpReader::Read(sk_sp<PaintShader>* shader) {
@@ -781,8 +724,7 @@ void PaintOpReader::Read(scoped_refptr<SkottieWrapper>* skottie) {
valid_ = false;
return;
}
- memory_ += bytes_to_skip;
- remaining_bytes_ -= bytes_to_skip;
+ DidRead(bytes_to_skip);
}
void PaintOpReader::AlignMemory(size_t alignment) {
@@ -819,8 +761,7 @@ const volatile void* PaintOpReader::ExtractReadableMemory(size_t bytes) {
return nullptr;
const volatile void* extracted_memory = memory_;
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ DidRead(bytes);
return extracted_memory;
}
@@ -844,7 +785,7 @@ void PaintOpReader::Read(sk_sp<PaintFilter>* filter) {
crop_rect.emplace(rect);
}
- AlignMemory(4);
+ AssertAlignment(PaintOpWriter::Alignment());
switch (type) {
case PaintFilter::Type::kNullFilter:
NOTREACHED();
@@ -1466,8 +1407,7 @@ size_t PaintOpReader::Read(sk_sp<PaintRecord>* record) {
SetInvalid(DeserializationError::kPaintOpBufferMakeFromMemoryFailure);
return 0;
}
- memory_ += size_bytes;
- remaining_bytes_ -= size_bytes;
+ DidRead(size_bytes);
return size_bytes;
}
@@ -1489,4 +1429,13 @@ void PaintOpReader::Read(SkRegion* region) {
SetInvalid(DeserializationError::kSkRegionReadFromMemoryFailure);
}
+inline void PaintOpReader::DidRead(size_t bytes_read) {
+ // All data are aligned with PaintOpWriter::Alignment() at least.
+ size_t aligned_bytes =
+ base::bits::AlignUp(bytes_read, PaintOpWriter::Alignment());
+ memory_ += aligned_bytes;
+ DCHECK_LE(aligned_bytes, remaining_bytes_);
+ remaining_bytes_ -= aligned_bytes;
+}
+
} // namespace cc
diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h
index c5b5e6e1e08..63aabf42e95 100644
--- a/chromium/cc/paint/paint_op_reader.h
+++ b/chromium/cc/paint/paint_op_reader.h
@@ -35,11 +35,17 @@ class CC_PAINT_EXPORT PaintOpReader {
bool enable_security_constraints = false)
: memory_(static_cast<const volatile char*>(memory) +
PaintOpWriter::HeaderBytes()),
- remaining_bytes_(size - PaintOpWriter::HeaderBytes()),
+ remaining_bytes_(
+ base::bits::AlignDown(size, PaintOpWriter::Alignment())),
options_(options),
enable_security_constraints_(enable_security_constraints) {
- if (size < PaintOpWriter::HeaderBytes())
+ DCHECK_EQ(memory_,
+ base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
+ if (remaining_bytes_ < PaintOpWriter::HeaderBytes()) {
valid_ = false;
+ return;
+ }
+ remaining_bytes_ -= PaintOpWriter::HeaderBytes();
}
static void FixupMatrixPostSerialization(SkMatrix* matrix);
@@ -62,12 +68,12 @@ class CC_PAINT_EXPORT PaintOpReader {
void Read(SkRect* rect);
void Read(SkIRect* rect);
void Read(SkRRect* rect);
+ void Read(SkColor4f* color);
void Read(SkPath* path);
void Read(PaintFlags* flags);
void Read(PaintImage* image);
void Read(sk_sp<SkData>* data);
- void Read(sk_sp<SkTextBlob>* blob);
void Read(sk_sp<GrSlug>* slug);
void Read(sk_sp<PaintFilter>* filter);
void Read(sk_sp<PaintShader>* shader);
@@ -126,6 +132,13 @@ class CC_PAINT_EXPORT PaintOpReader {
// Aligns the memory to the given alignment.
void AlignMemory(size_t alignment);
+ void AssertAlignment(size_t alignment) {
+#if DCHECK_IS_ON()
+ uintptr_t memory = reinterpret_cast<uintptr_t>(memory_);
+ DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory);
+#endif
+ }
+
private:
enum class DeserializationError {
// Enum values must remain synchronized with PaintOpDeserializationError
@@ -142,7 +155,7 @@ class CC_PAINT_EXPORT PaintOpReader {
kInsufficientRemainingBytes_Read_SkData = 9,
kInsufficientRemainingBytes_Read_SkPath = 10,
kInsufficientRemainingBytes_Read_SkRegion = 11,
- kInsufficientRemainingBytes_Read_SkTextBlob = 12,
+ kInsufficientRemainingBytes_Read_GrSlug = 12,
kInsufficientRemainingBytes_ReadData = 13,
kInsufficientRemainingBytes_ReadFlattenable = 14,
kInsufficientRemainingBytes_ReadMatrixConvolutionPaintFilter = 15,
@@ -173,7 +186,7 @@ class CC_PAINT_EXPORT PaintOpReader {
kSkPathEffectUnflattenFailure = 40,
kSkPathReadFromMemoryFailure = 41,
kSkRegionReadFromMemoryFailure = 42,
- kSkTextBlobDeserializeFailure = 43,
+ kGrSlugDeserializeFailure = 43,
kUnexpectedPaintShaderType = 44,
kUnexpectedSerializedImageType = 45,
kZeroMailbox = 46,
@@ -293,6 +306,7 @@ class CC_PAINT_EXPORT PaintOpReader {
void Read(SkRegion* region);
uint8_t* CopyScratchSpace(size_t bytes);
+ void DidRead(size_t bytes_read);
const volatile char* memory_ = nullptr;
size_t remaining_bytes_ = 0u;
diff --git a/chromium/cc/paint/paint_op_writer.cc b/chromium/cc/paint/paint_op_writer.cc
index 8e9e62af3f1..f899b75f254 100644
--- a/chromium/cc/paint/paint_op_writer.cc
+++ b/chromium/cc/paint/paint_op_writer.cc
@@ -5,6 +5,7 @@
#include "cc/paint/paint_op_writer.h"
#include <memory>
+#include <type_traits>
#include "base/bits.h"
#include "base/notreached.h"
@@ -34,8 +35,6 @@
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkSize.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
-#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/private/chromium/GrSlug.h"
#include "third_party/skia/include/private/chromium/SkChromeRemoteGlyphCache.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -43,7 +42,6 @@
namespace cc {
namespace {
-constexpr size_t kSkiaAlignment = 4u;
SkIRect MakeSrcRect(const PaintImage& image) {
if (!image)
@@ -98,26 +96,26 @@ PaintOpWriter::PaintOpWriter(void* memory,
const PaintOp::SerializeOptions& options,
bool enable_security_constraints)
: memory_(static_cast<char*>(memory) + HeaderBytes()),
- size_(size),
- remaining_bytes_(size - HeaderBytes()),
+ size_(base::bits::AlignDown(size, Alignment())),
+ remaining_bytes_(size_ - HeaderBytes()),
options_(options),
enable_security_constraints_(enable_security_constraints) {
// Leave space for header of type/skip.
DCHECK_GE(size, HeaderBytes());
+ DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment()));
}
PaintOpWriter::~PaintOpWriter() = default;
template <typename T>
void PaintOpWriter::WriteSimple(const T& val) {
- static_assert(base::is_trivially_copyable<T>::value, "");
+ static_assert(std::is_trivially_copyable_v<T>);
// Round up each write to 4 bytes. This is not technically perfect alignment,
// but it is about 30% faster to post-align each write to 4 bytes than it is
// to pre-align memory to the correct alignment.
- // TODO(enne): maybe we should do this correctly and DCHECK alignment.
- static constexpr size_t kAlign = 4;
- size_t size = base::bits::AlignUp(sizeof(T), kAlign);
+ DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment()));
+ static constexpr size_t size = base::bits::AlignUp(sizeof(T), Alignment());
EnsureBytes(size);
if (!valid_)
return;
@@ -138,14 +136,13 @@ void PaintOpWriter::WriteFlattenable(const SkFlattenable* val) {
return;
size_t bytes_written = val->serialize(
- memory_, base::bits::AlignDown(remaining_bytes_, kSkiaAlignment));
+ memory_, base::bits::AlignDown(remaining_bytes_, Alignment()));
if (bytes_written == 0u) {
valid_ = false;
return;
}
*size_memory = bytes_written;
- memory_ += bytes_written;
- remaining_bytes_ -= bytes_written;
+ DidWrite(bytes_written);
}
uint64_t* PaintOpWriter::WriteSize(size_t size) {
@@ -187,6 +184,10 @@ void PaintOpWriter::Write(const SkRRect& rect) {
WriteSimple(rect);
}
+void PaintOpWriter::Write(const SkColor4f& color) {
+ WriteSimple(color);
+}
+
void PaintOpWriter::Write(const SkPath& path, UsePaintCache use_paint_cache) {
auto id = path.getGenerationID();
if (!options_.for_identifiability_study)
@@ -226,8 +227,7 @@ void PaintOpWriter::Write(const SkPath& path, UsePaintCache use_paint_cache) {
options_.paint_cache->Put(PaintCacheDataType::kPath, id, bytes_written);
}
*bytes_to_skip = bytes_written;
- memory_ += bytes_written;
- remaining_bytes_ -= bytes_written;
+ DidWrite(bytes_written);
}
void PaintOpWriter::Write(const PaintFlags& flags, const SkM44& current_ctm) {
@@ -317,8 +317,7 @@ void PaintOpWriter::Write(scoped_refptr<SkottieWrapper> skottie) {
DCHECK_LE(bytes_written, remaining_bytes_);
*bytes_to_skip = bytes_written;
- memory_ += bytes_written;
- remaining_bytes_ -= bytes_written;
+ DidWrite(bytes_written);
}
void PaintOpWriter::WriteImage(const DecodedDrawImage& decoded_draw_image) {
@@ -356,8 +355,7 @@ void PaintOpWriter::WriteImage(const gpu::Mailbox& mailbox) {
return;
memcpy(memory_, mailbox.name, sizeof(mailbox.name));
- memory_ += sizeof(mailbox.name);
- remaining_bytes_ -= sizeof(mailbox.name);
+ DidWrite(sizeof(mailbox.name));
}
void PaintOpWriter::Write(const sk_sp<SkData>& data) {
@@ -397,16 +395,14 @@ void PaintOpWriter::Write(const SkColorSpace* color_space) {
size_t written = color_space->writeToMemory(memory_);
CHECK_EQ(written, size);
-
- memory_ += written;
- remaining_bytes_ -= written;
+ DidWrite(written);
}
void PaintOpWriter::Write(const sk_sp<GrSlug>& slug) {
if (!valid_)
return;
- AlignMemory(4);
+ AssertAlignment(Alignment());
uint64_t* size_memory = WriteSize(0u);
if (!valid_)
return;
@@ -416,52 +412,15 @@ void PaintOpWriter::Write(const sk_sp<GrSlug>& slug) {
// TODO(penghuang): should we use a unique id to avoid sending the same
// slug?
bytes_written = slug->serialize(
- memory_, base::bits::AlignDown(remaining_bytes_, kSkiaAlignment));
+ memory_, base::bits::AlignDown(remaining_bytes_, Alignment()));
if (bytes_written == 0u) {
valid_ = false;
return;
}
}
- *size_memory = bytes_written;
- memory_ += bytes_written;
- remaining_bytes_ -= bytes_written;
-}
-
-void PaintOpWriter::Write(const sk_sp<SkTextBlob>& blob) {
- DCHECK(blob);
- if (!valid_)
- return;
-
- AlignMemory(4);
- uint32_t blob_id = blob->uniqueID();
- Write(blob_id);
- uint64_t* size_memory = WriteSize(0u);
- if (!valid_)
- return;
-
- if (options_.paint_cache->Get(PaintCacheDataType::kTextBlob, blob_id))
- return;
-
- auto encodeTypeface = [](SkTypeface* tf, void* ctx) -> sk_sp<SkData> {
- return static_cast<SkStrikeServer*>(ctx)->serializeTypeface(tf);
- };
- DCHECK(options_.strike_server);
- SkSerialProcs procs;
- procs.fTypefaceProc = encodeTypeface;
- procs.fTypefaceCtx = options_.strike_server;
-
- size_t bytes_written = blob->serialize(
- procs, memory_, base::bits::AlignDown(remaining_bytes_, kSkiaAlignment));
- if (bytes_written == 0u) {
- valid_ = false;
- return;
- }
- options_.paint_cache->Put(PaintCacheDataType::kTextBlob, blob_id,
- bytes_written);
*size_memory = bytes_written;
- memory_ += bytes_written;
- remaining_bytes_ -= bytes_written;
+ DidWrite(bytes_written);
}
sk_sp<PaintShader> PaintOpWriter::TransformShaderIfNecessary(
@@ -607,15 +566,18 @@ void PaintOpWriter::Write(SkYUVAInfo::Subsampling subsampling) {
}
void PaintOpWriter::WriteData(size_t bytes, const void* input) {
+ DCHECK_EQ(memory_.get(),
+ base::bits::AlignUp(memory_.get(), PaintOpWriter::Alignment()));
+ if (bytes == 0)
+ return;
+
EnsureBytes(bytes);
+
if (!valid_)
return;
- if (bytes == 0)
- return;
memcpy(memory_, input, bytes);
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ DidWrite(bytes);
}
void PaintOpWriter::AlignMemory(size_t alignment) {
@@ -652,7 +614,7 @@ void PaintOpWriter::Write(const PaintFilter* filter, const SkM44& current_ctm) {
if (!valid_)
return;
- AlignMemory(kSkiaAlignment);
+ AssertAlignment(Alignment());
switch (filter->type()) {
case PaintFilter::Type::kNullFilter:
NOTREACHED();
@@ -1006,8 +968,7 @@ void PaintOpWriter::Write(const PaintRecord* record,
// The serializer should have failed if it ran out of space. DCHECK to verify
// that it wrote at most as many bytes as we had left.
DCHECK_LE(serializer.written(), remaining_bytes_);
- memory_ += serializer.written();
- remaining_bytes_ -= serializer.written();
+ DidWrite(serializer.written());
}
void PaintOpWriter::Write(const SkRegion& region) {
@@ -1020,6 +981,14 @@ void PaintOpWriter::Write(const SkRegion& region) {
WriteData(bytes_written, data.get());
}
+inline void PaintOpWriter::DidWrite(size_t bytes_written) {
+ // All data are aligned with PaintOpWriter::Alignment() at least.
+ size_t aligned_bytes = base::bits::AlignUp(bytes_written, Alignment());
+ memory_ += aligned_bytes;
+ DCHECK_LE(aligned_bytes, remaining_bytes_);
+ remaining_bytes_ -= aligned_bytes;
+}
+
inline void PaintOpWriter::EnsureBytes(size_t required_bytes) {
if (remaining_bytes_ < required_bytes)
valid_ = false;
diff --git a/chromium/cc/paint/paint_op_writer.h b/chromium/cc/paint/paint_op_writer.h
index 0c35f8e7d60..defb8ce9c99 100644
--- a/chromium/cc/paint/paint_op_writer.h
+++ b/chromium/cc/paint/paint_op_writer.h
@@ -60,11 +60,11 @@ class CC_PAINT_EXPORT PaintOpWriter {
void Write(const SkRect& rect);
void Write(const SkIRect& rect);
void Write(const SkRRect& rect);
+ void Write(const SkColor4f& color);
void Write(const SkPath& path, UsePaintCache);
void Write(const sk_sp<SkData>& data);
void Write(const SkColorSpace* data);
void Write(const SkSamplingOptions&);
- void Write(const sk_sp<SkTextBlob>& blob);
void Write(const sk_sp<GrSlug>& slug);
void Write(SkYUVColorSpace yuv_color_space);
void Write(SkYUVAInfo::PlaneConfig plane_config);
@@ -98,6 +98,13 @@ class CC_PAINT_EXPORT PaintOpWriter {
// Aligns the memory to the given alignment.
void AlignMemory(size_t alignment);
+ void AssertAlignment(size_t alignment) {
+#if DCHECK_IS_ON()
+ uintptr_t memory = reinterpret_cast<uintptr_t>(memory_.get());
+ DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory);
+#endif
+ }
+
// sk_sp is implicitly convertible to uint8_t (likely via implicit bool
// conversion). In order to avoid accidentally calling that overload instead
// of a specific function (such as would be the case if one forgets to call
@@ -171,7 +178,7 @@ class CC_PAINT_EXPORT PaintOpWriter {
void WriteImage(const DecodedDrawImage& decoded_draw_image);
void WriteImage(uint32_t transfer_cache_entry_id, bool needs_mips);
void WriteImage(const gpu::Mailbox& mailbox);
-
+ void DidWrite(size_t bytes_written);
void EnsureBytes(size_t required_bytes);
sk_sp<PaintShader> TransformShaderIfNecessary(
const PaintShader* original,
diff --git a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
index c6e4f150185..e5d985af10d 100644
--- a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -7,6 +7,8 @@
#include <string.h>
#include <utility>
+#include "base/check_op.h"
+
namespace cc {
ClientRawMemoryTransferCacheEntry::ClientRawMemoryTransferCacheEntry(
diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc
index 4938ba5ab52..0f917af47e1 100644
--- a/chromium/cc/paint/record_paint_canvas.cc
+++ b/chromium/cc/paint/record_paint_canvas.cc
@@ -228,11 +228,11 @@ bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
}
void RecordPaintCanvas::drawColor(SkColor color, SkBlendMode mode) {
- push<DrawColorOp>(color, mode);
+ push<DrawColorOp>(SkColor4f::FromColor(color), mode);
}
void RecordPaintCanvas::clear(SkColor color) {
- push<DrawColorOp>(color, SkBlendMode::kSrc);
+ push<DrawColorOp>(SkColor4f::FromColor(color), SkBlendMode::kSrc);
}
void RecordPaintCanvas::drawLine(SkScalar x0,
diff --git a/chromium/cc/paint/skottie_frame_data.h b/chromium/cc/paint/skottie_frame_data.h
index c76115f0f3a..0629918093b 100644
--- a/chromium/cc/paint/skottie_frame_data.h
+++ b/chromium/cc/paint/skottie_frame_data.h
@@ -28,7 +28,7 @@ struct CC_PAINT_EXPORT SkottieFrameData {
PaintImage image;
// Chromium version of SkSamplingOptions. Controls resampling quality if the
// image needs to be resized when rendering.
- PaintFlags::FilterQuality quality;
+ PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
};
CC_PAINT_EXPORT bool operator==(const SkottieFrameData& frame_l,
diff --git a/chromium/cc/paint/skottie_frame_data_provider.h b/chromium/cc/paint/skottie_frame_data_provider.h
index d6064763f12..27559f0c4b5 100644
--- a/chromium/cc/paint/skottie_frame_data_provider.h
+++ b/chromium/cc/paint/skottie_frame_data_provider.h
@@ -32,6 +32,9 @@ class CC_PAINT_EXPORT SkottieFrameDataProvider {
class CC_PAINT_EXPORT ImageAsset : public base::RefCounted<ImageAsset> {
public:
// Returns the image to use for an asset in a frame of a skottie animation.
+ // May return a blank SkottieFrameData instance with an empty |image|.
+ // Skottie handles this gracefully and simply skips the image asset while
+ // still rendering the rest of the frame.
//
// |t|: See skresources::ImageAsset::getFrame(). Same semantics. Specifies
// the frame of interest in the animation that's about to be rendered.
diff --git a/chromium/cc/paint/skottie_serialization_history.cc b/chromium/cc/paint/skottie_serialization_history.cc
index d7403547845..19004b4f51c 100644
--- a/chromium/cc/paint/skottie_serialization_history.cc
+++ b/chromium/cc/paint/skottie_serialization_history.cc
@@ -16,10 +16,9 @@ namespace cc {
SkottieSerializationHistory::SkottieFrameDataId::SkottieFrameDataId(
const SkottieFrameData& frame_data)
- : paint_image_id(frame_data.image.stable_id()),
- quality(frame_data.quality) {
- DCHECK_NE(paint_image_id, PaintImage::kInvalidId);
-}
+ : paint_image_id(frame_data.image ? frame_data.image.stable_id()
+ : PaintImage::kInvalidId),
+ quality(frame_data.quality) {}
bool SkottieSerializationHistory::SkottieFrameDataId::operator==(
const SkottieFrameDataId& other) const {
diff --git a/chromium/cc/paint/skottie_serialization_history_unittest.cc b/chromium/cc/paint/skottie_serialization_history_unittest.cc
index 4a6c0ea7ecd..64098b0871b 100644
--- a/chromium/cc/paint/skottie_serialization_history_unittest.cc
+++ b/chromium/cc/paint/skottie_serialization_history_unittest.cc
@@ -21,6 +21,7 @@
namespace cc {
namespace {
+using ::testing::Contains;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
@@ -90,6 +91,49 @@ TEST_F(SkottieSerializationHistoryTest, FilterNewSkottieFrameImages) {
EXPECT_THAT(images, IsEmpty());
}
+TEST_F(SkottieSerializationHistoryTest, HandlesEmptyImages) {
+ auto skottie = CreateSkottieFromString(
+ CreateCustomLottieDataWith2Assets("asset_a", "asset_b"));
+ PaintImage blank_image;
+ PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
+ PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
+ ;
+
+ SkottieFrameDataMap images = {
+ {HashSkottieResourceId("asset_a"),
+ {blank_image, PaintFlags::FilterQuality::kMedium}},
+ {HashSkottieResourceId("asset_b"),
+ {image_2, PaintFlags::FilterQuality::kMedium}},
+ };
+ history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
+ EXPECT_THAT(
+ images,
+ Contains(Pair(HashSkottieResourceId("asset_a"),
+ SkottieFrameData(
+ {blank_image, PaintFlags::FilterQuality::kMedium}))));
+
+ images = {{HashSkottieResourceId("asset_a"),
+ {image_1, PaintFlags::FilterQuality::kMedium}}};
+ history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
+ EXPECT_THAT(
+ images,
+ Contains(Pair(
+ HashSkottieResourceId("asset_a"),
+ SkottieFrameData({image_1, PaintFlags::FilterQuality::kMedium}))));
+
+ images = {{HashSkottieResourceId("asset_a"),
+ {blank_image, PaintFlags::FilterQuality::kMedium}}};
+ history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
+ EXPECT_THAT(
+ images,
+ Contains(Pair(HashSkottieResourceId("asset_a"),
+ SkottieFrameData(
+ {blank_image, PaintFlags::FilterQuality::kMedium}))));
+
+ history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
+ EXPECT_THAT(images, IsEmpty());
+}
+
TEST_F(SkottieSerializationHistoryTest, FilterNewSkottieFrameText) {
auto skottie = CreateSkottie(gfx::Size(10, 10), 1);
diff --git a/chromium/cc/paint/skottie_wrapper.h b/chromium/cc/paint/skottie_wrapper.h
index cbeece2c245..a7c4a7cf824 100644
--- a/chromium/cc/paint/skottie_wrapper.h
+++ b/chromium/cc/paint/skottie_wrapper.h
@@ -63,16 +63,13 @@ class CC_PAINT_EXPORT SkottieWrapper
// immutable and does not change during SkottieWrapper's lifetime.
virtual const base::flat_set<std::string>& GetTextNodeNames() const = 0;
- // Returns the set of all text nodes in the animation, along with their
- // corresponding current values. The nodes' values can only be updated via
- // the |text_map| argument in Draw().
+ // Returns a map from hashed animation node name to its current property
+ // value in the animation (see SkottieProperty.h). Some properties' values
+ // can be updated via its corresponding argument in Draw().
virtual SkottieTextPropertyValueMap GetCurrentTextPropertyValues() const = 0;
-
- // Returns the set of all transform nodes in the animation, along with their
- // corresponding current values. The nodes' values are not updateable via
- // Draw() like other properties simply because there is no use case yet.
virtual SkottieTransformPropertyValueMap GetCurrentTransformPropertyValues()
const = 0;
+ virtual SkottieColorMap GetCurrentColorPropertyValues() const = 0;
// Returns all markers present in the animation. The returned list is
// immutable and does not change during SkottieWrapper's lifetime.
@@ -91,9 +88,9 @@ class CC_PAINT_EXPORT SkottieWrapper
// The callback's output parameters have not been filled and will be
// ignored by SkottieWrapper. In this case, SkottieWrapper will reuse the
// frame data that was most recently provided for the given asset (it caches
- // this internally). If no frame data has ever been provided for this asset,
- // a null image will be passed to Skottie's Animation during Seek(); this
- // is acceptable if there's no rendering.
+ // this internally). Note it is acceptable to set |image_out| to a null
+ // SkImage; Skottie will simply skip the image asset while rendering the
+ // rest of the frame.
NO_UPDATE,
};
// The callback's implementation must synchronously fill the output
diff --git a/chromium/cc/paint/skottie_wrapper_impl.cc b/chromium/cc/paint/skottie_wrapper_impl.cc
index 7345e2f1c84..703575304f0 100644
--- a/chromium/cc/paint/skottie_wrapper_impl.cc
+++ b/chromium/cc/paint/skottie_wrapper_impl.cc
@@ -14,6 +14,7 @@
#include "base/containers/flat_map.h"
#include "base/hash/hash.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/trace_event/trace_event.h"
@@ -46,117 +47,169 @@ class SkottieLogWriter : public skottie::Logger {
}
};
-class PropertyHandler final : public skottie::PropertyObserver {
+// Methods for converting from a skottie::<Type>PropertyValue to its
+// corresponding representation in Chromium that gets circulated through the
+// graphics pipeline.
+class SkottiePropertyConversions {
public:
- PropertyHandler() = default;
- PropertyHandler(const PropertyHandler&) = delete;
- PropertyHandler& operator=(const PropertyHandler&) = delete;
- ~PropertyHandler() override = default;
-
- void ApplyColorMap(const SkottieColorMap& color_map) {
- for (const auto& map_color : color_map) {
- for (auto& handle : color_handles_[map_color.first]) {
- DCHECK(handle);
- handle->set(map_color.second);
- }
- }
+ // Convert skottie library representation to Chromium representation:
+ static SkColor ConvertToChromium(
+ const skottie::ColorPropertyValue& skottie_value) {
+ return skottie_value;
+ }
+
+ static SkottieTextPropertyValue ConvertToChromium(
+ const skottie::TextPropertyValue& skottie_value) {
+ std::string text(skottie_value.fText.c_str());
+ return SkottieTextPropertyValue(std::move(text),
+ gfx::SkRectToRectF(skottie_value.fBox));
}
- void ApplyTextMap(const SkottieTextPropertyValueMap& text_map) {
- for (const auto& [node_name_hash, new_text_val] : text_map) {
- auto current_text_values_iter = current_text_values_.find(node_name_hash);
- if (current_text_values_iter == current_text_values_.end()) {
- LOG(WARNING) << "Encountered unknown text node with hash: "
+ static SkottieTransformPropertyValue ConvertToChromium(
+ const skottie::TransformPropertyValue& skottie_value) {
+ SkottieTransformPropertyValue output = {
+ /*position*/ gfx::SkPointToPointF(skottie_value.fPosition)};
+ return output;
+ }
+
+ // Convert Chromium representation to skottie library representation:
+ static void ConvertToSkottie(const SkColor& chromium_value,
+ skottie::ColorPropertyValue& skottie_value_out) {
+ skottie_value_out = chromium_value;
+ }
+
+ static void ConvertToSkottie(const SkottieTextPropertyValue& chromium_value,
+ skottie::TextPropertyValue& skottie_value_out) {
+ skottie_value_out.fText.set(chromium_value.text().c_str());
+ skottie_value_out.fBox = gfx::RectFToSkRect(chromium_value.box());
+ }
+
+ static void ConvertToSkottie(
+ const SkottieTransformPropertyValue& chromium_value,
+ skottie::TransformPropertyValue& skottie_value_out) {
+ NOTIMPLEMENTED() << "No use case yet for modifying transform properties";
+ }
+};
+
+template <typename SkottiePropertyValueType,
+ typename SkottiePropertyHandleType,
+ typename ChromiumPropertyValueType>
+class PropertyManager {
+ public:
+ PropertyManager() = default;
+ PropertyManager(const PropertyManager&) = delete;
+ PropertyManager& operator=(const PropertyManager&) = delete;
+ ~PropertyManager() = default;
+
+ void OnNodeParsed(
+ const char node_name[],
+ const skottie::PropertyObserver::LazyHandle<SkottiePropertyHandleType>&
+ lh) {
+ if (!node_name)
+ return;
+
+ node_names_.insert(node_name);
+ SkottieResourceIdHash node_name_hash = HashSkottieResourceId(node_name);
+ auto skottie_property_handle = lh();
+ current_vals_as_chromium_.emplace(
+ node_name_hash, SkottiePropertyConversions::ConvertToChromium(
+ skottie_property_handle->get()));
+ skottie_property_handles_[node_name_hash].push_back(
+ std::move(skottie_property_handle));
+ }
+
+ void SetNewValues(
+ const base::flat_map<SkottieResourceIdHash, ChromiumPropertyValueType>&
+ new_vals_as_chromium) {
+ for (const auto& [node_name_hash, new_val_as_chromium] :
+ new_vals_as_chromium) {
+ auto iter = current_vals_as_chromium_.find(node_name_hash);
+ if (iter == current_vals_as_chromium_.end()) {
+ LOG(WARNING) << "Encountered unknown property node with hash: "
<< node_name_hash;
continue;
}
- current_text_values_iter->second = new_text_val;
-
- for (auto& handle : text_handles_[node_name_hash]) {
- DCHECK(handle);
- skottie::TextPropertyValue current_text_val = handle->get();
- ConvertTextValueToSkottie(new_text_val, current_text_val);
- handle->set(std::move(current_text_val));
+ iter->second = new_val_as_chromium;
+
+ for (auto& skottie_handle : skottie_property_handles_[node_name_hash]) {
+ DCHECK(skottie_handle);
+ SkottiePropertyValueType current_val_as_skottie = skottie_handle->get();
+ SkottiePropertyConversions::ConvertToSkottie(new_val_as_chromium,
+ current_val_as_skottie);
+ skottie_handle->set(std::move(current_val_as_skottie));
}
}
}
- const SkottieTextPropertyValueMap& current_text_values() const {
- return current_text_values_;
+ const base::flat_set<std::string>& node_names() const { return node_names_; }
+
+ const base::flat_map<SkottieResourceIdHash, ChromiumPropertyValueType>
+ current_vals_as_chromium() const {
+ return current_vals_as_chromium_;
}
- const SkottieTransformPropertyValueMap current_transform_values() const {
- return current_transform_values_;
+ private:
+ base::flat_map<SkottieResourceIdHash,
+ std::vector<std::unique_ptr<SkottiePropertyHandleType>>>
+ skottie_property_handles_;
+ base::flat_set<std::string> node_names_;
+ base::flat_map<SkottieResourceIdHash, ChromiumPropertyValueType>
+ current_vals_as_chromium_;
+};
+
+using ColorPropertyManager = PropertyManager<skottie::ColorPropertyValue,
+ skottie::ColorPropertyHandle,
+ SkColor>;
+using TextPropertyManager = PropertyManager<skottie::TextPropertyValue,
+ skottie::TextPropertyHandle,
+ SkottieTextPropertyValue>;
+using TransformPropertyManager =
+ PropertyManager<skottie::TransformPropertyValue,
+ skottie::TransformPropertyHandle,
+ SkottieTransformPropertyValue>;
+
+class GlobalPropertyManager final : public skottie::PropertyObserver {
+ public:
+ GlobalPropertyManager() = default;
+ GlobalPropertyManager(const GlobalPropertyManager&) = delete;
+ GlobalPropertyManager& operator=(const GlobalPropertyManager&) = delete;
+ ~GlobalPropertyManager() override = default;
+
+ ColorPropertyManager& color_property_manager() {
+ return color_property_manager_;
}
- const base::flat_set<std::string>& text_node_names() const {
- return text_node_names_;
+ TextPropertyManager& text_property_manager() {
+ return text_property_manager_;
+ }
+
+ TransformPropertyManager& transform_property_manager() {
+ return transform_property_manager_;
}
// skottie::PropertyObserver:
void onColorProperty(
const char node_name[],
const LazyHandle<skottie::ColorPropertyHandle>& lh) override {
- if (node_name)
- color_handles_[HashSkottieResourceId(node_name)].push_back(lh());
+ color_property_manager_.OnNodeParsed(node_name, lh);
}
void onTextProperty(
const char node_name[],
const LazyHandle<skottie::TextPropertyHandle>& lh) override {
- if (!node_name)
- return;
-
- text_node_names_.insert(node_name);
- SkottieResourceIdHash node_name_hash = HashSkottieResourceId(node_name);
- auto text_handle = lh();
- current_text_values_.emplace(
- node_name_hash, ConvertTextValueToChromium(text_handle->get()));
- text_handles_[node_name_hash].push_back(std::move(text_handle));
+ text_property_manager_.OnNodeParsed(node_name, lh);
}
void onTransformProperty(
const char node_name[],
const LazyHandle<skottie::TransformPropertyHandle>& lh) override {
- if (!node_name)
- return;
-
- current_transform_values_.emplace(
- HashSkottieResourceId(node_name),
- ConvertTransformValueToChromium(lh()->get()));
+ transform_property_manager_.OnNodeParsed(node_name, lh);
}
private:
- static SkottieTextPropertyValue ConvertTextValueToChromium(
- const skottie::TextPropertyValue& value_in) {
- std::string text(value_in.fText.c_str());
- return SkottieTextPropertyValue(std::move(text),
- gfx::SkRectToRectF(value_in.fBox));
- }
-
- static void ConvertTextValueToSkottie(
- const SkottieTextPropertyValue& value_in,
- skottie::TextPropertyValue& value_out) {
- value_out.fText.set(value_in.text().c_str());
- value_out.fBox = gfx::RectFToSkRect(value_in.box());
- }
-
- static SkottieTransformPropertyValue ConvertTransformValueToChromium(
- const skottie::TransformPropertyValue& value_in) {
- SkottieTransformPropertyValue output = {
- /*position*/ gfx::SkPointToPointF(value_in.fPosition)};
- return output;
- }
-
- base::flat_map<SkottieResourceIdHash,
- std::vector<std::unique_ptr<skottie::ColorPropertyHandle>>>
- color_handles_;
- base::flat_map<SkottieResourceIdHash,
- std::vector<std::unique_ptr<skottie::TextPropertyHandle>>>
- text_handles_;
- base::flat_set<std::string> text_node_names_;
- SkottieTextPropertyValueMap current_text_values_;
- SkottieTransformPropertyValueMap current_transform_values_;
+ ColorPropertyManager color_property_manager_;
+ TextPropertyManager text_property_manager_;
+ TransformPropertyManager transform_property_manager_;
};
class MarkerStore : public skottie::MarkerObserver {
@@ -212,19 +265,28 @@ class SkottieWrapperImpl : public SkottieWrapper {
const base::flat_set<std::string>& GetTextNodeNames() const override
LOCKS_EXCLUDED(lock_) {
base::AutoLock lock(lock_);
- return property_handler_->text_node_names();
+ return property_manager_->text_property_manager().node_names();
}
SkottieTextPropertyValueMap GetCurrentTextPropertyValues() const override
LOCKS_EXCLUDED(lock_) {
base::AutoLock lock(lock_);
- return property_handler_->current_text_values();
+ return property_manager_->text_property_manager()
+ .current_vals_as_chromium();
}
SkottieTransformPropertyValueMap GetCurrentTransformPropertyValues()
const override LOCKS_EXCLUDED(lock_) {
base::AutoLock lock(lock_);
- return property_handler_->current_transform_values();
+ return property_manager_->transform_property_manager()
+ .current_vals_as_chromium();
+ }
+
+ SkottieColorMap GetCurrentColorPropertyValues() const override
+ LOCKS_EXCLUDED(lock_) {
+ base::AutoLock lock(lock_);
+ return property_manager_->color_property_manager()
+ .current_vals_as_chromium();
}
const std::vector<SkottieMarker>& GetAllMarkers() const override {
@@ -250,8 +312,8 @@ class SkottieWrapperImpl : public SkottieWrapper {
LOCKS_EXCLUDED(lock_) {
base::AutoLock lock(lock_);
current_frame_data_cb_ = std::move(frame_data_cb);
- property_handler_->ApplyColorMap(color_map);
- property_handler_->ApplyTextMap(text_map);
+ property_manager_->color_property_manager().SetNewValues(color_map);
+ property_manager_->text_property_manager().SetNewValues(text_map);
animation_->seek(t);
animation_->render(canvas, &rect);
}
@@ -272,12 +334,12 @@ class SkottieWrapperImpl : public SkottieWrapper {
base::span<const uint8_t> data,
std::vector<uint8_t> raw_data,
const sk_sp<SkottieMRUResourceProvider>& mru_resource_provider)
- : property_handler_(sk_make_sp<PropertyHandler>()),
+ : property_manager_(sk_make_sp<GlobalPropertyManager>()),
marker_store_(sk_make_sp<MarkerStore>()),
animation_(
skottie::Animation::Builder()
.setLogger(sk_make_sp<SkottieLogWriter>())
- .setPropertyObserver(property_handler_)
+ .setPropertyObserver(property_manager_)
.setResourceProvider(skresources::CachingResourceProvider::Make(
mru_resource_provider))
.setMarkerObserver(marker_store_)
@@ -305,7 +367,7 @@ class SkottieWrapperImpl : public SkottieWrapper {
mutable base::Lock lock_;
FrameDataCallback current_frame_data_cb_ GUARDED_BY(lock_);
- sk_sp<PropertyHandler> property_handler_ GUARDED_BY(lock_);
+ sk_sp<GlobalPropertyManager> property_manager_ GUARDED_BY(lock_);
const sk_sp<MarkerStore> marker_store_;
sk_sp<skottie::Animation> animation_;
diff --git a/chromium/cc/paint/skottie_wrapper_unittest.cc b/chromium/cc/paint/skottie_wrapper_unittest.cc
index f45f625accf..469e2d9c186 100644
--- a/chromium/cc/paint/skottie_wrapper_unittest.cc
+++ b/chromium/cc/paint/skottie_wrapper_unittest.cc
@@ -185,6 +185,53 @@ TEST(SkottieWrapperTest, LoadsCorrectAssetsForSeek) {
Mock::VerifyAndClearExpectations(&mock_callback);
}
+TEST(SkottieWrapperTest, LoadsColorNodes) {
+ auto skottie = CreateSkottieFromString(kLottieDataWithoutAssets1);
+ ASSERT_TRUE(skottie->is_valid());
+ EXPECT_THAT(
+ skottie->GetCurrentColorPropertyValues(),
+ UnorderedElementsAre(
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
+ kLottieDataWithoutAssets1Color1),
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
+ kLottieDataWithoutAssets1Color2)));
+}
+
+TEST(SkottieWrapperTest, SetsColorNodesWithDraw) {
+ auto skottie = CreateSkottieFromString(kLottieDataWithoutAssets1);
+ ASSERT_TRUE(skottie->is_valid());
+ ::testing::NiceMock<MockCanvas> canvas;
+
+ SkottieColorMap color_map = {
+ {HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
+ SK_ColorYELLOW},
+ {HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
+ SK_ColorCYAN}};
+ skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
+ SkottieWrapper::FrameDataCallback(), color_map,
+ SkottieTextPropertyValueMap());
+ EXPECT_THAT(
+ skottie->GetCurrentColorPropertyValues(),
+ UnorderedElementsAre(
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
+ SK_ColorYELLOW),
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
+ SK_ColorCYAN)));
+
+ color_map = {{HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
+ SK_ColorMAGENTA}};
+ skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
+ SkottieWrapper::FrameDataCallback(), color_map,
+ SkottieTextPropertyValueMap());
+ EXPECT_THAT(
+ skottie->GetCurrentColorPropertyValues(),
+ UnorderedElementsAre(
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
+ SK_ColorYELLOW),
+ Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
+ SK_ColorMAGENTA)));
+}
+
TEST(SkottieWrapperTest, LoadsTextNodes) {
auto skottie = CreateSkottieFromTestDataDir(kLottieDataWith2TextFileName);
ASSERT_TRUE(skottie->is_valid());
diff --git a/chromium/cc/paint/solid_color_analyzer.cc b/chromium/cc/paint/solid_color_analyzer.cc
index a1d4a92d01e..73f38fc20ed 100644
--- a/chromium/cc/paint/solid_color_analyzer.cc
+++ b/chromium/cc/paint/solid_color_analyzer.cc
@@ -324,8 +324,8 @@ absl::optional<SkColor4f> SolidColorAnalyzer::DetermineIfSolidColor(
if (++num_draw_ops > max_ops_to_analyze)
return absl::nullopt;
const DrawColorOp* color_op = static_cast<const DrawColorOp*>(op);
- CheckIfSolidColor(canvas, SkColor4f::FromColor(color_op->color),
- color_op->mode, &is_solid, &is_transparent, &color);
+ CheckIfSolidColor(canvas, color_op->color, color_op->mode, &is_solid,
+ &is_transparent, &color);
break;
}
case PaintOpType::ClipRect: {
diff --git a/chromium/cc/paint/solid_color_analyzer_unittest.cc b/chromium/cc/paint/solid_color_analyzer_unittest.cc
index 26c50f99ad5..a343e1d4cc5 100644
--- a/chromium/cc/paint/solid_color_analyzer_unittest.cc
+++ b/chromium/cc/paint/solid_color_analyzer_unittest.cc
@@ -116,7 +116,7 @@ TEST_F(SolidColorAnalyzerTest, DrawOval) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
canvas()->drawOval(SkRect::MakeWH(100, 100), flags);
EXPECT_FALSE(IsSolidColor());
}
@@ -125,7 +125,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRect) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->clipRect(rect, SkClipOp::kIntersect, false);
canvas()->drawRect(rect, flags);
@@ -142,7 +142,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRRect) {
Initialize(canvas_rect);
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
canvas()->drawRRect(rrect, flags);
EXPECT_EQ(color, GetColor());
}
@@ -151,7 +151,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectClipped) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->clipRect(SkRect::MakeWH(50, 50), SkClipOp::kIntersect, false);
canvas()->drawRect(rect, flags);
@@ -162,7 +162,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectClippedDifference) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect drawRect = SkRect::MakeWH(200, 200);
canvas()->clipRect(drawRect, SkClipOp::kIntersect, false);
SkRect differenceRect = SkRect::MakeXYWH(50, 50, 200, 200);
@@ -176,7 +176,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectWithTranslateNotSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(100, 100);
canvas()->translate(1, 1);
canvas()->drawRect(rect, flags);
@@ -187,7 +187,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectWithTranslateSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(101, 101);
canvas()->translate(1, 1);
canvas()->drawRect(rect, flags);
@@ -206,7 +206,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectBlendModeClear) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
flags.setBlendMode(SkBlendMode::kClear);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->drawRect(rect, flags);
@@ -217,7 +217,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectBlendModeSrcOver) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
flags.setBlendMode(SkBlendMode::kSrcOver);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->drawRect(rect, flags);
@@ -228,7 +228,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectRotated) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->rotate(50);
canvas()->drawRect(rect, flags);
@@ -239,7 +239,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectScaledNotSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->scale(0.1f, 0.1f);
canvas()->drawRect(rect, flags);
@@ -250,7 +250,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectScaledSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(10, 10);
canvas()->scale(10, 10);
canvas()->drawRect(rect, flags);
@@ -261,7 +261,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectFilterPaint) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
flags.setImageFilter(sk_make_sp<OffsetPaintFilter>(10, 10, nullptr));
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->drawRect(rect, flags);
@@ -272,7 +272,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectClipPath) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkPath path;
path.moveTo(0, 0);
@@ -291,7 +291,7 @@ TEST_F(SolidColorAnalyzerTest, DrawRectTranslucent) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(128, 128, 0, 0));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(100, 100);
canvas()->drawRect(rect, flags);
#if BUILDFLAG(IS_MAC)
@@ -307,11 +307,11 @@ TEST_F(SolidColorAnalyzerTest, DrawRectTranslucentOverNonSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 128, 0, 0));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(100, 50);
canvas()->drawRect(rect, flags);
color = SkColor4f::FromColor(SkColorSetARGB(128, 0, 128, 0));
- flags.setColor4f(color);
+ flags.setColor(color);
rect = SkRect::MakeWH(100, 100);
canvas()->drawRect(rect, flags);
EXPECT_FALSE(IsSolidColor(2 /* max_ops_to_analyze */));
@@ -321,11 +321,11 @@ TEST_F(SolidColorAnalyzerTest, DrawRectOpaqueOccludesNonSolid) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 128, 0, 0));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(100, 50);
canvas()->drawRect(rect, flags);
color = SkColor4f::FromColor(SkColorSetARGB(255, 0, 128, 0));
- flags.setColor4f(color);
+ flags.setColor(color);
rect = SkRect::MakeWH(100, 100);
canvas()->drawRect(rect, flags);
EXPECT_EQ(color, GetColor(2 /* max_ops_to_analyze */));
@@ -335,11 +335,11 @@ TEST_F(SolidColorAnalyzerTest, DrawRectSolidWithSrcOverBlending) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(64, 40, 50, 60));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(100, 100);
canvas()->drawRect(rect, flags);
color = SkColor4f::FromColor(SkColorSetARGB(128, 10, 20, 30));
- flags.setColor4f(color);
+ flags.setColor(color);
rect = SkRect::MakeWH(100, 100);
canvas()->drawRect(rect, flags);
#if BUILDFLAG(IS_MAC)
@@ -357,7 +357,7 @@ TEST_F(SolidColorAnalyzerTest, SaveLayer) {
Initialize();
PaintFlags flags;
SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
- flags.setColor4f(color);
+ flags.setColor(color);
SkRect rect = SkRect::MakeWH(200, 200);
canvas()->saveLayer(&rect, &flags);
@@ -379,7 +379,7 @@ TEST_F(SolidColorAnalyzerTest, ClipRRectCoversCanvas) {
int canvas_size = 255;
gfx::Rect canvas_rect(canvas_size, canvas_size);
PaintFlags flags;
- flags.setColor4f(SkColors::kWhite);
+ flags.setColor(SkColors::kWhite);
struct {
SkVector offset;
diff --git a/chromium/cc/paint/transfer_cache_unittest.cc b/chromium/cc/paint/transfer_cache_unittest.cc
index f8f7984e8db..af89bbfcece 100644
--- a/chromium/cc/paint/transfer_cache_unittest.cc
+++ b/chromium/cc/paint/transfer_cache_unittest.cc
@@ -49,8 +49,7 @@ class TransferCacheTest : public testing::Test {
context_ = std::make_unique<gpu::RasterInProcessContext>();
auto result = context_->Initialize(
viz::TestGpuServiceHolder::GetInstance()->task_executor(), attribs,
- gpu::SharedMemoryLimits(), &gpu_memory_buffer_manager_, &image_factory_,
- /*gpu_channel_manager_delegate=*/nullptr, nullptr, nullptr);
+ gpu::SharedMemoryLimits(), &image_factory_, nullptr, nullptr);
ASSERT_EQ(result, gpu::ContextResult::kSuccess);
ASSERT_TRUE(context_->GetCapabilities().supports_oop_raster);
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index a404b098d21..a7065c6b83f 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -90,7 +90,7 @@ class BitmapRasterBufferImpl : public RasterBuffer {
// `pixels_` is not a raw_ptr<...> for performance reasons: pointee is never
// protected by BackupRefPtr, because the pointer comes either from using
// `mmap`, MapViewOfFile or base::AllocPages directly.
- void* const pixels_;
+ RAW_PTR_EXCLUSION void* const pixels_;
bool resource_has_previous_content_;
};
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index f88bec234b7..bf0d9d7b2d4 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -12,6 +12,7 @@
#include <vector>
#include "base/bits.h"
+#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
@@ -379,7 +380,7 @@ void GpuRasterBufferProvider::RasterBufferImpl::RasterizeSource(
// If playback_settings.msaa_sample_count <= 0, the MSAA is not used. It is
// equivalent to MSAA sample count 1.
uint32_t sample_count =
- std::clamp(playback_settings.msaa_sample_count, 1, 64);
+ base::clamp(playback_settings.msaa_sample_count, 1, 64);
UMA_HISTOGRAM_CUSTOM_COUNTS("Gpu.Rasterization.Raster.MSAASampleCountLog2",
base::bits::Log2Floor(sample_count), 0, 7, 7);
// With Raw Draw, the framebuffer will be the rasterization target. It cannot
@@ -388,10 +389,12 @@ void GpuRasterBufferProvider::RasterBufferImpl::RasterizeSource(
bool is_raw_draw_backing =
client_->is_using_raw_draw_ && !backing_->overlay_candidate;
bool use_lcd_text = playback_settings.use_lcd_text && !is_raw_draw_backing;
+
ri->BeginRasterCHROMIUM(
raster_source->background_color(), mailbox_needs_clear,
playback_settings.msaa_sample_count, msaa_mode, use_lcd_text,
playback_settings.visible, color_space_, backing_->mailbox.name);
+
gfx::Vector2dF recording_to_raster_scale = transform.scale();
recording_to_raster_scale.Scale(1 / raster_source->recording_scale_factor());
gfx::Size content_size = raster_source->GetContentSize(transform.scale());
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index 31df8af1b09..ca84866c0c5 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -413,7 +413,7 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
// Create staging shared image.
if (staging_buffer->mailbox.IsZero()) {
- const uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER;
+ const uint32_t usage = gpu::SHARED_IMAGE_USAGE_CPU_WRITE;
staging_buffer->mailbox = sii->CreateSharedImage(
staging_buffer->gpu_memory_buffer.get(), gpu_memory_buffer_manager_,
color_space, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage);
@@ -468,7 +468,9 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
resource_size.height());
SkBitmap bitmap;
if (bitmap.tryAllocPixels(dst_info, clear_bytes_per_row)) {
- bitmap.eraseColor(raster_source->background_color());
+ // SkBitmap.cpp doesn't yet have an interface for SkColor4fs
+ // https://bugs.chromium.org/p/skia/issues/detail?id=13329
+ bitmap.eraseColor(raster_source->background_color().toSkColor());
ri->WritePixels(*mailbox, 0, 0, mailbox_texture_target,
clear_bytes_per_row, dst_info, bitmap.getPixels());
}
diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc
index 78cd768d485..f6c39937b46 100644
--- a/chromium/cc/raster/raster_buffer_provider_perftest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc
@@ -40,12 +40,6 @@ namespace {
class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
// Overridden from gpu::gles2::GLES2Interface:
- GLuint CreateImageCHROMIUM(ClientBuffer buffer,
- GLsizei width,
- GLsizei height,
- GLenum internalformat) override {
- return 1u;
- }
void GenBuffers(GLsizei n, GLuint* buffers) override {
for (GLsizei i = 0; i < n; ++i)
buffers[i] = 1u;
diff --git a/chromium/cc/raster/raster_source.cc b/chromium/cc/raster/raster_source.cc
index 40ff7b1cb6e..42f1a147ec5 100644
--- a/chromium/cc/raster/raster_source.cc
+++ b/chromium/cc/raster/raster_source.cc
@@ -128,7 +128,7 @@ void RasterSource::PlaybackDisplayListToCanvas(
}
bool RasterSource::PerformSolidColorAnalysis(gfx::Rect layer_rect,
- SkColor* color) const {
+ SkColor4f* color) const {
TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis");
layer_rect.Intersect(gfx::Rect(size_));
@@ -183,7 +183,7 @@ bool RasterSource::IsSolidColor() const {
SkColor RasterSource::GetSolidColor() const {
DCHECK(IsSolidColor());
- return solid_color_;
+ return solid_color_.toSkColor();
}
bool RasterSource::HasRecordings() const {
diff --git a/chromium/cc/raster/raster_source.h b/chromium/cc/raster/raster_source.h
index f8ab19ff57c..9e0fc1b719e 100644
--- a/chromium/cc/raster/raster_source.h
+++ b/chromium/cc/raster/raster_source.h
@@ -80,7 +80,8 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
// Returns whether the given rect at given scale is of solid color in
// this raster source, as well as the solid color value.
- bool PerformSolidColorAnalysis(gfx::Rect content_rect, SkColor* color) const;
+ bool PerformSolidColorAnalysis(gfx::Rect content_rect,
+ SkColor4f* color) const;
// Returns true iff the whole raster source is of solid color.
bool IsSolidColor() const;
@@ -121,7 +122,7 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
float recording_scale_factor() const { return recording_scale_factor_; }
- SkColor background_color() const { return background_color_; }
+ SkColor4f background_color() const { return background_color_; }
bool requires_clear() const { return requires_clear_; }
@@ -163,10 +164,10 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
// These members are const as this raster source may be in use on another
// thread and so should not be touched after construction.
const scoped_refptr<DisplayItemList> display_list_;
- const SkColor background_color_;
+ const SkColor4f background_color_;
const bool requires_clear_;
const bool is_solid_color_;
- const SkColor solid_color_;
+ const SkColor4f solid_color_;
const gfx::Rect recorded_viewport_;
const gfx::Size size_;
const int slow_down_raster_scale_factor_for_debug_;
diff --git a/chromium/cc/raster/raster_source_unittest.cc b/chromium/cc/raster/raster_source_unittest.cc
index 7085096822b..dd16a6526d4 100644
--- a/chromium/cc/raster/raster_source_unittest.cc
+++ b/chromium/cc/raster/raster_source_unittest.cc
@@ -51,7 +51,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) {
solid_flags.setColor(solid_color);
SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
PaintFlags non_solid_flags;
bool is_solid_color = false;
non_solid_flags.setColor(non_solid_color);
@@ -68,7 +68,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) {
gfx::Rect rect(x, y, 100, 100);
is_solid_color = raster->PerformSolidColorAnalysis(rect, &color);
EXPECT_TRUE(is_solid_color) << rect.ToString();
- EXPECT_COLOR_EQ(solid_color, color) << rect.ToString();
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor()) << rect.ToString();
}
}
@@ -78,35 +78,35 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) {
recording_source->Rerecord();
raster = recording_source->CreateRasterSource();
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 100, 100), &color);
EXPECT_FALSE(is_solid_color);
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(100, 0, 100, 100), &color);
EXPECT_TRUE(is_solid_color);
- EXPECT_COLOR_EQ(solid_color, color);
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor());
// Boundaries should be clipped.
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(350, 0, 100, 100), &color);
EXPECT_TRUE(is_solid_color);
- EXPECT_COLOR_EQ(solid_color, color);
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor());
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(0, 350, 100, 100), &color);
EXPECT_TRUE(is_solid_color);
- EXPECT_COLOR_EQ(solid_color, color);
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor());
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(350, 350, 100, 100), &color);
EXPECT_TRUE(is_solid_color);
- EXPECT_COLOR_EQ(solid_color, color);
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor());
}
TEST(RasterSourceTest, AnalyzeIsSolidScaled) {
@@ -123,7 +123,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) {
solid_flags.setColor(solid_color);
SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
PaintFlags non_solid_flags;
bool is_solid_color = false;
non_solid_flags.setColor(non_solid_color);
@@ -142,7 +142,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) {
is_solid_color = raster->PerformSolidColorAnalysis(rect, &color);
EXPECT_TRUE(is_solid_color)
<< rect.ToString() << " recording_scale: " << recording_scale;
- EXPECT_COLOR_EQ(solid_color, color)
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor())
<< rect.ToString() << " recording_scale: " << recording_scale;
}
}
@@ -155,43 +155,43 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) {
recording_source->Rerecord();
raster = recording_source->CreateRasterSource();
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 100, 100), &color);
EXPECT_FALSE(is_solid_color) << " recording_scale: " << recording_scale;
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 51, 51), &color);
EXPECT_FALSE(is_solid_color) << " recording_scale: " << recording_scale;
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(51, 0, 100, 100), &color);
EXPECT_TRUE(is_solid_color) << " recording_scale: " << recording_scale;
- EXPECT_COLOR_EQ(solid_color, color)
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor())
<< " recording_scale: " << recording_scale;
// Boundaries should be clipped.
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(350, 0, 100, 100), &color);
EXPECT_TRUE(is_solid_color) << " recording_scale: " << recording_scale;
- EXPECT_COLOR_EQ(solid_color, color)
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor())
<< " recording_scale: " << recording_scale;
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color =
raster->PerformSolidColorAnalysis(gfx::Rect(0, 350, 100, 100), &color);
EXPECT_TRUE(is_solid_color) << " recording_scale: " << recording_scale;
- EXPECT_COLOR_EQ(solid_color, color)
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor())
<< " recording_scale: " << recording_scale;
- color = SK_ColorTRANSPARENT;
+ color = SkColors::kTransparent;
is_solid_color = raster->PerformSolidColorAnalysis(
gfx::Rect(350, 350, 100, 100), &color);
EXPECT_TRUE(is_solid_color) << " recording_scale: " << recording_scale;
- EXPECT_COLOR_EQ(solid_color, color)
+ EXPECT_COLOR_EQ(solid_color, color.toSkColor())
<< " recording_scale: " << recording_scale;
}
}
@@ -268,7 +268,7 @@ TEST(RasterSourceTest, RasterFullContents) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorBLACK);
+ recording_source->SetBackgroundColor(SkColors::kBlack);
// Because the caller sets content opaque, it also promises that it
// has at least filled in layer_bounds opaquely.
@@ -302,7 +302,7 @@ TEST(RasterSourceTest, RasterFullContents) {
SkBitmap bitmap;
bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
SkCanvas canvas(bitmap, SkSurfaceProps{});
- canvas.clear(SK_ColorTRANSPARENT);
+ canvas.clear(SkColors::kTransparent);
raster->PlaybackToCanvas(
&canvas, content_bounds, canvas_rect, canvas_rect,
@@ -333,7 +333,7 @@ TEST(RasterSourceTest, RasterFullContentsWithRasterTranslation) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorBLACK);
+ recording_source->SetBackgroundColor(SkColors::kBlack);
// Because the caller sets content opaque, it also promises that it
// has at least filled in layer_bounds opaquely.
@@ -363,7 +363,7 @@ TEST(RasterSourceTest, RasterFullContentsWithRasterTranslation) {
SkBitmap bitmap;
bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
SkCanvas canvas(bitmap, SkSurfaceProps{});
- canvas.clear(SK_ColorTRANSPARENT);
+ canvas.clear(SkColors::kTransparent);
raster->PlaybackToCanvas(
&canvas, content_bounds, canvas_rect, canvas_rect,
@@ -393,7 +393,7 @@ TEST(RasterSourceTest, RasterPartialContents) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorGREEN);
+ recording_source->SetBackgroundColor(SkColors::kGreen);
// First record everything as white.
PaintFlags white_flags;
@@ -467,7 +467,7 @@ TEST(RasterSourceTest, RasterPartialContentsWithRasterTranslation) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorGREEN);
+ recording_source->SetBackgroundColor(SkColors::kGreen);
// First record everything as white.
PaintFlags white_flags;
@@ -558,7 +558,7 @@ TEST(RasterSourceTest, RasterPartialClear) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorGREEN);
+ recording_source->SetBackgroundColor(SkColors::kGreen);
recording_source->SetRequiresClear(true);
// First record everything as white.
@@ -596,7 +596,7 @@ TEST(RasterSourceTest, RasterPartialClear) {
std::unique_ptr<FakeRecordingSource> recording_source_light =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source_light->SetBackgroundColor(SK_ColorGREEN);
+ recording_source_light->SetBackgroundColor(SkColors::kGreen);
recording_source_light->SetRequiresClear(true);
// Record everything as a slightly lighter white.
@@ -633,7 +633,7 @@ TEST(RasterSourceTest, RasterContentsTransparent) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
- recording_source->SetBackgroundColor(SK_ColorTRANSPARENT);
+ recording_source->SetBackgroundColor(SkColors::kTransparent);
recording_source->SetRequiresClear(true);
recording_source->Rerecord();
diff --git a/chromium/cc/raster/task_graph_work_queue.cc b/chromium/cc/raster/task_graph_work_queue.cc
index 1ca3c67c2a9..707a1490983 100644
--- a/chromium/cc/raster/task_graph_work_queue.cc
+++ b/chromium/cc/raster/task_graph_work_queue.cc
@@ -13,6 +13,7 @@
#include <utility>
#include "base/containers/contains.h"
+#include "base/memory/raw_ptr_exclusion.h"
#include "base/trace_event/trace_event.h"
namespace cc {
@@ -96,14 +97,14 @@ class DependentIterator {
private:
// `graph_` and `task_` are not a raw_ptr<...> for performance reasons (based
// on analysis of sampling profiler data and tab_search:top100:2020).
- TaskGraph* graph_;
- const Task* task_;
+ RAW_PTR_EXCLUSION TaskGraph* graph_;
+ RAW_PTR_EXCLUSION const Task* task_;
size_t current_index_;
// `current_node_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- TaskGraph::Node* current_node_;
+ RAW_PTR_EXCLUSION TaskGraph::Node* current_node_;
};
} // namespace
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index db52cf6d60a..5ff92dc3acc 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -339,7 +339,9 @@ bool ResourcePool::PrepareForExport(const InUsePoolResource& in_use_resource) {
gpu_backing->mailbox, GL_LINEAR, gpu_backing->texture_target,
gpu_backing->mailbox_sync_token, resource->size(),
gpu_backing->overlay_candidate);
- transferable.read_lock_fences_enabled = gpu_backing->wait_on_fence_required;
+ if (gpu_backing->wait_on_fence_required)
+ transferable.synchronization_type =
+ viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted;
} else {
transferable = viz::TransferableResource::MakeSoftware(
resource->software_backing()->shared_bitmap_id, resource->size(),
@@ -661,9 +663,8 @@ void ResourcePool::PoolResource::OnMemoryDump(
dump->AddScalar(MemoryAllocatorDump::kNameSize,
MemoryAllocatorDump::kUnitsBytes, total_bytes);
- if (is_free) {
- dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, total_bytes);
- }
+ uint64_t free_size = is_free ? total_bytes : 0u;
+ dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, free_size);
}
} // namespace cc
diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h
index 3aedcd75035..a75b2e626de 100644
--- a/chromium/cc/resources/resource_pool.h
+++ b/chromium/cc/resources/resource_pool.h
@@ -202,7 +202,7 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
// `resource_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- PoolResource* resource_ = nullptr;
+ RAW_PTR_EXCLUSION PoolResource* resource_ = nullptr;
};
// When holding gpu resources, the |context_provider| should be non-null,
@@ -392,7 +392,7 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
}
private:
- ResourcePool* const resource_pool_;
+ const raw_ptr<ResourcePool> resource_pool_;
const size_t unique_id_;
const gfx::Size size_;
const viz::ResourceFormat format_;
diff --git a/chromium/cc/resources/resource_pool_unittest.cc b/chromium/cc/resources/resource_pool_unittest.cc
index 24d04f3fbfd..45104e75a1c 100644
--- a/chromium/cc/resources/resource_pool_unittest.cc
+++ b/chromium/cc/resources/resource_pool_unittest.cc
@@ -722,7 +722,9 @@ TEST_F(ResourcePoolTest, MetadataSentToDisplayCompositor) {
EXPECT_EQ(transfer[0].mailbox_holder.sync_token, sync_token);
EXPECT_EQ(transfer[0].mailbox_holder.texture_target, target);
EXPECT_EQ(transfer[0].format, format);
- EXPECT_TRUE(transfer[0].read_lock_fences_enabled);
+ EXPECT_EQ(
+ transfer[0].synchronization_type,
+ viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted);
EXPECT_TRUE(transfer[0].is_overlay_candidate);
resource_pool_->ReleaseResource(std::move(resource));
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index 3be3099800c..0bc092faf29 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -74,11 +74,13 @@ void Scheduler::Stop() {
void Scheduler::SetNeedsImplSideInvalidation(
bool needs_first_draw_on_activation) {
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
- "Scheduler::SetNeedsImplSideInvalidation",
- "needs_first_draw_on_activation",
- needs_first_draw_on_activation);
- state_machine_.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+ {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
+ "Scheduler::SetNeedsImplSideInvalidation",
+ "needs_first_draw_on_activation",
+ needs_first_draw_on_activation);
+ state_machine_.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+ }
ProcessScheduledActions();
}
@@ -107,6 +109,10 @@ void Scheduler::NotifyReadyToActivate() {
ProcessScheduledActions();
}
+bool Scheduler::IsReadyToActivate() {
+ return state_machine_.IsReadyToActivate();
+}
+
void Scheduler::NotifyReadyToDraw() {
// Future work might still needed for crbug.com/352894.
state_machine_.NotifyReadyToDraw();
@@ -175,10 +181,16 @@ void Scheduler::DidSubmitCompositorFrame(uint32_t frame_token,
base::Microseconds(1), base::Milliseconds(50), 50);
}
- compositor_frame_reporting_controller_->DidSubmitCompositorFrame(
- frame_token, submit_time, begin_main_frame_args_.frame_id,
- last_activate_origin_frame_args_.frame_id, std::move(events_metrics),
- has_missing_content);
+ // Hardware and software draw may occur at the same frame simultaneously for
+ // Android WebView. There is no need to call DidSubmitCompositorFrame here for
+ // software draw.
+ if (!settings_.using_synchronous_renderer_compositor ||
+ !state_machine_.resourceless_draw()) {
+ compositor_frame_reporting_controller_->DidSubmitCompositorFrame(
+ frame_token, submit_time, begin_main_frame_args_.frame_id,
+ last_activate_origin_frame_args_.frame_id, std::move(events_metrics),
+ has_missing_content);
+ }
state_machine_.DidSubmitCompositorFrame();
// There is no need to call ProcessScheduledActions here because
@@ -205,28 +217,27 @@ void Scheduler::SetTreePrioritiesAndScrollState(
void Scheduler::NotifyReadyToCommit(
std::unique_ptr<BeginMainFrameMetrics> details) {
- TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
- compositor_timing_history_->NotifyReadyToCommit();
- compositor_frame_reporting_controller_->NotifyReadyToCommit(
- std::move(details));
- state_machine_.NotifyReadyToCommit();
+ {
+ TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
+ compositor_timing_history_->NotifyReadyToCommit();
+ compositor_frame_reporting_controller_->NotifyReadyToCommit(
+ std::move(details));
+ state_machine_.NotifyReadyToCommit();
+ }
ProcessScheduledActions();
}
-void Scheduler::DidCommit() {
- compositor_timing_history_->DidCommit();
- compositor_frame_reporting_controller_->DidCommit();
-}
-
void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) {
- TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason",
- CommitEarlyOutReasonToString(reason));
- compositor_timing_history_->BeginMainFrameAborted();
- auto frame_id = last_dispatched_begin_main_frame_args_.frame_id;
- compositor_frame_reporting_controller_->BeginMainFrameAborted(frame_id,
- reason);
-
- state_machine_.BeginMainFrameAborted(reason);
+ {
+ TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason",
+ CommitEarlyOutReasonToString(reason));
+ compositor_timing_history_->BeginMainFrameAborted();
+ auto frame_id = last_dispatched_begin_main_frame_args_.frame_id;
+ compositor_frame_reporting_controller_->BeginMainFrameAborted(frame_id,
+ reason);
+
+ state_machine_.BeginMainFrameAborted(reason);
+ }
ProcessScheduledActions();
}
@@ -247,18 +258,22 @@ void Scheduler::DidPresentCompositorFrame(
}
void Scheduler::DidLoseLayerTreeFrameSink() {
- TRACE_EVENT0("cc", "Scheduler::DidLoseLayerTreeFrameSink");
- state_machine_.DidLoseLayerTreeFrameSink();
- UpdateCompositorTimingHistoryRecordingEnabled();
+ {
+ TRACE_EVENT0("cc", "Scheduler::DidLoseLayerTreeFrameSink");
+ state_machine_.DidLoseLayerTreeFrameSink();
+ UpdateCompositorTimingHistoryRecordingEnabled();
+ }
ProcessScheduledActions();
}
void Scheduler::DidCreateAndInitializeLayerTreeFrameSink() {
- TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeLayerTreeFrameSink");
- DCHECK(!observing_begin_frame_source_);
- DCHECK(!begin_impl_frame_deadline_timer_.IsRunning());
- state_machine_.DidCreateAndInitializeLayerTreeFrameSink();
- UpdateCompositorTimingHistoryRecordingEnabled();
+ {
+ TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeLayerTreeFrameSink");
+ DCHECK(!observing_begin_frame_source_);
+ DCHECK(!begin_impl_frame_deadline_timer_.IsRunning());
+ state_machine_.DidCreateAndInitializeLayerTreeFrameSink();
+ UpdateCompositorTimingHistoryRecordingEnabled();
+ }
ProcessScheduledActions();
}
@@ -356,9 +371,11 @@ void Scheduler::PostPendingBeginFrameTask() {
void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
if (state_machine_.begin_frame_source_paused() == paused)
return;
- TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
- TRACE_EVENT_SCOPE_THREAD, "paused", paused);
- state_machine_.SetBeginFrameSourcePaused(paused);
+ {
+ TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
+ TRACE_EVENT_SCOPE_THREAD, "paused", paused);
+ state_machine_.SetBeginFrameSourcePaused(paused);
+ }
ProcessScheduledActions();
}
@@ -763,24 +780,26 @@ void Scheduler::ScheduleBeginImplFrameDeadline() {
}
void Scheduler::OnBeginImplFrameDeadline() {
- TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline");
- begin_impl_frame_deadline_timer_.Stop();
- // We split the deadline actions up into two phases so the state machine
- // has a chance to trigger actions that should occur durring and after
- // the deadline separately. For example:
- // * Sending the BeginMainFrame will not occur after the deadline in
- // order to wait for more user-input before starting the next commit.
- // * Creating a new OuputSurface will not occur during the deadline in
- // order to allow the state machine to "settle" first.
- compositor_timing_history_->RecordDeadlineMode(deadline_mode_);
- if (!settings_.using_synchronous_renderer_compositor) {
- compositor_timing_history_->WillFinishImplFrame(
- state_machine_.needs_redraw());
- compositor_frame_reporting_controller_->OnFinishImplFrame(
- begin_main_frame_args_.frame_id);
- }
+ {
+ TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline");
+ begin_impl_frame_deadline_timer_.Stop();
+ // We split the deadline actions up into two phases so the state machine
+ // has a chance to trigger actions that should occur during and after
+ // the deadline separately. For example:
+ // * Sending the BeginMainFrame will not occur after the deadline in
+ // order to wait for more user-input before starting the next commit.
+ // * Creating a new OutputSurface will not occur during the deadline in
+ // order to allow the state machine to "settle" first.
+ compositor_timing_history_->RecordDeadlineMode(deadline_mode_);
+ if (!settings_.using_synchronous_renderer_compositor) {
+ compositor_timing_history_->WillFinishImplFrame(
+ state_machine_.needs_redraw());
+ compositor_frame_reporting_controller_->OnFinishImplFrame(
+ begin_main_frame_args_.frame_id);
+ }
- state_machine_.OnBeginImplFrameDeadline();
+ state_machine_.OnBeginImplFrameDeadline();
+ }
ProcessScheduledActions();
if (settings_.using_synchronous_renderer_compositor)
@@ -817,6 +836,13 @@ void Scheduler::DrawForced() {
bool drawing_with_new_active_tree =
state_machine_.active_tree_needs_first_draw() &&
!state_machine_.previous_pending_tree_was_impl_side();
+ if (drawing_with_new_active_tree) {
+ TRACE_EVENT_WITH_FLOW1(
+ "viz,benchmark", "Graphics.Pipeline.DrawForced",
+ TRACE_ID_GLOBAL(last_activate_origin_frame_args().trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "trace_id",
+ last_activate_origin_frame_args().trace_id);
+ }
compositor_timing_history_->WillDraw();
state_machine_.WillDraw();
DrawResult result = client_->ScheduledActionDrawForced();
@@ -826,9 +852,11 @@ void Scheduler::DrawForced() {
}
void Scheduler::SetDeferBeginMainFrame(bool defer_begin_main_frame) {
- TRACE_EVENT1("cc", "Scheduler::SetDeferBeginMainFrame",
- "defer_begin_main_frame", defer_begin_main_frame);
- state_machine_.SetDeferBeginMainFrame(defer_begin_main_frame);
+ {
+ TRACE_EVENT1("cc", "Scheduler::SetDeferBeginMainFrame",
+ "defer_begin_main_frame", defer_begin_main_frame);
+ state_machine_.SetDeferBeginMainFrame(defer_begin_main_frame);
+ }
ProcessScheduledActions();
}
@@ -881,15 +909,20 @@ void Scheduler::ProcessScheduledActions() {
state_machine_.WillNotifyBeginMainFrameNotExpectedSoon();
BeginMainFrameNotExpectedSoon();
break;
- case SchedulerStateMachine::Action::COMMIT: {
- bool commit_has_no_updates = false;
- state_machine_.WillCommit(commit_has_no_updates);
+ case SchedulerStateMachine::Action::COMMIT:
+ state_machine_.WillCommit(/*commit_had_no_updates=*/false);
compositor_timing_history_->WillCommit();
compositor_frame_reporting_controller_->WillCommit();
client_->ScheduledActionCommit();
+ compositor_timing_history_->DidCommit();
+ compositor_frame_reporting_controller_->DidCommit();
+ state_machine_.DidCommit();
last_commit_origin_frame_args_ = last_dispatched_begin_main_frame_args_;
break;
- }
+ case SchedulerStateMachine::Action::POST_COMMIT:
+ client_->ScheduledActionPostCommit();
+ state_machine_.DidPostCommit();
+ break;
case SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE:
compositor_timing_history_->WillActivate();
compositor_frame_reporting_controller_->WillActivate();
@@ -911,12 +944,11 @@ void Scheduler::ProcessScheduledActions() {
case SchedulerStateMachine::Action::DRAW_FORCED:
DrawForced();
break;
- case SchedulerStateMachine::Action::DRAW_ABORT: {
+ case SchedulerStateMachine::Action::DRAW_ABORT:
// No action is actually performed, but this allows the state machine to
// drain the pipeline without actually drawing.
state_machine_.AbortDraw();
break;
- }
case SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
state_machine_.WillBeginLayerTreeFrameSinkCreation();
client_->ScheduledActionBeginLayerTreeFrameSinkCreation();
@@ -925,12 +957,11 @@ void Scheduler::ProcessScheduledActions() {
state_machine_.WillPrepareTiles();
client_->ScheduledActionPrepareTiles();
break;
- case SchedulerStateMachine::Action::INVALIDATE_LAYER_TREE_FRAME_SINK: {
+ case SchedulerStateMachine::Action::INVALIDATE_LAYER_TREE_FRAME_SINK:
state_machine_.WillInvalidateLayerTreeFrameSink();
client_->ScheduledActionInvalidateLayerTreeFrameSink(
state_machine_.RedrawPending());
break;
- }
}
} while (action != SchedulerStateMachine::Action::NONE);
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index 179b0e4202c..bf83e8447a7 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -67,6 +67,7 @@ class SchedulerClient {
// compositor thread, which allows Compositor thread to update its layer tree
// to match the state of the layer tree on the main thread.
virtual void ScheduledActionCommit() = 0;
+ virtual void ScheduledActionPostCommit() = 0;
virtual void ScheduledActionActivateSyncTree() = 0;
virtual void ScheduledActionBeginLayerTreeFrameSinkCreation() = 0;
virtual void ScheduledActionPrepareTiles() = 0;
@@ -132,6 +133,7 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
// pending_tree, call this method to notify that this pending tree is ready to
// be activated, that is to be copied to the active tree.
void NotifyReadyToActivate();
+ bool IsReadyToActivate();
void NotifyReadyToDraw();
void SetBeginFrameSource(viz::BeginFrameSource* source);
@@ -176,6 +178,10 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
// new tree can be activated.
void SetNeedsImplSideInvalidation(bool needs_first_draw_on_activation);
+ bool pending_tree_is_ready_for_activation() const {
+ return state_machine_.pending_tree_is_ready_for_activation();
+ }
+
// Drawing should result in submitting a CompositorFrame to the
// LayerTreeFrameSink and then calling this.
void DidSubmitCompositorFrame(uint32_t frame_token,
@@ -195,7 +201,6 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
// main thread updates are completed to signal it is ready for the commmit.
void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
void BeginMainFrameAborted(CommitEarlyOutReason reason);
- void DidCommit();
// In the PrepareTiles step, compositor thread divides the layers into tiles
// to reduce cost of raster large layers. Then, each tile is rastered by a
@@ -262,6 +267,9 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
const viz::BeginFrameArgs& last_dispatched_begin_main_frame_args() const {
return last_dispatched_begin_main_frame_args_;
}
+ const viz::BeginFrameArgs& last_commit_origin_frame_args() const {
+ return last_commit_origin_frame_args_;
+ }
const viz::BeginFrameArgs& last_activate_origin_frame_args() const {
return last_activate_origin_frame_args_;
}
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index 0e49dca023e..0f9872b52eb 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -167,6 +167,8 @@ SchedulerStateMachine::ActionToProtozeroEnum(Action action) {
case Action::SEND_BEGIN_MAIN_FRAME:
return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME;
case Action::COMMIT:
+ case Action::POST_COMMIT:
+ // TODO(szager): Add CC_SCHEDULER_ACTION_POST_COMMIT to perfetto
return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_COMMIT;
case Action::ACTIVATE_SYNC_TREE:
return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE;
@@ -621,6 +623,20 @@ bool SchedulerStateMachine::ShouldCommit() const {
return true;
}
+void SchedulerStateMachine::DidCommit() {
+ DCHECK(!needs_post_commit_);
+ needs_post_commit_ = true;
+}
+
+bool SchedulerStateMachine::ShouldRunPostCommit() const {
+ return needs_post_commit_;
+}
+
+void SchedulerStateMachine::DidPostCommit() {
+ DCHECK(needs_post_commit_);
+ needs_post_commit_ = false;
+}
+
bool SchedulerStateMachine::ShouldPrepareTiles() const {
// In full-pipeline mode, we need to prepare tiles ASAP to ensure that we
// don't get stuck.
@@ -662,6 +678,10 @@ bool SchedulerStateMachine::ShouldInvalidateLayerTreeFrameSink() const {
}
SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
+ if (ShouldSendBeginMainFrame())
+ return Action::SEND_BEGIN_MAIN_FRAME;
+ if (ShouldRunPostCommit())
+ return Action::POST_COMMIT;
if (ShouldActivateSyncTree())
return Action::ACTIVATE_SYNC_TREE;
if (ShouldCommit())
@@ -675,8 +695,6 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
else
return Action::DRAW_IF_POSSIBLE;
}
- if (ShouldSendBeginMainFrame())
- return Action::SEND_BEGIN_MAIN_FRAME;
if (ShouldPerformImplSideInvalidation())
return Action::PERFORM_IMPL_SIDE_INVALIDATION;
if (ShouldPrepareTiles())
@@ -1436,8 +1454,7 @@ void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) {
SetNeedsBeginMainFrame();
return;
case CommitEarlyOutReason::FINISHED_NO_UPDATES:
- bool commit_has_no_updates = true;
- WillCommit(commit_has_no_updates);
+ WillCommit(/*commit_had_no_updates=*/true);
return;
}
}
@@ -1469,6 +1486,10 @@ bool SchedulerStateMachine::NotifyReadyToActivate() {
return true;
}
+bool SchedulerStateMachine::IsReadyToActivate() {
+ return pending_tree_is_ready_for_activation_;
+}
+
void SchedulerStateMachine::NotifyReadyToDraw() {
active_tree_is_ready_to_draw_ = true;
}
diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h
index 929d58550de..c2f3239f32e 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.h
+++ b/chromium/cc/scheduler/scheduler_state_machine.h
@@ -136,6 +136,7 @@ class CC_EXPORT SchedulerStateMachine {
NONE,
SEND_BEGIN_MAIN_FRAME,
COMMIT,
+ POST_COMMIT,
ACTIVATE_SYNC_TREE,
PERFORM_IMPL_SIDE_INVALIDATION,
DRAW_IF_POSSIBLE,
@@ -158,6 +159,8 @@ class CC_EXPORT SchedulerStateMachine {
void WillNotifyBeginMainFrameNotExpectedUntil();
void WillNotifyBeginMainFrameNotExpectedSoon();
void WillCommit(bool commit_had_no_updates);
+ void DidCommit();
+ void DidPostCommit();
void WillActivate();
void WillDraw();
void WillBeginLayerTreeFrameSinkCreation();
@@ -287,6 +290,7 @@ class CC_EXPORT SchedulerStateMachine {
// the notification received updated the state for the current pending tree,
// if any.
bool NotifyReadyToActivate();
+ bool IsReadyToActivate();
// Indicates the active tree's visible tiles are ready to be drawn.
void NotifyReadyToDraw();
@@ -354,6 +358,12 @@ class CC_EXPORT SchedulerStateMachine {
return aborted_begin_main_frame_count_;
}
+ bool pending_tree_is_ready_for_activation() const {
+ return pending_tree_is_ready_for_activation_;
+ }
+
+ bool resourceless_draw() const { return resourceless_draw_; }
+
protected:
bool BeginFrameRequiredForAction() const;
bool BeginFrameNeededForVideo() const;
@@ -380,6 +390,7 @@ class CC_EXPORT SchedulerStateMachine {
bool ShouldActivateSyncTree() const;
bool ShouldSendBeginMainFrame() const;
bool ShouldCommit() const;
+ bool ShouldRunPostCommit() const;
bool ShouldPrepareTiles() const;
bool ShouldInvalidateLayerTreeFrameSink() const;
bool ShouldNotifyBeginMainFrameNotExpectedUntil() const;
@@ -440,6 +451,7 @@ class CC_EXPORT SchedulerStateMachine {
bool needs_prepare_tiles_ = false;
bool needs_begin_main_frame_ = false;
bool needs_one_begin_impl_frame_ = false;
+ bool needs_post_commit_ = false;
bool visible_ = false;
bool begin_frame_source_paused_ = false;
bool resourceless_draw_ = false;
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index f331078d623..3cfc032b8c3 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -55,7 +55,7 @@
SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION); \
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE); \
state.CreateAndInitializeLayerTreeFrameSinkWithActivatedCommit(); \
- state.SetCanDraw(true);
+ state.SetCanDraw(true)
namespace cc {
@@ -99,6 +99,8 @@ const char* ActionToString(SchedulerStateMachine::Action action) {
return "Action::SEND_BEGIN_MAIN_FRAME";
case Action::COMMIT:
return "Action::COMMIT";
+ case Action::POST_COMMIT:
+ return "Action::POST_COMMIT";
case Action::ACTIVATE_SYNC_TREE:
return "Action::ACTIVATE_SYNC_TREE";
case Action::DRAW_IF_POSSIBLE:
@@ -260,9 +262,14 @@ void PerformAction(StateMachine* sm, SchedulerStateMachine::Action action) {
case SchedulerStateMachine::Action::COMMIT: {
bool commit_has_no_updates = false;
sm->WillCommit(commit_has_no_updates);
+ sm->DidCommit();
return;
}
+ case SchedulerStateMachine::Action::POST_COMMIT:
+ sm->DidPostCommit();
+ return;
+
case SchedulerStateMachine::Action::DRAW_FORCED:
case SchedulerStateMachine::Action::DRAW_IF_POSSIBLE: {
sm->WillDraw();
@@ -343,6 +350,40 @@ TEST(SchedulerStateMachineTest, BeginFrameNeeded) {
EXPECT_FALSE(state.BeginFrameNeeded());
}
+TEST(SchedulerStateMachineTest, BeginMainFrameIsHighestPriorityAction) {
+ SchedulerSettings default_scheduler_settings;
+ default_scheduler_settings.main_frame_before_activation_enabled = true;
+ StateMachine state(default_scheduler_settings);
+ SET_UP_STATE(state);
+ state.SetNeedsBeginMainFrame();
+ state.IssueNextBeginImplFrame();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
+
+ // Still need to active, but sending BMF takes priority.
+ state.SetNeedsBeginMainFrame();
+ state.IssueNextBeginImplFrame();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
+
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION(SchedulerStateMachine::Action::DRAW_IF_POSSIBLE);
+
+ // Still need to draw, but sending BMF takes priority.
+ state.SetNeedsBeginMainFrame();
+ state.IssueNextBeginImplFrame();
+ EXPECT_ACTION(SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+}
+
TEST(SchedulerStateMachineTest,
TestNextActionNotifyBeginMainFrameNotExpectedUntil) {
SchedulerSettings default_scheduler_settings;
@@ -500,7 +541,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
StateMachine state(scheduler_settings);
state.SetBeginMainFrameState(
SchedulerStateMachine::BeginMainFrameState::IDLE);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsRedraw(false);
state.SetNeedsBeginMainFrame();
@@ -514,6 +555,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BeginMainFrameState::IDLE);
@@ -537,6 +579,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
@@ -552,7 +595,7 @@ TEST(SchedulerStateMachineTest,
FailedDrawForAnimationCheckerboardSetsNeedsCommitAndRetriesDraw) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginFrameNeeded());
@@ -589,7 +632,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginFrameNeeded());
@@ -623,6 +666,7 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) {
// Finish the commit and activation.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -646,7 +690,7 @@ TEST(SchedulerStateMachineTest,
SchedulerSettings scheduler_settings;
scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced = 1;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start a commit.
state.SetNeedsBeginMainFrame();
@@ -671,6 +715,7 @@ TEST(SchedulerStateMachineTest,
// continue the commit as usual.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
EXPECT_TRUE(state.RedrawPending());
@@ -700,7 +745,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced =
draw_limit;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start a commit.
state.SetNeedsBeginMainFrame();
@@ -759,7 +804,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start a draw.
state.SetNeedsRedraw(true);
@@ -795,7 +840,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsRedraw(true);
// Draw the first frame.
@@ -976,12 +1021,13 @@ TEST(SchedulerStateMachineTest,
state.SetNeedsRedraw(true);
state.SetCanDraw(false);
state.IssueNextBeginImplFrame();
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_ABORT);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_ABORT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
state.OnBeginImplFrameDeadline();
@@ -992,7 +1038,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsBeginMainFrame();
EXPECT_TRUE(state.BeginFrameNeeded());
@@ -1034,6 +1080,7 @@ TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) {
// Finish the commit and activate, then make sure we start the next commit
// immediately and draw on the next BeginImplFrame.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_ACTION_UPDATE_STATE(
@@ -1052,7 +1099,7 @@ TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) {
TEST(SchedulerStateMachineTest, TestFullCycle) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1072,6 +1119,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) {
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// Activate.
state.NotifyReadyToActivate();
@@ -1097,7 +1145,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) {
TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1108,6 +1156,7 @@ TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1120,6 +1169,7 @@ TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
}
TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) {
@@ -1127,7 +1177,7 @@ TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) {
scheduler_settings.commit_to_active_tree = true;
scheduler_settings.main_frame_before_activation_enabled = false;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1138,6 +1188,7 @@ TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1163,6 +1214,7 @@ TEST(SchedulerStateMachineTest, AbortedMainFrameDoesNotResetPendingTree) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
EXPECT_TRUE(state.has_pending_tree());
state.OnBeginImplFrameDeadline();
@@ -1197,6 +1249,7 @@ TEST(SchedulerStateMachineTest, AbortedMainFrameDoesNotResetPendingTree) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_FALSE(state.has_pending_tree());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
EXPECT_TRUE(state.has_pending_tree());
}
@@ -1206,7 +1259,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
scheduler_settings.commit_to_active_tree = true;
scheduler_settings.main_frame_before_activation_enabled = false;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1226,6 +1279,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
SchedulerStateMachine::BeginMainFrameState::READY_TO_COMMIT);
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// Commit always calls NotifyReadyToActivate in this mode.
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1263,6 +1317,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
@@ -1284,7 +1339,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1308,6 +1363,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
// First commit and activate.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
@@ -1385,7 +1441,7 @@ TEST(SchedulerStateMachineTest, TestNoRequestLayerTreeFrameSinkWhenInvisible) {
TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -1508,7 +1564,7 @@ TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
EXPECT_NE(SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION,
state.NextAction());
@@ -1534,7 +1590,7 @@ TEST(SchedulerStateMachineTest,
TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
EXPECT_NE(SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION,
state.NextAction());
@@ -1584,6 +1640,7 @@ TEST(SchedulerStateMachineTest,
// Finish the commit, which should make the surface active.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_EQ(state.layer_tree_frame_sink_state(),
SchedulerStateMachine::LayerTreeFrameSinkState::
WAITING_FOR_FIRST_ACTIVATION);
@@ -1633,6 +1690,7 @@ TEST(SchedulerStateMachineTest,
// Activate so we need the first draw
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
@@ -1650,7 +1708,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Get a commit in flight.
state.SetNeedsBeginMainFrame();
@@ -1679,6 +1737,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
// Finish the frame, commit and activate.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1708,7 +1767,7 @@ TEST(SchedulerStateMachineTest,
TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Get a commit in flight.
state.SetNeedsBeginMainFrame();
@@ -1737,6 +1796,7 @@ TEST(SchedulerStateMachineTest,
// Finish the frame, and commit and activate.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
@@ -1771,6 +1831,7 @@ TEST(SchedulerStateMachineTest,
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1786,7 +1847,7 @@ TEST(SchedulerStateMachineTest,
DontDrawBeforeCommitAfterLostLayerTreeFrameSink) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsRedraw(true);
@@ -1806,7 +1867,7 @@ TEST(SchedulerStateMachineTest,
TestShouldAbortCurrentFrameAfterLostLayerTreeFrameSink) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetBeginMainFrameState(
SchedulerStateMachine::BeginMainFrameState::SENT);
@@ -1816,6 +1877,7 @@ TEST(SchedulerStateMachineTest,
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -1882,6 +1944,7 @@ TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
// because we are not visible.
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_ABORT);
@@ -1907,6 +1970,7 @@ TEST(SchedulerStateMachineTest,
state.NotifyReadyToCommit();
EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_ABORT);
@@ -1916,7 +1980,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsBeginMainFrame();
state.DidLoseLayerTreeFrameSink();
@@ -1941,7 +2005,7 @@ TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
state.SetCanDraw(false);
@@ -1968,7 +2032,7 @@ TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
TEST(SchedulerStateMachineTest, ForceDrawForResourcelessSoftwareDraw) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetResourcelessSoftwareDraw(true);
EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
@@ -2018,7 +2082,7 @@ TEST(SchedulerStateMachineTest,
TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// This test mirrors what happens during the first frame of a scroll gesture.
// First we get the input event and a BeginFrame.
@@ -2050,6 +2114,7 @@ void FinishPreviousCommitAndDrawWithoutExitingDeadline(
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
@@ -2067,7 +2132,7 @@ void FinishPreviousCommitAndDrawWithoutExitingDeadline(
TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// This test ensures that impl-draws are prioritized over main thread updates
// in prefer impl latency mode.
@@ -2121,7 +2186,7 @@ TEST(SchedulerStateMachineTest,
TestTriggerDeadlineImmediatelyOnLostLayerTreeFrameSink) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsBeginMainFrame();
@@ -2141,7 +2206,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestTriggerDeadlineImmediatelyWhenInvisible) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsBeginMainFrame();
@@ -2161,7 +2226,7 @@ TEST(SchedulerStateMachineTest,
TestTriggerDeadlineImmediatelyWhenBeginFrameSourcePaused) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetNeedsBeginMainFrame();
@@ -2180,7 +2245,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestDeferBeginMainFrame) {
SchedulerSettings settings;
StateMachine state(settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
state.SetDeferBeginMainFrame(true);
@@ -2322,6 +2387,7 @@ TEST(SchedulerStateMachineTest,
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
state.OnBeginImplFrameDeadline();
@@ -2385,7 +2451,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, NoImplSideInvalidationUntilFrameSinkActive) {
SchedulerSettings settings;
StateMachine state(settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Prefer impl side invalidation over begin main frame.
state.set_should_defer_invalidation_for_fast_main_frame(false);
@@ -2410,6 +2476,7 @@ TEST(SchedulerStateMachineTest, NoImplSideInvalidationUntilFrameSinkActive) {
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.OnBeginImplFrameDeadline();
state.OnBeginImplFrameIdle();
@@ -2452,6 +2519,7 @@ TEST(SchedulerStateMachineTest, ImplSideInvalidationWhenPendingTreeExists) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// Request an impl-side invalidation after the commit. The request should wait
// till the current pending tree is activated.
@@ -2497,6 +2565,7 @@ TEST(SchedulerStateMachineTest, ImplSideInvalidationWhileReadyToCommit) {
state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
EXPECT_TRUE(state.needs_impl_side_invalidation());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_FALSE(state.needs_impl_side_invalidation());
}
@@ -2547,6 +2616,7 @@ TEST(SchedulerStateMachineTest, ImplSideInvalidationsThrottledOnDraw) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
state.NotifyReadyToDraw();
@@ -2595,7 +2665,7 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
SchedulerSettings scheduler_settings;
scheduler_settings.wait_for_all_pipeline_stages_before_draw = true;
StateMachine state(scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
@@ -2634,6 +2704,7 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
state.CurrentBeginImplFrameDeadlineMode());
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// We are blocking on activation.
EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
@@ -2728,7 +2799,7 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
TEST(SchedulerStateMachineTest, AllowSkippingActiveTreeFirstDraws) {
SchedulerSettings settings;
StateMachine state(settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Impl-side invalidation creates a pending tree which is activated but not
// drawn in this frame.
@@ -2751,6 +2822,7 @@ TEST(SchedulerStateMachineTest, AllowSkippingActiveTreeFirstDraws) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// We should be able to activate this tree without drawing the active tree.
state.NotifyReadyToActivate();
@@ -2760,7 +2832,7 @@ TEST(SchedulerStateMachineTest, AllowSkippingActiveTreeFirstDraws) {
TEST(SchedulerStateMachineTest, DelayDrawIfAnimationWorkletsPending) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// This test verifies that having pending mutations from Animation Worklets on
// the active tree will not trigger the deadline early.
@@ -2771,6 +2843,7 @@ TEST(SchedulerStateMachineTest, DelayDrawIfAnimationWorkletsPending) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
@@ -2826,7 +2899,7 @@ TEST(SchedulerStateMachineTest, DelayDrawIfAnimationWorkletsPending) {
TEST(SchedulerStateMachineTest, BlockActivationIfAnimationWorkletsPending) {
SchedulerSettings settings;
StateMachine state(settings);
- SET_UP_STATE(state)
+ SET_UP_STATE(state);
// Verify that pending mutations from Animation Worklets block activation.
state.SetNeedsBeginMainFrame();
@@ -2836,6 +2909,7 @@ TEST(SchedulerStateMachineTest, BlockActivationIfAnimationWorkletsPending) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
state.NotifyAnimationWorkletStateChange(
SchedulerStateMachine::AnimationWorkletState::PROCESSING,
SchedulerStateMachine::TreeType::PENDING);
@@ -2859,6 +2933,7 @@ TEST(SchedulerStateMachineTest, BlockActivationIfPaintWorkletsPending) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
// Post-commit, we start working on PaintWorklets. It is not valid to activate
@@ -2887,6 +2962,7 @@ TEST(SchedulerStateMachineTest,
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
// Even if we are aborting the frame, we must paint the pending tree before we
@@ -2918,6 +2994,7 @@ TEST(SchedulerStateMachineTest, TestFullPipelineModeDoesntBlockAfterCommit) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
state.NotifyReadyToActivate();
@@ -2939,6 +3016,7 @@ TEST(SchedulerStateMachineTest, TestFullPipelineModeDoesntBlockAfterCommit) {
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::POST_COMMIT);
// ... and make sure we're in a state where we can proceed,
// rather than draw being blocked by the pending tree.
state.OnBeginImplFrameDeadline();
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index 3e404b232f2..498884d549d 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -201,7 +201,11 @@ class FakeSchedulerClient : public SchedulerClient,
EXPECT_FALSE(inside_action_);
base::AutoReset<bool> mark_inside(&inside_action_, true);
PushAction("ScheduledActionCommit");
- scheduler_->DidCommit();
+ }
+ void ScheduledActionPostCommit() override {
+ EXPECT_FALSE(inside_action_);
+ base::AutoReset<bool> mark_inside(&inside_action_, true);
+ PushAction("ScheduledActionPostCommit");
}
void ScheduledActionActivateSyncTree() override {
EXPECT_FALSE(inside_action_);
@@ -680,7 +684,7 @@ TEST_F(SchedulerTest, RequestCommit) {
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
@@ -795,7 +799,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// Finish the first commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
@@ -824,7 +828,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// to trigger the deadline early.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -1397,7 +1401,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -1435,7 +1439,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostLayerTreeFrameSink) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -1470,6 +1474,7 @@ void SchedulerTest::AdvanceAndMissOneFrame() {
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
"ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
+ "ScheduledActionPostCommit",
"ScheduledActionActivateSyncTree");
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
client_->Reset();
@@ -1713,7 +1718,8 @@ TEST_F(SchedulerTest, MainFrameNotSkippedAfterCanDrawChanges) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
- EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree");
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
scheduler_->SetCanDraw(false);
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
@@ -1758,7 +1764,8 @@ TEST_F(SchedulerTest, MainFrameNotSkippedWhenNoTimingHistory) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
- EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree");
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
// Clear the timing history. Make sure we don't skip the main frame until we
@@ -1788,7 +1795,8 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {
scheduler_->NotifyReadyToActivate();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
- EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
// Verify impl thread consistently operates in high latency mode
@@ -1814,6 +1822,7 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {
// Verify that we don't skip the actions of the BeginImplFrame
EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
+ "ScheduledActionPostCommit",
"ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
}
@@ -1885,7 +1894,7 @@ void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) {
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
// NotifyReadyToActivate should trigger the activation.
@@ -1939,7 +1948,7 @@ void SchedulerTest::BeginFramesNotFromClient_IsDrawThrottled(
// NotifyReadyToCommit should trigger the pending commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
// NotifyReadyToActivate should trigger the activation and draw.
@@ -2045,7 +2054,8 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterBeginFrameStarted) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree");
client_->Reset();
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -2090,7 +2100,8 @@ TEST_F(SchedulerTest,
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionBeginLayerTreeFrameSinkCreation");
}
@@ -2109,7 +2120,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterReadyToCommit) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->DidLoseLayerTreeFrameSink();
@@ -2165,7 +2176,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWithDelayBasedBeginFrameSource) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToActivate should trigger the activation.
@@ -2201,7 +2212,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWhenIdle) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -2233,7 +2244,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
@@ -2259,7 +2270,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
@@ -2446,7 +2457,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceWhenNotObserving) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -2540,7 +2551,8 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Requested) {
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
- "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ "ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
client_->Reset();
@@ -2576,7 +2588,8 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Unrequested) {
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
- "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ "ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
client_->Reset();
@@ -2614,7 +2627,8 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonOnlyOncePerFrame) {
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
- "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ "ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
client_->Reset();
@@ -2655,7 +2669,8 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_AlreadyIdle) {
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
- "ScheduledActionCommit", "ScheduledActionActivateSyncTree",
+ "ScheduledActionCommit", "ScheduledActionPostCommit",
+ "ScheduledActionActivateSyncTree",
"ScheduledActionDrawIfPossible");
client_->Reset();
@@ -3012,7 +3027,7 @@ TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {
client_->Reset();
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -3130,7 +3145,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAllowsActivateBeforeDraw) {
// Commit and activate.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
@@ -3148,7 +3163,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAllowsActivateBeforeDraw) {
// Commit and activate.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
@@ -3208,7 +3223,7 @@ TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
client_->Reset();
scheduler_->NotifyReadyToActivate();
@@ -3376,7 +3391,7 @@ TEST_F(SchedulerTest, ImplSideInvalidationsMergedWithCommit) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_FALSE(scheduler_->needs_impl_side_invalidation());
}
@@ -3565,7 +3580,7 @@ TEST_F(SchedulerTest, BeginFrameAckForFinishedImplFrame) {
// Allow the commit now. NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
@@ -3920,7 +3935,7 @@ TEST_F(SchedulerTest,
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
// Draw deadline.
client_->Reset();
@@ -4182,7 +4197,7 @@ TEST_F(SchedulerTestForPowerMode, BeginMainFramePowerModeVoter) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
scheduler_->NotifyReadyToCommit(nullptr);
- EXPECT_ACTIONS("ScheduledActionCommit");
+ EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
PowerMode::kMainThreadAnimation);
client_->Reset();
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 3507754e0b8..f9c24c2c0c5 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -466,6 +466,44 @@ sk_sp<SkImage> MakeTextureImage(viz::RasterContextProvider* context,
return uploaded_image;
}
+// We use this below, instead of just a std::unique_ptr, so that we can run
+// a Finch experiment to check the impact of not using discardable memory on the
+// GPU decode path.
+class HeapDiscardableMemory : public base::DiscardableMemory {
+ public:
+ explicit HeapDiscardableMemory(size_t size)
+ : memory_(new char[size]), size_(size) {}
+ ~HeapDiscardableMemory() override = default;
+ [[nodiscard]] bool Lock() override {
+ // Locking only succeeds when we have not yet discarded the memory (i.e. if
+ // we have never called |Unlock()|.)
+ return memory_ != nullptr;
+ }
+ void Unlock() override { Discard(); }
+ void* data() const override {
+ DCHECK(memory_);
+ return static_cast<void*>(memory_.get());
+ }
+ void DiscardForTesting() override { Discard(); }
+ base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
+ const char* name,
+ base::trace_event::ProcessMemoryDump* pmd) const override {
+ auto* dump = pmd->CreateAllocatorDump(name);
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes, size_);
+ return dump;
+ }
+
+ private:
+ void Discard() {
+ memory_.reset();
+ size_ = 0;
+ }
+
+ std::unique_ptr<char[]> memory_;
+ size_t size_;
+};
+
} // namespace
// Extract the information to uniquely identify a DrawImage for the purposes of
@@ -953,6 +991,7 @@ GpuImageDecodeCache::GpuImageDecodeCache(
max_working_set_bytes_(max_working_set_bytes),
max_working_set_items_(kMaxItemsInWorkingSet),
dark_mode_filter_(dark_mode_filter) {
+ DCHECK_NE(generator_client_id_, PaintImage::kDefaultGeneratorClientId);
// Note that to compute |allow_accelerated_jpeg_decodes_| and
// |allow_accelerated_webp_decodes_|, the last thing we check is the feature
// flag. That's because we want to ensure that we're in OOP-R mode and the
@@ -1986,10 +2025,17 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(
sk_sp<SkImage> image_v;
{
base::AutoUnlock unlock(lock_);
- auto* allocator = base::DiscardableMemoryAllocator::GetInstance();
- backing_memory = allocator->AllocateLockedDiscardableMemoryWithRetryOrDie(
- image_data->size, base::BindOnce(&GpuImageDecodeCache::ClearCache,
- base::Unretained(this)));
+ if (base::FeatureList::IsEnabled(
+ features::kNoDiscardableMemoryForGpuDecodePath)) {
+ backing_memory =
+ std::make_unique<HeapDiscardableMemory>(image_data->size);
+ } else {
+ auto* allocator = base::DiscardableMemoryAllocator::GetInstance();
+ backing_memory = allocator->AllocateLockedDiscardableMemoryWithRetryOrDie(
+ image_data->size, base::BindOnce(&GpuImageDecodeCache::ClearCache,
+ base::Unretained(this)));
+ }
+
sk_sp<SkColorSpace> color_space =
ColorSpaceForImageDecode(draw_image, image_data->mode);
auto release_proc = [](const void*, void*) {};
@@ -2136,7 +2182,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
sk_sp<SkColorSpace> decoded_target_colorspace =
ColorSpaceForImageDecode(draw_image, image_data->mode);
if (target_color_space && decoded_target_colorspace) {
- if (!gfx::ColorSpace(*decoded_target_colorspace).IsPQOrHLG() &&
+ if (!gfx::ColorSpace(*decoded_target_colorspace).IsToneMappedByDefault() &&
SkColorSpace::Equals(target_color_space.get(),
decoded_target_colorspace.get())) {
target_color_space = nullptr;
@@ -2157,7 +2203,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
} else if (image_data->yuva_pixmap_info.has_value()) {
const bool needs_tone_mapping =
decoded_target_colorspace &&
- gfx::ColorSpace(*decoded_target_colorspace).IsPQOrHLG();
+ gfx::ColorSpace(*decoded_target_colorspace).IsToneMappedByDefault();
UploadImageIfNecessary_TransferCache_SoftwareDecode_YUVA(
draw_image, image_data, decoded_target_colorspace,
needs_tone_mapping ? target_color_params : absl::nullopt);
@@ -2861,8 +2907,17 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
image_data->upload_scale_mip_level;
bool quality_is_compatible =
CalculateDesiredFilterQuality(draw_image) <= image_data->quality;
- bool color_is_compatible =
- image_data->target_color_params == draw_image.target_color_params();
+ sk_sp<SkColorSpace> decoded_target_colorspace =
+ ColorSpaceForImageDecode(draw_image, image_data->mode);
+ bool color_is_compatible = false;
+ if (!decoded_target_colorspace ||
+ !gfx::ColorSpace(*decoded_target_colorspace).IsToneMappedByDefault()) {
+ color_is_compatible = image_data->target_color_params.color_space ==
+ draw_image.target_color_space();
+ } else {
+ color_is_compatible =
+ image_data->target_color_params == draw_image.target_color_params();
+ }
if (!color_is_compatible)
return false;
if (is_scaled && (!scale_is_compatible || !quality_is_compatible))
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
index 6230a6b7cd6..0e8bba94795 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -55,7 +55,7 @@ class GpuImageDecodeCachePerfTest
ASSERT_EQ(result, gpu::ContextResult::kSuccess);
cache_ = std::make_unique<GpuImageDecodeCache>(
context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType,
- kCacheSize, MaxTextureSize(), PaintImage::kDefaultGeneratorClientId,
+ kCacheSize, MaxTextureSize(), PaintImage::GetNextGeneratorClientId(),
nullptr);
}
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index a2b72d799c4..b72b54d5569 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -12,6 +12,7 @@
#include <tuple>
#include <vector>
+#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
@@ -380,7 +381,8 @@ class GpuImageDecodeCacheTest
bool /* allow_accelerated_jpeg_decoding */,
bool /* allow_accelerated_webp_decoding */,
bool /* advertise_accelerated_decoding */,
- bool /* enable_clipped_image_scaling */>> {
+ bool /* enable_clipped_image_scaling */,
+ bool /* no_discardable_memory */>> {
public:
void SetUp() override {
std::vector<base::Feature> enabled_features;
@@ -390,6 +392,10 @@ class GpuImageDecodeCacheTest
allow_accelerated_webp_decoding_ = std::get<4>(GetParam());
if (allow_accelerated_webp_decoding_)
enabled_features.push_back(features::kVaapiWebPImageDecodeAcceleration);
+ no_discardable_memory_ = std::get<7>(GetParam());
+ if (no_discardable_memory_)
+ enabled_features.push_back(
+ features::kNoDiscardableMemoryForGpuDecodePath);
feature_list_.InitWithFeatures(enabled_features,
{} /* disabled_features */);
advertise_accelerated_decoding_ = std::get<5>(GetParam());
@@ -423,7 +429,7 @@ class GpuImageDecodeCacheTest
return std::make_unique<GpuImageDecodeCache>(
context_provider_.get(), use_transfer_cache_, color_type_,
memory_limit_bytes, max_texture_size_,
- PaintImage::kDefaultGeneratorClientId, dark_mode_filter);
+ PaintImage::GetNextGeneratorClientId(), dark_mode_filter);
}
// Returns dimensions for an image that will not fit in GPU memory and hence
@@ -691,6 +697,7 @@ class GpuImageDecodeCacheTest
bool allow_accelerated_webp_decoding_;
bool advertise_accelerated_decoding_;
bool enable_clipped_image_scaling_;
+ bool no_discardable_memory_;
int max_texture_size_ = 0;
};
@@ -3131,7 +3138,7 @@ TEST_P(GpuImageDecodeCacheTest, HighBitDepthYUVDecoding) {
// If `draw_image` is tone mapped, then it will be converted to RGBA
// during tone mapping.
bool color_converted_to_rgba = use_transfer_cache_ &&
- decoded_cs.IsPQOrHLG() &&
+ decoded_cs.IsToneMappedByDefault() &&
cache->SupportsColorSpaceConversion();
if (decodes_to_yuv && !color_converted_to_rgba) {
@@ -3628,7 +3635,8 @@ INSTANTIATE_TEST_SUITE_P(
testing::Values(false) /* allow_accelerated_jpeg_decoding */,
testing::Values(false) /* allow_accelerated_webp_decoding */,
testing::Values(false) /* advertise_accelerated_decoding */,
- testing::Bool() /* enable_clipped_image_scaling */));
+ testing::Bool() /* enable_clipped_image_scaling */,
+ testing::Values(false) /* no_discardable_memory */));
INSTANTIATE_TEST_SUITE_P(
GpuImageDecodeCacheTestsOOPR,
@@ -3640,7 +3648,8 @@ INSTANTIATE_TEST_SUITE_P(
testing::Values(false) /* allow_accelerated_jpeg_decoding */,
testing::Values(false) /* allow_accelerated_webp_decoding */,
testing::Values(false) /* advertise_accelerated_decoding */,
- testing::Values(false) /* enable_clipped_image_scaling */));
+ testing::Values(false) /* enable_clipped_image_scaling */,
+ testing::Values(false) /* no_discardable_memory */));
class GpuImageDecodeCacheWithAcceleratedDecodesTest
: public GpuImageDecodeCacheTest {
@@ -3956,7 +3965,8 @@ INSTANTIATE_TEST_SUITE_P(
testing::Values(true) /* allow_accelerated_jpeg_decoding */,
testing::Values(true) /* allow_accelerated_webp_decoding */,
testing::Values(true) /* advertise_accelerated_decoding */,
- testing::Values(false) /* enable_clipped_image_scaling */));
+ testing::Values(false) /* enable_clipped_image_scaling */,
+ testing::Bool() /* no_discardable_memory */));
class GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest
: public GpuImageDecodeCacheWithAcceleratedDecodesTest {};
@@ -4092,14 +4102,14 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
INSTANTIATE_TEST_SUITE_P(
GpuImageDecodeCacheTestsOOPR,
GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
- testing::Combine(
- testing::Values(kN32_SkColorType),
- testing::Values(true) /* use_transfer_cache */,
- testing::Bool() /* do_yuv_decode */,
- testing::Bool() /* allow_accelerated_jpeg_decoding */,
- testing::Bool() /* allow_accelerated_webp_decoding */,
- testing::Bool() /* advertise_accelerated_decoding */,
- testing::Values(false) /* enable_clipped_image_scaling */));
+ testing::Combine(testing::Values(kN32_SkColorType),
+ testing::Values(true) /* use_transfer_cache */,
+ testing::Bool() /* do_yuv_decode */,
+ testing::Bool() /* allow_accelerated_jpeg_decoding */,
+ testing::Bool() /* allow_accelerated_webp_decoding */,
+ testing::Bool() /* advertise_accelerated_decoding */,
+ testing::Values(false) /* enable_clipped_image_scaling */,
+ testing::Bool() /* no_discardable_memory */));
#undef EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE
#undef EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE
diff --git a/chromium/cc/tiles/picture_layer_tiling.h b/chromium/cc/tiles/picture_layer_tiling.h
index c27c0316bfa..4198f11350c 100644
--- a/chromium/cc/tiles/picture_layer_tiling.h
+++ b/chromium/cc/tiles/picture_layer_tiling.h
@@ -288,7 +288,7 @@ class CC_EXPORT PictureLayerTiling {
// `tiling_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- const PictureLayerTiling* tiling_ = nullptr;
+ RAW_PTR_EXCLUSION const PictureLayerTiling* tiling_ = nullptr;
gfx::Size coverage_rect_max_bounds_;
gfx::Rect coverage_rect_;
@@ -296,7 +296,7 @@ class CC_EXPORT PictureLayerTiling {
// `current_tile_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- Tile* current_tile_ = nullptr;
+ RAW_PTR_EXCLUSION Tile* current_tile_ = nullptr;
gfx::Rect current_geometry_rect_;
int tile_i_ = 0;
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index b709fab69f3..28b6a196983 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -149,6 +149,7 @@ SoftwareImageDecodeCache::SoftwareImageDecodeCache(
color_type_(color_type),
generator_client_id_(generator_client_id),
max_items_in_cache_(kNormalMaxItemsInCacheForSoftware) {
+ DCHECK_NE(generator_client_id_, PaintImage::kDefaultGeneratorClientId);
// In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
// Don't register a dump provider in these cases.
if (base::ThreadTaskRunnerHandle::IsSet()) {
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest.cc b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
index 52beb179d2a..90abb8dc920 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
@@ -29,7 +29,7 @@ class TestSoftwareImageDecodeCache : public SoftwareImageDecodeCache {
TestSoftwareImageDecodeCache()
: SoftwareImageDecodeCache(kN32_SkColorType,
kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId) {}
+ PaintImage::GetNextGeneratorClientId()) {}
};
SkM44 CreateMatrix(const SkSize& scale, bool is_decomposable) {
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
index 4fc04c1751b..0a89147856e 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
@@ -83,7 +83,7 @@ class N32Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kN32_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
}
};
@@ -92,7 +92,7 @@ class RGBA4444Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kARGB_4444_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
}
};
@@ -101,7 +101,7 @@ class RGBA_F16Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::GetNextGeneratorClientId());
}
};
diff --git a/chromium/cc/tiles/tile.cc b/chromium/cc/tiles/tile.cc
index 3afc048dbe2..a8cb3fd52e5 100644
--- a/chromium/cc/tiles/tile.cc
+++ b/chromium/cc/tiles/tile.cc
@@ -25,7 +25,7 @@ Tile::Tile(TileManager* tile_manager,
int source_frame_number,
int flags)
: tile_manager_(tile_manager),
- tiling_(info.tiling),
+ tiling_(info.tiling.get()),
content_rect_(info.content_rect),
enclosing_layer_rect_(info.enclosing_layer_rect),
raster_transform_(info.raster_transform),
diff --git a/chromium/cc/tiles/tile.h b/chromium/cc/tiles/tile.h
index bf4d2d6eff6..cde7850f9e4 100644
--- a/chromium/cc/tiles/tile.h
+++ b/chromium/cc/tiles/tile.h
@@ -29,7 +29,7 @@ class TileManager;
class CC_EXPORT Tile {
public:
struct CreateInfo {
- const PictureLayerTiling* tiling = nullptr;
+ raw_ptr<const PictureLayerTiling> tiling = nullptr;
int tiling_i_index = 0;
int tiling_j_index = 0;
gfx::Rect enclosing_layer_rect;
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index caf59cac516..000c0c5a02d 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -748,12 +748,12 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
// We analyze for solid color here, to decide to continue
// or drop the tile for scheduling and raster.
tile->set_solid_color_analysis_performed(true);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
bool is_solid_color =
prioritized_tile.raster_source()->PerformSolidColorAnalysis(
tile->enclosing_layer_rect(), &color);
if (is_solid_color) {
- tile->draw_info().set_solid_color(color);
+ tile->draw_info().set_solid_color(color.toSkColor());
client_->NotifyTileStateChanged(tile);
continue;
}
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index b18e59c4a11..3086adbf21e 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -1915,7 +1915,7 @@ TEST_F(PixelInspectTileManagerTest, LowResHasNoImage) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(size);
- recording_source->SetBackgroundColor(SK_ColorTRANSPARENT);
+ recording_source->SetBackgroundColor(SkColors::kTransparent);
recording_source->SetRequiresClear(true);
PaintFlags flags;
flags.setColor(SK_ColorGREEN);
@@ -3569,7 +3569,7 @@ TEST_F(DecodedImageTrackerTileManagerTest, DecodedImageTrackerDropsLocksOnUse) {
class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
public:
- void DecodeHdrImage(const gfx::ColorSpace& raster_cs) {
+ void DecodeHdrImage(const gfx::ColorSpace& output_cs) {
auto color_space = gfx::ColorSpace::CreateHDR10();
auto size = gfx::Size(250, 250);
auto info =
@@ -3586,7 +3586,7 @@ class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
// Add the image to our decoded_image_tracker.
TargetColorParams target_color_params;
- target_color_params.color_space = raster_cs;
+ target_color_params.color_space = output_cs;
host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
hdr_image, target_color_params, base::DoNothing());
FlushDecodeTasks();
@@ -3606,8 +3606,8 @@ class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
SetupPendingTree(raster_source, kTileSize, invalidation);
constexpr float kCustomWhiteLevel = 200.f;
- auto display_cs = gfx::DisplayColorSpaces(raster_cs);
- if (raster_cs.IsHDR())
+ auto display_cs = gfx::DisplayColorSpaces(output_cs);
+ if (output_cs.IsHDR())
display_cs.SetSDRMaxLuminanceNits(kCustomWhiteLevel);
pending_layer()->layer_tree_impl()->SetDisplayColorSpaces(display_cs);
@@ -3628,7 +3628,8 @@ class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
auto pending_tiles = pending_tiling->AllTilesForTesting();
ASSERT_FALSE(pending_tiles.empty());
- if (raster_cs.IsHDR()) {
+ const auto raster_cs = gfx::ColorSpace::CreateExtendedSRGB();
+ if (output_cs.IsHDR()) {
// Only the last tile will have any pending tasks.
const auto& pending_tasks =
host_impl()->tile_manager()->decode_tasks_for_testing(
@@ -3647,7 +3648,7 @@ class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
ASSERT_FALSE(
host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
- auto expected_format = raster_cs.IsHDR() ? viz::RGBA_F16 : viz::RGBA_8888;
+ auto expected_format = output_cs.IsHDR() ? viz::RGBA_F16 : viz::RGBA_8888;
auto all_tiles = host_impl()->tile_manager()->AllTilesForTesting();
for (const auto* tile : all_tiles)
EXPECT_EQ(expected_format, tile->draw_info().resource_format());
diff --git a/chromium/cc/tiles/tiling_set_eviction_queue.h b/chromium/cc/tiles/tiling_set_eviction_queue.h
index 6b830f1a3c0..662fb19a742 100644
--- a/chromium/cc/tiles/tiling_set_eviction_queue.h
+++ b/chromium/cc/tiles/tiling_set_eviction_queue.h
@@ -9,6 +9,7 @@
#include <vector>
+#include "base/memory/raw_ptr_exclusion.h"
#include "cc/cc_export.h"
#include "cc/tiles/picture_layer_tiling_set.h"
#include "cc/tiles/prioritized_tile.h"
@@ -115,7 +116,7 @@ class CC_EXPORT TilingSetEvictionQueue {
// `tilings_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data and tab_search:top100:2020).
- std::vector<PictureLayerTiling*>* tilings_;
+ RAW_PTR_EXCLUSION std::vector<PictureLayerTiling*>* tilings_;
WhichTree tree_;
PictureLayerTiling::PriorityRectType priority_rect_type_;
diff --git a/chromium/cc/tiles/tiling_set_raster_queue_all.h b/chromium/cc/tiles/tiling_set_raster_queue_all.h
index 57cebbf74e8..76a4f1969d5 100644
--- a/chromium/cc/tiles/tiling_set_raster_queue_all.h
+++ b/chromium/cc/tiles/tiling_set_raster_queue_all.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include "base/containers/stack_container.h"
+#include "base/memory/raw_ptr_exclusion.h"
#include "base/notreached.h"
#include "cc/cc_export.h"
#include "cc/tiles/picture_layer_tiling_set.h"
@@ -67,8 +68,8 @@ class CC_EXPORT TilingSetRasterQueueAll {
// `tiling_` and `tiling_data_` are not a raw_ptr<...> for performance
// reasons (based on analysis of sampling profiler data and
// tab_search:top100:2020).
- PictureLayerTiling* tiling_;
- TilingData* tiling_data_;
+ RAW_PTR_EXCLUSION PictureLayerTiling* tiling_;
+ RAW_PTR_EXCLUSION TilingData* tiling_data_;
PictureLayerTiling::PriorityRectType priority_rect_type_;
gfx::Rect pending_visible_rect_;
@@ -197,7 +198,7 @@ class CC_EXPORT TilingSetRasterQueueAll {
// `tiling_set_` is not a raw_ptr<...> for performance reasons (based on
// analysis of sampling profiler data).
- PictureLayerTilingSet* tiling_set_;
+ RAW_PTR_EXCLUSION PictureLayerTilingSet* tiling_set_;
struct IterationStage {
IterationStage(IteratorType type, TilePriority::PriorityBin bin);
diff --git a/chromium/cc/tiles/tiling_set_raster_queue_required.h b/chromium/cc/tiles/tiling_set_raster_queue_required.h
index 1a89cad01f7..64f9dc2735e 100644
--- a/chromium/cc/tiles/tiling_set_raster_queue_required.h
+++ b/chromium/cc/tiles/tiling_set_raster_queue_required.h
@@ -5,6 +5,7 @@
#ifndef CC_TILES_TILING_SET_RASTER_QUEUE_REQUIRED_H_
#define CC_TILES_TILING_SET_RASTER_QUEUE_REQUIRED_H_
+#include "base/memory/raw_ptr_exclusion.h"
#include "cc/cc_export.h"
#include "cc/tiles/picture_layer_tiling_set.h"
#include "cc/tiles/raster_tile_priority_queue.h"
@@ -45,8 +46,8 @@ class CC_EXPORT TilingSetRasterQueueRequired {
// `tiling_` and `tiling_data_` are not a raw_ptr<...> for performance
// reasons (based on analysis of sampling profiler data and
// tab_search:top100:2020).
- PictureLayerTiling* tiling_;
- TilingData* tiling_data_;
+ RAW_PTR_EXCLUSION PictureLayerTiling* tiling_;
+ RAW_PTR_EXCLUSION TilingData* tiling_data_;
PrioritizedTile current_tile_;
TilingData::Iterator visible_iterator_;
diff --git a/chromium/cc/trees/browser_controls_params.h b/chromium/cc/trees/browser_controls_params.h
index 91311103e78..9aab1b8a303 100644
--- a/chromium/cc/trees/browser_controls_params.h
+++ b/chromium/cc/trees/browser_controls_params.h
@@ -10,10 +10,6 @@
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;
diff --git a/chromium/cc/trees/commit_state.cc b/chromium/cc/trees/commit_state.cc
index e541fa5d25f..6abac8a47ea 100644
--- a/chromium/cc/trees/commit_state.cc
+++ b/chromium/cc/trees/commit_state.cc
@@ -38,7 +38,10 @@ CommitState::CommitState(const CommitState& prev)
overscroll_behavior(prev.overscroll_behavior),
background_color(prev.background_color),
viewport_property_ids(prev.viewport_property_ids),
- local_surface_id_from_parent(prev.local_surface_id_from_parent) {
+ local_surface_id_from_parent(prev.local_surface_id_from_parent),
+ previous_surfaces_visual_update_duration(
+ prev.previous_surfaces_visual_update_duration),
+ visual_update_duration(prev.visual_update_duration) {
memcpy(event_listener_properties, prev.event_listener_properties,
sizeof(event_listener_properties));
}
diff --git a/chromium/cc/trees/commit_state.h b/chromium/cc/trees/commit_state.h
index b4978d873b7..85f2ad29805 100644
--- a/chromium/cc/trees/commit_state.h
+++ b/chromium/cc/trees/commit_state.h
@@ -12,6 +12,7 @@
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
+#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "cc/benchmarks/micro_benchmark_impl.h"
#include "cc/cc_export.h"
@@ -104,6 +105,8 @@ struct CC_EXPORT CommitState {
SkColor background_color = SK_ColorWHITE;
ViewportPropertyIds viewport_property_ids;
viz::LocalSurfaceId local_surface_id_from_parent;
+ base::TimeDelta previous_surfaces_visual_update_duration;
+ base::TimeDelta visual_update_duration;
// -------------------------------------------------------------------------
// Take/reset: these values are reset on the LayerTreeHost between commits.
@@ -120,6 +123,7 @@ struct CC_EXPORT CommitState {
bool new_local_surface_id_request = false;
bool next_commit_forces_recalculate_raster_scales = false;
bool next_commit_forces_redraw = false;
+ uint64_t trace_id = 0;
EventMetrics::List event_metrics;
// Latency information for work done in ProxyMain::BeginMainFrame. The
// unique_ptr is allocated in RequestMainFrameUpdate, and passed to Blink's
@@ -162,7 +166,7 @@ struct CC_EXPORT ThreadUnsafeCommitState {
}
LayerListConstIterator end() const { return LayerListConstIterator(nullptr); }
- MutatorHost* mutator_host;
+ raw_ptr<MutatorHost> mutator_host;
PropertyTrees property_trees;
scoped_refptr<Layer> root_layer;
};
diff --git a/chromium/cc/trees/draw_properties_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc
index f18d813c165..6534341fdfa 100644
--- a/chromium/cc/trees/draw_properties_unittest.cc
+++ b/chromium/cc/trees/draw_properties_unittest.cc
@@ -1680,14 +1680,16 @@ TEST_F(DrawPropertiesTest, LargeTransforms) {
static bool TransformIsAnimating(LayerImpl* layer) {
MutatorHost* host = layer->layer_tree_impl()->mutator_host();
- return host->IsAnimatingTransformProperty(
- layer->element_id(), layer->GetElementTypeForAnimation());
+ return host->IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSFORM);
}
static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) {
MutatorHost* host = layer->layer_tree_impl()->mutator_host();
- return host->HasPotentiallyRunningTransformAnimation(
- layer->element_id(), layer->GetElementTypeForAnimation());
+ return host->HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSFORM);
}
TEST_F(DrawPropertiesTest,
@@ -6648,6 +6650,7 @@ TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) {
std::unique_ptr<KeyframeModel> transform_animation(KeyframeModel::Create(
std::move(curve), 3, 3,
KeyframeModel::TargetPropertyId(TargetProperty::TRANSFORM)));
+ transform_animation->set_affects_pending_elements(false);
scoped_refptr<Animation> animation(Animation::Create(1));
timeline_impl()->AttachAnimation(animation);
animation->AddKeyframeModel(std::move(transform_animation));
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index 02a889cad64..b9d99c69cb4 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -28,6 +28,7 @@
#include "cc/trees/property_tree_builder.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
+#include "cc/trees/viewport_property_ids.h"
#include "components/viz/common/display/de_jelly.h"
#include "components/viz/common/shared_element_resource_id.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -1425,7 +1426,8 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
}
}
-void ComputeTransforms(TransformTree* transform_tree) {
+void ComputeTransforms(TransformTree* transform_tree,
+ const ViewportPropertyIds& viewport_property_ids) {
if (!transform_tree->needs_update()) {
#if DCHECK_IS_ON()
// If the transform tree does not need an update, no TransformNode should
@@ -1439,7 +1441,7 @@ void ComputeTransforms(TransformTree* transform_tree) {
}
for (int i = kContentsRootPropertyNodeId;
i < static_cast<int>(transform_tree->size()); ++i)
- transform_tree->UpdateTransforms(i);
+ transform_tree->UpdateTransforms(i, &viewport_property_ids);
transform_tree->set_needs_update(false);
}
@@ -1460,14 +1462,16 @@ void UpdatePropertyTrees(LayerTreeHost* layer_tree_host) {
property_trees->clip_tree_mutable().set_needs_update(true);
property_trees->effect_tree_mutable().set_needs_update(true);
}
- ComputeTransforms(&property_trees->transform_tree_mutable());
+
+ ComputeTransforms(&property_trees->transform_tree_mutable(),
+ layer_tree_host->viewport_property_ids());
ComputeEffects(&property_trees->effect_tree_mutable());
// Computation of clips uses ToScreen which is updated while computing
// transforms. So, ComputeTransforms should be before ComputeClips.
ComputeClips(property_trees);
}
-void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
+void UpdatePropertyTreesAndRenderSurfaces(LayerTreeImpl* layer_tree_impl,
PropertyTrees* property_trees) {
if (property_trees->transform_tree().needs_update()) {
property_trees->clip_tree_mutable().set_needs_update(true);
@@ -1475,7 +1479,8 @@ void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
}
UpdateRenderTarget(&property_trees->effect_tree_mutable());
- ComputeTransforms(&property_trees->transform_tree_mutable());
+ ComputeTransforms(&property_trees->transform_tree_mutable(),
+ layer_tree_impl->viewport_property_ids());
ComputeEffects(&property_trees->effect_tree_mutable());
// Computation of clips uses ToScreen which is updated while computing
// transforms. So, ComputeTransforms should be before ComputeClips.
@@ -1555,8 +1560,7 @@ void CalculateDrawProperties(
gfx::RectF(layer_tree_impl->GetDeviceViewport()));
property_trees->transform_tree_mutable().SetRootScaleAndTransform(
layer_tree_impl->device_scale_factor(), layer_tree_impl->DrawTransform());
- UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl->root_layer(),
- property_trees);
+ UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl, property_trees);
{
TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates");
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index b80b38e3ab9..2c6d94c42a2 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -24,6 +24,7 @@ class TransformTree;
class PropertyTrees;
struct EffectNode;
struct TransformNode;
+struct ViewportPropertyIds;
namespace draw_property_utils {
@@ -32,7 +33,9 @@ void CC_EXPORT ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
// Computes combined (screen space) transforms for every node in the transform
// tree. This must be done prior to calling |ComputeClips|.
-void CC_EXPORT ComputeTransforms(TransformTree* transform_tree);
+void CC_EXPORT
+ComputeTransforms(TransformTree* transform_tree,
+ const ViewportPropertyIds& viewport_property_ids);
// Computes screen space opacity for every node in the opacity tree.
void CC_EXPORT ComputeEffects(EffectTree* effect_tree);
@@ -40,7 +43,7 @@ void CC_EXPORT ComputeEffects(EffectTree* effect_tree);
void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host);
void CC_EXPORT
-UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
+UpdatePropertyTreesAndRenderSurfaces(LayerTreeImpl* layer_tree_impl,
PropertyTrees* property_trees);
void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index b08f9cf0e5e..ffaddbaecc2 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -182,7 +182,7 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
value);
if (mask_filter_info.HasRoundedCorners()) {
MathUtil::AddCornerRadiiToTracedValue(
- "mask_filter_rounded_corner_raii",
+ "mask_filter_rounded_corners_radii",
mask_filter_info.rounded_corner_bounds(), value);
value->SetBoolean("mask_filter_is_fast_rounded_corner",
is_fast_rounded_corner);
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index e68f245b08e..2aa0f851421 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -21,7 +21,6 @@
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/returned_resource.h"
-#include "gpu/command_buffer/common/texture_in_use_response.h"
#include "ui/gfx/color_space.h"
namespace gpu {
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index 82dcc904980..6855ae2576f 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -11,7 +11,6 @@
#include "base/memory/ref_counted.h"
#include "cc/cc_export.h"
#include "components/viz/common/resources/returned_resource.h"
-#include "gpu/command_buffer/common/texture_in_use_response.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 730f3952679..9636bffb09f 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -409,6 +409,8 @@ std::unique_ptr<CommitState> LayerTreeHost::WillCommit(
client_->WillCommit(has_updates ? *result : *pending_commit_state());
pending_commit_state()->source_frame_number++;
commit_completion_event_ = std::move(completion);
+ pending_commit_state()->previous_surfaces_visual_update_duration =
+ base::TimeDelta();
return result;
}
@@ -732,7 +734,7 @@ void LayerTreeHost::SetDebugState(const LayerTreeDebugState& new_debug_state) {
void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
DCHECK(IsMainThread());
- DCHECK(CommitRequested());
+ DCHECK(syncing_deltas_for_test_ || CommitRequested());
if (page_scale_delta == 1.f)
return;
float page_scale =
@@ -1011,6 +1013,21 @@ void LayerTreeHost::UpdateScrollOffsetFromImpl(
transform_node->needs_local_transform_update = true;
transform_node->transform_changed = true;
transform_tree.set_needs_update(true);
+
+ // If the scroll was realized on the compositor, then its transform node
+ // is already updated (see LayerTreeImpl::DidUpdateScrollOffset) and we
+ // are now "catching up" to it on main, so we don't need a commit.
+ //
+ // But if the scroll was NOT realized on the compositor, we need a
+ // commit to push the transform change.
+ //
+ // Skip this if scroll unification is disabled as we will not set
+ // ScrollNode::is_composited in that case.
+ //
+ if (base::FeatureList::IsEnabled(features::kScrollUnification) &&
+ !scroll_tree.CanRealizeScrollsOnCompositor(*scroll_node)) {
+ SetNeedsCommit();
+ }
}
// The transform tree has been modified which requires a call to
@@ -1089,6 +1106,11 @@ void LayerTreeHost::NotifyThroughputTrackerResults(
client_->NotifyThroughputTrackerResults(std::move(results));
}
+void LayerTreeHost::ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) {
+ client_->ReportEventLatency(std::move(latencies));
+}
+
const base::WeakPtr<CompositorDelegateForInput>&
LayerTreeHost::GetDelegateForInput() const {
DCHECK(IsMainThread());
@@ -1378,7 +1400,7 @@ void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
// We should never process non-unit page_scale_delta for an OOPIF subframe.
// TODO(wjmaclean): Remove this dcheck as a pre-condition to closing the bug.
// https://crbug.com/845097
- DCHECK(!settings_.is_layer_tree_for_subframe ||
+ DCHECK(settings_.is_for_scalable_page ||
page_scale_factor == pending_commit_state()->page_scale_factor)
<< "Setting PSF in oopif subframe: old psf = "
<< pending_commit_state()->page_scale_factor
@@ -1505,6 +1527,13 @@ void LayerTreeHost::SetLocalSurfaceIdFromParent(
pending_commit_state()->local_surface_id_from_parent =
local_surface_id_from_parent;
+ // When we are switching to a new viz::LocalSurfaceId add our current visual
+ // update duration to that of previous surfaces, and clear out the total. So
+ // that we can begin to track the updates for this new Surface.
+ pending_commit_state()->previous_surfaces_visual_update_duration +=
+ pending_commit_state()->visual_update_duration;
+ pending_commit_state()->visual_update_duration = base::TimeDelta();
+
// If the parent sequence number has not advanced, then there is no need to
// commit anything. This can occur when the child sequence number has
// advanced. Which means that child has changed visual properites, and the
@@ -1582,11 +1611,11 @@ void LayerTreeHost::AddLayerShouldPushProperties(Layer* layer) {
}
void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) {
- DCHECK(CommitRequested());
+ DCHECK(syncing_deltas_for_test_ || CommitRequested());
// We should never process non-unit page_scale_delta for an OOPIF subframe.
// TODO(wjmaclean): Remove this check as a pre-condition to closing the bug.
// https://crbug.com/845097
- DCHECK(!settings_.is_layer_tree_for_subframe ||
+ DCHECK(settings_.is_for_scalable_page ||
page_scale == pending_commit_state()->page_scale_factor)
<< "Setting PSF in oopif subframe: old psf = "
<< pending_commit_state()->page_scale_factor
@@ -1597,7 +1626,7 @@ void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) {
void LayerTreeHost::SetElasticOverscrollFromImplSide(
gfx::Vector2dF elastic_overscroll) {
- DCHECK(CommitRequested());
+ DCHECK(syncing_deltas_for_test_ || CommitRequested());
pending_commit_state()->elastic_overscroll = elastic_overscroll;
}
@@ -1704,6 +1733,9 @@ void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() {
void LayerTreeHost::SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) {
+ if (list_type != ElementListType::ACTIVE)
+ return;
+
if (IsUsingLayerLists()) {
// In BlinkGenPropertyTrees/CompositeAfterPaint we always have property
// tree nodes and can set the filter directly on the effect node.
@@ -1721,6 +1753,9 @@ void LayerTreeHost::SetElementBackdropFilterMutated(
ElementId element_id,
ElementListType list_type,
const FilterOperations& backdrop_filters) {
+ if (list_type != ElementListType::ACTIVE)
+ return;
+
if (IsUsingLayerLists()) {
// In BlinkGenPropertyTrees/CompositeAfterPaint we always have property
// tree nodes and can set the backdrop_filter directly on the effect node.
@@ -1740,6 +1775,9 @@ void LayerTreeHost::SetElementOpacityMutated(ElementId element_id,
DCHECK_GE(opacity, 0.f);
DCHECK_LE(opacity, 1.f);
+ if (list_type != ElementListType::ACTIVE)
+ return;
+
if (IsUsingLayerLists()) {
property_trees()->effect_tree_mutable().OnOpacityAnimated(element_id,
opacity);
@@ -1767,6 +1805,9 @@ void LayerTreeHost::SetElementTransformMutated(
ElementId element_id,
ElementListType list_type,
const gfx::Transform& transform) {
+ if (list_type != ElementListType::ACTIVE)
+ return;
+
if (IsUsingLayerLists()) {
property_trees()->transform_tree_mutable().OnTransformAnimated(element_id,
transform);
@@ -1921,12 +1962,6 @@ void LayerTreeHost::SetRenderFrameObserver(
proxy_->SetRenderFrameObserver(std::move(observer));
}
-void LayerTreeHost::SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) {
- DCHECK(IsMainThread());
- proxy_->SetEnableFrameRateThrottling(enable_frame_rate_throttling);
-}
-
void LayerTreeHost::SetDelegatedInkMetadata(
std::unique_ptr<gfx::DelegatedInkMetadata> metadata) {
pending_commit_state()->delegated_ink_metadata = std::move(metadata);
@@ -1948,4 +1983,9 @@ uint32_t LayerTreeHost::GetAverageThroughput() const {
return proxy_->GetAverageThroughput();
}
+void LayerTreeHost::IncrementVisualUpdateDuration(
+ base::TimeDelta visual_update_duration) {
+ pending_commit_state()->visual_update_duration += visual_update_duration;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index feccd6a65bd..abe129ddb22 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -441,10 +441,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
->event_listener_properties[static_cast<size_t>(event_class)];
}
- // Indicates that its acceptable to throttle the frame rate for this content
- // to prioritize lower power/CPU use.
- void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling);
-
void SetViewportRectAndScale(
const gfx::Rect& device_viewport_rect,
float device_scale_factor,
@@ -720,6 +716,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void NotifyThroughputTrackerResults(CustomTrackerResults results);
void NotifyTransitionRequestsFinished(
const std::vector<uint32_t>& sequence_ids);
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies);
LayerTreeHostClient* client() {
DCHECK(IsMainThread());
@@ -809,6 +807,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return recording_scale_factor_;
}
+ const ViewportPropertyIds& viewport_property_ids() const {
+ return pending_commit_state()->viewport_property_ids;
+ }
+
void SetSourceURL(ukm::SourceId source_id, const GURL& url);
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm();
@@ -838,6 +840,23 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// Returns a percentage representing average throughput of last X seconds.
uint32_t GetAverageThroughput() const;
+ // TODO(szager): Remove these once threaded compositing is enabled for all
+ // web_tests.
+ bool in_composite_for_test() const { return in_composite_for_test_; }
+ [[nodiscard]] base::AutoReset<bool> ForceSyncCompositeForTest() {
+ return base::AutoReset<bool>(&in_composite_for_test_, true);
+ }
+
+ // Blink compositor unit tests sometimes want to simulate pushing deltas
+ // without going through the whole lifecycle to test the effects of the
+ // deltas. This flag turns off DCHECKs that deltas being set to main are
+ // during a commit phase so these tests can do this.
+ [[nodiscard]] base::AutoReset<bool> SimulateSyncingDeltasForTesting() {
+ return base::AutoReset<bool>(&syncing_deltas_for_test_, true);
+ }
+
+ void IncrementVisualUpdateDuration(base::TimeDelta visual_update_duration);
+
protected:
LayerTreeHost(InitParams params, CompositorMode mode);
@@ -1015,6 +1034,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// for histograms.
mutable bool waited_for_protected_sequence_ = false;
+ bool in_composite_for_test_ = false;
+
+ bool syncing_deltas_for_test_ = false;
+
// Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate
// objects.
base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 0e775a23e53..f52db87ce1a 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -6,10 +6,12 @@
#define CC_TREES_LAYER_TREE_HOST_CLIENT_H_
#include <memory>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cc/input/browser_controls_state.h"
+#include "cc/metrics/event_latency_tracker.h"
#include "cc/metrics/frame_sequence_tracker_collection.h"
#include "cc/trees/paint_holding_reason.h"
#include "cc/trees/property_tree.h"
@@ -188,6 +190,8 @@ class LayerTreeHostClient {
// RecordEndOfFrameMetrics.
virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0;
virtual void NotifyThroughputTrackerResults(CustomTrackerResults results) = 0;
+ virtual void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) = 0;
// Should only be implemented by Blink.
virtual std::unique_ptr<WebVitalMetrics> GetWebVitalMetrics() = 0;
@@ -203,9 +207,6 @@ class LayerTreeHostClient {
// must be safe to use on both the compositor and main threads.
class LayerTreeHostSchedulingClient {
public:
- // Indicates that the compositor thread scheduled a BeginMainFrame to run on
- // the main thread.
- virtual void DidScheduleBeginMainFrame() = 0;
// Called unconditionally when BeginMainFrame runs on the main thread.
virtual void DidRunBeginMainFrame() = 0;
};
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 14e13169de8..aca208728d0 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -259,9 +259,6 @@ void RecordSourceIdConsistency(bool all_valid, bool all_unique) {
} // namespace
-DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeRasterDurationHistogramTimer,
- "Scheduling.%s.PendingTreeRasterDuration")
-
void LayerTreeHostImpl::DidUpdateScrollAnimationCurve() {
// Because we updated the animation target, notify the
// `LatencyInfoSwapPromiseMonitor` to tell it that something happened that
@@ -320,6 +317,11 @@ void LayerTreeHostImpl::SetNeedsFullViewportRedraw() {
SetNeedsRedraw();
}
+void LayerTreeHostImpl::SetDeferBeginMainFrame(
+ bool defer_begin_main_frame) const {
+ client_->SetDeferBeginMainFrameFromImpl(defer_begin_main_frame);
+}
+
bool LayerTreeHostImpl::IsInHighLatencyMode() const {
return impl_thread_phase_ == ImplThreadPhase::IDLE;
}
@@ -385,7 +387,9 @@ LayerTreeHostImpl::LayerTreeHostImpl(
current_begin_frame_tracker_(FROM_HERE),
compositor_frame_reporting_controller_(
std::make_unique<CompositorFrameReportingController>(
- /*should_report_metrics=*/!settings.single_thread_proxy_scheduler,
+ /*should_report_histograms=*/!settings
+ .single_thread_proxy_scheduler,
+ /*should_report_ukm=*/!settings.single_thread_proxy_scheduler,
id)),
settings_(settings),
is_synchronous_single_threaded_(!task_runner_provider->HasImplThread() &&
@@ -455,14 +459,16 @@ LayerTreeHostImpl::LayerTreeHostImpl(
compositor_frame_reporting_controller_->SetFrameSequenceTrackerCollection(
&frame_trackers_);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
const bool is_ui = settings.is_layer_tree_for_ui;
if (is_ui) {
+ compositor_frame_reporting_controller_->set_event_latency_tracker(this);
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
dropped_frame_counter_.EnableReporForUI();
compositor_frame_reporting_controller_->SetThreadAffectsSmoothness(
FrameInfo::SmoothEffectDrivingThread::kMain, true);
- }
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+ }
dropped_frame_counter_.set_total_counter(&total_frame_counter_);
frame_trackers_.set_custom_tracker_results_added_callback(
@@ -522,11 +528,6 @@ const ThreadedInputHandler& LayerTreeHostImpl::GetInputHandler() const {
return static_cast<const ThreadedInputHandler&>(*input_delegate_.get());
}
-void LayerTreeHostImpl::WillSendBeginMainFrame() {
- if (scheduling_client_)
- scheduling_client_->DidScheduleBeginMainFrame();
-}
-
void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) {
frame_trackers_.NotifyBeginMainFrame(args);
}
@@ -586,12 +587,14 @@ void LayerTreeHostImpl::ReadyToCommit(
}
}
-void LayerTreeHostImpl::BeginCommit(int source_frame_number) {
+void LayerTreeHostImpl::BeginCommit(int source_frame_number,
+ uint64_t trace_id) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit");
if (!CommitToActiveTree())
CreatePendingTree();
sync_tree()->set_source_frame_number(source_frame_number);
+ sync_tree()->set_trace_id(trace_id);
}
// This function commits the LayerTreeHost, as represented by CommitState, to an
@@ -719,6 +722,10 @@ void LayerTreeHostImpl::CommitComplete() {
mutator_host_->HasSmilAnimation()) {
frame_trackers_.StartSequence(
FrameSequenceTrackerType::kMainThreadAnimation);
+ if (mutator_host_->HasSharedElementTransition()) {
+ frame_trackers_.StartSequence(
+ FrameSequenceTrackerType::kSETMainThreadAnimation);
+ }
}
for (const auto& info : mutator_host_->TakePendingThroughputTrackerInfos()) {
@@ -750,8 +757,6 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
// and the updated data for the image from the main frame.
PaintImageIdFlatSet images_to_invalidate =
tile_manager_.TakeImagesToInvalidateOnSyncTree();
- if (ukm_manager_)
- ukm_manager_->AddCheckerboardedImages(images_to_invalidate.size());
const auto& animated_images =
image_animation_controller_.AnimateForSyncTree(CurrentBeginFrameArgs());
@@ -914,10 +919,6 @@ void LayerTreeHostImpl::NotifyPendingTreeFullyPainted() {
// Scheduler to wait for ReadyToDraw signal to avoid Checkerboard.
if (CommitToActiveTree())
NotifyReadyToDraw();
- } else if (!CommitToActiveTree()) {
- DCHECK(!pending_tree_raster_duration_timer_);
- pending_tree_raster_duration_timer_ =
- std::make_unique<PendingTreeRasterDurationHistogramTimer>();
}
}
@@ -1020,19 +1021,6 @@ void LayerTreeHostImpl::StartPageScaleAnimation(const gfx::Point& target_offset,
bool anchor_point,
float page_scale,
base::TimeDelta duration) {
- // Temporary crash logging for https://crbug.com/845097.
- static bool has_dumped_without_crashing = false;
- if (settings().is_layer_tree_for_subframe && !has_dumped_without_crashing) {
- has_dumped_without_crashing = true;
- static auto* psf_oopif_animation_error =
- base::debug::AllocateCrashKeyString("psf_oopif_animation_error",
- base::debug::CrashKeySize::Size32);
- base::debug::SetCrashKeyString(
- psf_oopif_animation_error,
- base::StringPrintf("%p", InnerViewportScrollNode()));
- base::debug::DumpWithoutCrashing();
- }
-
if (!InnerViewportScrollNode())
return;
@@ -1308,8 +1296,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
int num_missing_tiles = 0;
int num_incomplete_tiles = 0;
int64_t checkerboarded_no_recording_content_area = 0;
- int64_t checkerboarded_needs_raster_content_area = 0;
- int64_t total_visible_area = 0;
+
bool have_copy_request =
active_tree()->property_trees()->effect_tree().HasCopyRequests();
bool have_missing_animated_tiles = false;
@@ -1389,9 +1376,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
num_incomplete_tiles += append_quads_data.num_incomplete_tiles;
checkerboarded_no_recording_content_area +=
append_quads_data.checkerboarded_no_recording_content_area;
- checkerboarded_needs_raster_content_area +=
- append_quads_data.checkerboarded_needs_raster_content_area;
- total_visible_area += append_quads_data.visible_layer_area;
+
if (append_quads_data.num_missing_tiles > 0) {
have_missing_animated_tiles |=
layer->screen_space_transform_is_animating();
@@ -1490,30 +1475,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
frame->has_missing_content =
num_missing_tiles > 0 || num_incomplete_tiles > 0;
- if (ukm_manager_) {
- ukm_manager_->AddCheckerboardStatsForFrame(
- checkerboarded_no_recording_content_area +
- checkerboarded_needs_raster_content_area,
- num_missing_tiles, total_visible_area);
- }
-
- if (active_tree_->has_ever_been_drawn()) {
- UMA_HISTOGRAM_COUNTS_100(
- "Compositing.RenderPass.AppendQuadData.NumMissingTiles",
- num_missing_tiles);
- UMA_HISTOGRAM_COUNTS_100(
- "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles",
- num_incomplete_tiles);
- UMA_HISTOGRAM_COUNTS_1M(
- "Compositing.RenderPass.AppendQuadData."
- "CheckerboardedNoRecordingContentArea",
- checkerboarded_no_recording_content_area);
- UMA_HISTOGRAM_COUNTS_1M(
- "Compositing.RenderPass.AppendQuadData."
- "CheckerboardedNeedRasterContentArea",
- checkerboarded_needs_raster_content_area);
- }
-
TRACE_EVENT_END2("cc,benchmark", "LayerTreeHostImpl::CalculateRenderPasses",
"draw_result", draw_result, "missing tiles",
num_missing_tiles);
@@ -1547,11 +1508,6 @@ void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) {
viewport_damage_rect_.Union(damage_rect);
}
-void LayerTreeHostImpl::SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) {
- enable_frame_rate_throttling_ = enable_frame_rate_throttling;
-}
-
void LayerTreeHostImpl::InvalidateContentOnImplSide() {
DCHECK(!pending_tree_);
// Invalidation should never be ran outside the impl frame for non
@@ -1750,7 +1706,9 @@ void LayerTreeHostImpl::EvictTexturesForTesting() {
UpdateTileManagerMemoryPolicy(ManagedMemoryPolicy(0));
}
-void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) {
+void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(
+ bool block,
+ bool notify_if_blocked) {
NOTREACHED();
}
@@ -1923,24 +1881,23 @@ TargetColorParams LayerTreeHostImpl::GetTargetColorParams(
if (!hdr_color_space.IsValid())
return params;
- // It's expensive to rasterize in HDR, so we only want to do so when we know
- // we have HDR content to rasterize.
- if (hdr_color_space.IsHDR() &&
- content_color_usage != gfx::ContentColorUsage::kHDR) {
- params.color_space = gfx::ColorSpace::CreateDisplayP3D65();
- return params;
- }
+ if (hdr_color_space.IsHDR()) {
+ if (content_color_usage == gfx::ContentColorUsage::kHDR) {
+ // Rasterization of HDR content is always done in extended-sRGB space.
+ params.color_space = gfx::ColorSpace::CreateExtendedSRGB();
- // The raster color space should contain sRGB to avoid artifacts during
- // rasterization.
- if (CheckColorSpaceContainsSrgb(hdr_color_space)) {
- params.color_space = hdr_color_space;
+ // Only report the HDR capabilities if they are requested.
+ params.hdr_max_luminance_relative =
+ display_cs.GetHDRMaxLuminanceRelative();
+ } else {
+ // If the content is not HDR, then use Display P3 as the rasterization
+ // color space.
+ params.color_space = gfx::ColorSpace::CreateDisplayP3D65();
+ }
+ return params;
}
- // Only report the HDR capabilities if they are requested.
- if (content_color_usage == gfx::ContentColorUsage::kHDR)
- params.hdr_max_luminance_relative = display_cs.GetHDRMaxLuminanceRelative();
-
+ params.color_space = hdr_color_space;
return params;
}
@@ -2005,7 +1962,6 @@ void LayerTreeHostImpl::NotifyReadyToActivate() {
// than wait for the TileManager to actually raster the content!
if (!pending_tree_fully_painted_)
return;
- pending_tree_raster_duration_timer_.reset();
client_->NotifyReadyToActivate();
}
@@ -2186,23 +2142,6 @@ void LayerTreeHostImpl::ReclaimResources(
// In OOM, we now might be able to release more resources that were held
// because they were exported.
if (resource_pool_) {
- if (resource_pool_->memory_usage_bytes()) {
- const size_t kMegabyte = 1024 * 1024;
- // This is a good time to log memory usage. A chunk of work has just
- // completed but none of the memory used for that work has likely been
- // freed.
- std::string client_suffix;
- if (settings_.commit_to_active_tree) {
- client_suffix = "Browser";
- } else if (settings_.is_layer_tree_for_subframe) {
- client_suffix = "OOPIF";
- } else {
- client_suffix = "Renderer";
- }
- base::UmaHistogramMemoryMB(
- "Compositing.ResourcePoolMemoryUsage." + client_suffix,
- static_cast<int>(resource_pool_->memory_usage_bytes() / kMegabyte));
- }
resource_pool_->ReduceResourceUsage();
}
@@ -2276,6 +2215,11 @@ void LayerTreeHostImpl::OnCompositorFrameTransitionDirectiveProcessed(
SetNeedsCommit();
}
+void LayerTreeHostImpl::ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) {
+ client_->ReportEventLatency(std::move(latencies));
+}
+
void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
client_->OnCanDrawStateChanged(CanDraw());
}
@@ -2469,6 +2413,14 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
}
+ metadata.previous_surfaces_visual_update_duration =
+ active_tree()->previous_surfaces_visual_update_duration();
+ metadata.current_surface_visual_update_duration =
+ active_tree()->visual_update_duration();
+ // We only want to report the durations from a Commit the first time. Not for
+ // subsequent Impl-only frames.
+ active_tree()->ClearVisualUpdateDurations();
+
return metadata;
}
@@ -2516,9 +2468,15 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers(
}
base::TimeTicks submit_time = base::TimeTicks::Now();
- layer_tree_frame_sink_->SubmitCompositorFrame(
- std::move(compositor_frame),
- /*hit_test_data_changed=*/false);
+ {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.SubmitCompositorFrame",
+ TRACE_ID_GLOBAL(active_tree()->trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ layer_tree_frame_sink_->SubmitCompositorFrame(
+ std::move(compositor_frame),
+ /*hit_test_data_changed=*/false);
+ }
#if DCHECK_IS_ON()
if (!doing_sync_draw_) {
@@ -2554,6 +2512,11 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers(
!mutator_host_->HasSmilAnimation()) {
frame_trackers_.StopSequence(
FrameSequenceTrackerType::kMainThreadAnimation);
+ frame_trackers_.StopSequence(
+ FrameSequenceTrackerType::kSETMainThreadAnimation);
+ } else if (!mutator_host_->HasSharedElementTransition()) {
+ frame_trackers_.StopSequence(
+ FrameSequenceTrackerType::kSETMainThreadAnimation);
}
if (lcd_text_metrics_reporter_) {
@@ -2575,7 +2538,6 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers(
}
active_tree_->ResetAllChangeTracking();
- active_tree_->set_has_ever_been_drawn(true);
devtools_instrumentation::DidDrawFrame(
id_, frame->begin_frame_ack.frame_id.sequence_number);
benchmark_instrumentation::IssueImplThreadRenderingStatsEvent(
@@ -2595,6 +2557,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
TRACE_ID_GLOBAL(CurrentBeginFrameArgs().trace_id),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"step", "GenerateCompositorFrame");
+
rendering_stats_instrumentation_->IncrementFrameCount(1);
memory_history_->SaveEntry(tile_manager_.memory_stats_from_last_assign());
@@ -2686,13 +2649,11 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
constexpr auto kTwiceOfDefaultInterval =
viz::BeginFrameArgs::DefaultInterval() * 2;
constexpr auto kMinDelta = kTwiceOfDefaultInterval - kFudgeDelta;
- if (enable_frame_rate_throttling_) {
- metadata.preferred_frame_interval = viz::BeginFrameArgs::MaxInterval();
- } else if (mutator_host_->MainThreadAnimationsCount() == 0 &&
- !mutator_host_->HasSmilAnimation() &&
- mutator_host_->NeedsTickAnimations() &&
- !frame_rate_estimator_.input_priority_mode() &&
- mutator_host_->MinimumTickInterval() > kMinDelta) {
+ if (mutator_host_->MainThreadAnimationsCount() == 0 &&
+ !mutator_host_->HasSmilAnimation() &&
+ mutator_host_->NeedsTickAnimations() &&
+ !frame_rate_estimator_.input_priority_mode() &&
+ mutator_host_->MinimumTickInterval() > kMinDelta) {
// All animations are impl-thread animations that tick at no more than
// half the default display compositing fps.
// Here and below with FrameRateEstimator::GetPreferredInterval(), the
@@ -3327,12 +3288,6 @@ void LayerTreeHostImpl::ActivateSyncTree() {
pending_tree_->local_surface_id_from_parent().ToString());
active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync);
- // In most cases, this will be reset in NotifyReadyToActivate, since we
- // activate the pending tree only when its ready. But an activation may be
- // forced, in the case of a context loss for instance, so reset it here as
- // well.
- pending_tree_raster_duration_timer_.reset();
-
// Process any requests in the UI resource queue. The request queue is
// given in LayerTreeHost::FinishCommit. This must take place before the
// swap.
@@ -4169,7 +4124,7 @@ LayerTreeHostImpl::ProcessCompositorDeltas() {
// We should never process non-unit page_scale_delta for an OOPIF subframe.
// TODO(wjmaclean): Remove this DCHECK as a pre-condition to closing the bug.
// https://crbug.com/845097
- DCHECK(!settings().is_layer_tree_for_subframe ||
+ DCHECK(settings().is_for_scalable_page ||
commit_data->page_scale_delta == 1.f);
commit_data->top_controls_delta =
active_tree()->top_controls_shown_ratio()->PullDeltaForMainThread();
@@ -4290,6 +4245,14 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
FrameSequenceTrackerType::kCompositorAnimation);
}
+ if (animated && mutator_host_->HasSharedElementTransition()) {
+ frame_trackers_.StartSequence(
+ FrameSequenceTrackerType::kSETCompositorAnimation);
+ } else {
+ frame_trackers_.StopSequence(
+ FrameSequenceTrackerType::kSETCompositorAnimation);
+ }
+
// TODO(crbug.com/551138): We could return true only if the animations are on
// the active tree. There's no need to cause a draw to take place from
// animations starting/ticking on the pending tree.
@@ -4333,6 +4296,13 @@ void LayerTreeHostImpl::RegisterScrollbarAnimationController(
scrollbar_opacity);
}
+void LayerTreeHostImpl::DidRegisterScrollbarLayer(
+ ElementId scroll_element_id,
+ ScrollbarOrientation orientation) {
+ if (input_delegate_)
+ input_delegate_->DidRegisterScrollbar(scroll_element_id, orientation);
+}
+
void LayerTreeHostImpl::DidUnregisterScrollbarLayer(
ElementId scroll_element_id,
ScrollbarOrientation orientation) {
@@ -4404,6 +4374,10 @@ ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(ElementId id) const {
return active_tree_->ScrollbarsFor(id);
}
+bool LayerTreeHostImpl::IsFluentScrollbar() const {
+ return settings().enable_fluent_scrollbar;
+}
+
void LayerTreeHostImpl::AddVideoFrameController(
VideoFrameController* controller) {
bool was_empty = video_frame_controllers_.empty();
@@ -5152,6 +5126,15 @@ void LayerTreeHostImpl::RequestInvalidationForAnimatedImages() {
client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
}
+bool LayerTreeHostImpl::IsReadyToActivate() const {
+ return client_->IsReadyToActivate();
+}
+
+void LayerTreeHostImpl::RequestImplSideInvalidationForRerasterTiling() {
+ bool needs_first_draw_on_activation = true;
+ client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
+}
+
base::WeakPtr<LayerTreeHostImpl> LayerTreeHostImpl::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 782a3c0de89..1b985be80c6 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -32,6 +32,7 @@
#include "cc/layers/layer_collections.h"
#include "cc/metrics/average_lag_tracking_manager.h"
#include "cc/metrics/dropped_frame_counter.h"
+#include "cc/metrics/event_latency_tracker.h"
#include "cc/metrics/event_metrics.h"
#include "cc/metrics/events_metrics_manager.h"
#include "cc/metrics/frame_sequence_tracker_collection.h"
@@ -92,7 +93,6 @@ class MemoryHistory;
class MutatorEvents;
class MutatorHost;
class PageScaleAnimation;
-class PendingTreeRasterDurationHistogramTimer;
class RasterTilePriorityQueue;
class RasterBufferProvider;
class RasterQueryQueue;
@@ -119,6 +119,7 @@ class LayerTreeHostImplClient {
virtual void DidReceiveCompositorFrameAckOnImplThread() = 0;
virtual void OnCanDrawStateChanged(bool can_draw) = 0;
virtual void NotifyReadyToActivate() = 0;
+ virtual bool IsReadyToActivate() = 0;
virtual void NotifyReadyToDraw() = 0;
// Please call these 2 functions through
// LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsOneBeginImplFrame().
@@ -127,6 +128,7 @@ class LayerTreeHostImplClient {
virtual void SetNeedsCommitOnImplThread() = 0;
virtual void SetNeedsPrepareTilesOnImplThread() = 0;
virtual void SetVideoNeedsBeginFrames(bool needs_begin_frames) = 0;
+ virtual void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) = 0;
virtual bool IsInsideDraw() = 0;
virtual void RenewTreePriority() = 0;
virtual void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
@@ -180,6 +182,9 @@ class LayerTreeHostImplClient {
virtual size_t CommitDurationSampleCountForTesting() const = 0;
+ virtual void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) = 0;
+
protected:
virtual ~LayerTreeHostImplClient() = default;
};
@@ -193,7 +198,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
public VideoFrameControllerClient,
public MutatorHostClient,
public ImageAnimationController::Client,
- public CompositorDelegateForInput {
+ public CompositorDelegateForInput,
+ public EventLatencyTracker {
public:
// This structure is used to build all the state required for producing a
// single CompositorFrame. The |render_passes| list becomes the set of
@@ -318,7 +324,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
return viewport_damage_rect_;
}
- virtual void WillSendBeginMainFrame();
+ virtual void WillSendBeginMainFrame() {}
virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args);
virtual void BeginMainFrameAborted(
CommitEarlyOutReason reason,
@@ -329,7 +335,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
const viz::BeginFrameArgs& commit_args,
const BeginMainFrameMetrics* begin_main_frame_metrics,
bool commit_timeout = false);
- virtual void BeginCommit(int source_frame_number);
+ virtual void BeginCommit(int source_frame_number, uint64_t trace_id);
virtual void FinishCommit(CommitState& commit_state,
const ThreadUnsafeCommitState& unsafe_state);
virtual void CommitComplete();
@@ -343,7 +349,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
void DidAnimateScrollOffset();
void SetFullViewportDamage();
void SetViewportDamage(const gfx::Rect& damage_rect);
- void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling);
// Interface for ThreadedInputHandler
void BindToInputHandler(
@@ -371,6 +376,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
const LayerTreeSettings& GetSettings() const override;
LayerTreeHostImpl& GetImplDeprecated() override;
const LayerTreeHostImpl& GetImplDeprecated() const override;
+ void SetDeferBeginMainFrame(bool defer_begin_main_frame) const override;
bool CanInjectJankOnMain() const;
FrameSequenceTrackerCollection& frame_trackers() { return frame_trackers_; }
@@ -481,8 +487,11 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
// When blocking, this prevents client_->NotifyReadyToActivate() from being
// called. When disabled, it calls client_->NotifyReadyToActivate()
- // immediately if any notifications had been blocked while blocking.
- virtual void BlockNotifyReadyToActivateForTesting(bool block);
+ // immediately if any notifications had been blocked while blocking and
+ // notify_if_blocked is true.
+ virtual void BlockNotifyReadyToActivateForTesting(
+ bool block,
+ bool notify_if_blocked = true);
// Prevents notifying the |client_| when an impl side invalidation request is
// made. When unblocked, the disabled request will immediately be called.
@@ -495,6 +504,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
void RegisterScrollbarAnimationController(ElementId scroll_element_id,
float initial_opacity);
+ void DidRegisterScrollbarLayer(ElementId scroll_element_id,
+ ScrollbarOrientation orientation);
void DidUnregisterScrollbarLayer(ElementId scroll_element_id,
ScrollbarOrientation orientation);
ScrollbarAnimationController* ScrollbarAnimationControllerForElementId(
@@ -535,6 +546,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
void SetNeedsRedrawForScrollbarAnimation() override;
ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override;
void DidChangeScrollbarVisibility() override;
+ bool IsFluentScrollbar() const override;
// VideoBeginFrameSource implementation.
void AddVideoFrameController(VideoFrameController* controller) override;
@@ -561,6 +573,10 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
void OnCompositorFrameTransitionDirectiveProcessed(
uint32_t sequence_id) override;
+ // EventLatencyTracker implementation.
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) override;
+
// Called from LayerTreeImpl.
void OnCanDrawStateChangedForTree();
@@ -879,6 +895,10 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
return throttle_decider_.ids();
}
+ bool IsReadyToActivate() const;
+
+ void RequestImplSideInvalidationForRerasterTiling();
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -1181,9 +1201,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
bool may_throttle_if_undrawn_frames_ = true;
- std::unique_ptr<PendingTreeRasterDurationHistogramTimer>
- pending_tree_raster_duration_timer_;
-
// These completion states to be transfered to the main thread when we
// begin main frame. The pair represents a request id and the completion (ie
// success) state.
@@ -1270,8 +1287,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
FrameRateEstimator frame_rate_estimator_;
bool has_observed_first_scroll_delay_ = false;
- bool enable_frame_rate_throttling_ = false;
-
// True if we are measuring smoothness in TotalFrameCounter and
// DroppedFrameCounter. Currently true when first contentful paint is done.
bool is_measuring_smoothness_ = false;
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index f7bca00a04a..3b1e8aa5ed6 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -83,7 +83,6 @@
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/region_capture_bounds.h"
-#include "components/viz/service/display/gl_renderer.h"
#include "components/viz/service/display/skia_output_surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
@@ -215,6 +214,11 @@ class LayerTreeHostImplTest : public testing::Test,
did_notify_ready_to_activate_ = true;
host_impl_->ActivateSyncTree();
}
+ bool IsReadyToActivate() override {
+ // in NotifyReadyToActivate(), call ActivateSyncTree() directly
+ // so this is always false
+ return false;
+ }
void NotifyReadyToDraw() override {}
void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; }
void SetNeedsOneBeginImplFrameOnImplThread() override {
@@ -225,6 +229,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; }
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {}
+ void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override {}
bool IsInsideDraw() override { return false; }
void RenewTreePriority() override {}
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
@@ -272,6 +277,8 @@ class LayerTreeHostImplTest : public testing::Test,
void NotifyPaintWorkletStateChange(
Scheduler::PaintWorkletState state) override {}
void NotifyThroughputTrackerResults(CustomTrackerResults results) override {}
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) override {}
void DidObserveFirstScrollDelay(
base::TimeDelta first_scroll_delay,
@@ -674,7 +681,7 @@ class LayerTreeHostImplTest : public testing::Test,
FakeRasterSource::CreateFromRecordingSource(recording_source.get());
// Create the pending tree.
- host_impl_->BeginCommit(0);
+ host_impl_->BeginCommit(0, /*trace_id=*/1);
LayerTreeImpl* pending_tree = host_impl_->pending_tree();
LayerImpl* root = SetupRootLayer<FakePictureLayerImpl>(
pending_tree, layer_size, raster_source);
@@ -3485,7 +3492,6 @@ class MissingTilesLayer : public LayerImpl {
AppendQuadsData* append_quads_data) override {
append_quads_data->num_missing_tiles += 10;
append_quads_data->checkerboarded_no_recording_content_area += 200;
- append_quads_data->checkerboarded_needs_raster_content_area += 200;
append_quads_data->visible_layer_area += 200;
}
};
@@ -4407,9 +4413,11 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, SyncSubpixelScrollDelta) {
// Verify this scroll delta is consistent with the snapped position of the
// scroll layer.
- draw_property_utils::ComputeTransforms(&scroll_layer->layer_tree_impl()
- ->property_trees()
- ->transform_tree_mutable());
+ draw_property_utils::ComputeTransforms(
+ &scroll_layer->layer_tree_impl()
+ ->property_trees()
+ ->transform_tree_mutable(),
+ scroll_layer->layer_tree_impl()->viewport_property_ids());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0, -19),
scroll_layer->ScreenSpaceTransform().To2dTranslation());
}
@@ -6242,7 +6250,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
auto* layer = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree());
layer->SetBounds(gfx::Size(10, 10));
layer->SetDrawsContent(true);
- layer->SetBackgroundColor(SK_ColorRED);
+ layer->SetBackgroundColor(SkColors::kRed);
CopyProperties(root, layer);
UpdateDrawProperties(host_impl_->active_tree());
@@ -11043,7 +11051,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10));
// This will damage everything.
- root->SetBackgroundColor(SK_ColorBLACK);
+ root->SetBackgroundColor(SkColors::kBlack);
args = viz::CreateBeginFrameArgsForTesting(
BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
base::TimeTicks() + base::Milliseconds(1));
@@ -11250,13 +11258,13 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(),
gfx::Size(10, 10));
root->SetDrawsContent(true);
- root->SetBackgroundColor(SK_ColorRED);
+ root->SetBackgroundColor(SkColors::kRed);
// Child layer is in the bottom right corner.
auto* child = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree());
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
- child->SetBackgroundColor(SK_ColorRED);
+ child->SetBackgroundColor(SkColors::kRed);
CopyProperties(root, child);
child->SetOffsetToTransformParent(gfx::Vector2dF(9, 9));
@@ -11278,11 +11286,6 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
DrawFrameAndTestDamage(no_damage, child);
}
-class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer {
- public:
- using viz::GLRenderer::ShouldAntialiasQuad;
-};
-
TEST_P(ScrollUnifiedLayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
// Due to precision issues (especially on Android), sometimes far
// away quads can end up thinking they need AA.
@@ -11334,16 +11337,12 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
const viz::DrawQuad* quad = frame.render_passes[0]->quad_list.front();
- bool clipped = false, force_aa = false;
- gfx::QuadF device_layer_quad = MathUtil::MapQuad(
+ bool clipped = false;
+ MathUtil::MapQuad(
quad->shared_quad_state->quad_to_target_transform,
gfx::QuadF(gfx::RectF(quad->shared_quad_state->visible_quad_layer_rect)),
&clipped);
EXPECT_FALSE(clipped);
- bool antialiased =
- GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
- device_layer_quad, clipped, force_aa);
- EXPECT_FALSE(antialiased);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -11530,7 +11529,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage,
LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>(
host_impl_->active_tree(), gfx::Size(10, 10));
- root->SetBackgroundColor(SK_ColorRED);
+ root->SetBackgroundColor(SkColors::kRed);
UpdateDrawProperties(host_impl_->active_tree());
// RequiresHighResToDraw is set when new output surface is used.
@@ -11651,108 +11650,6 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, CreateETC1UIResource) {
EXPECT_NE(viz::kInvalidResourceId, id1);
}
-class FrameSinkClient : public TestLayerTreeFrameSinkClient {
- public:
- explicit FrameSinkClient(
- scoped_refptr<viz::ContextProvider> display_context_provider)
- : display_context_provider_(std::move(display_context_provider)) {}
-
- std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
- CreateDisplayController() override {
- // In this implementation, no output surface has a real gpu thread, and
- // there is no overlay support.
- return nullptr;
- }
- std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface(
- viz::DisplayCompositorMemoryAndTaskController*) override {
- return viz::FakeSkiaOutputSurface::Create3d(
- std::move(display_context_provider_));
- }
-
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- return viz::FakeOutputSurface::Create3d(
- std::move(display_context_provider_));
- }
-
- void DisplayReceivedLocalSurfaceId(
- const viz::LocalSurfaceId& local_surface_id) override {}
- void DisplayReceivedCompositorFrame(
- const viz::CompositorFrame& frame) override {}
- void DisplayWillDrawAndSwap(
- bool will_draw_and_swap,
- viz::AggregatedRenderPassList* render_passes) override {}
- void DisplayDidDrawAndSwap() override {}
-
- private:
- scoped_refptr<viz::ContextProvider> display_context_provider_;
-};
-
-using LayerTreeHostImplTestWithRenderer = LayerTreeHostImplTest;
-
-TEST_F(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) {
- viz::DebugRendererSettings debug_settings;
-
- scoped_refptr<viz::TestContextProvider> context_provider =
- viz::TestContextProvider::Create();
- FrameSinkClient test_client(context_provider);
-
- constexpr bool synchronous_composite = true;
- constexpr bool disable_display_vsync = false;
- constexpr double refresh_rate = 60.0;
- std::unique_ptr<TaskRunnerProvider> task_runner_provider =
- TaskRunnerProvider::Create(base::ThreadTaskRunnerHandle::Get(), nullptr);
- auto layer_tree_frame_sink = std::make_unique<TestLayerTreeFrameSink>(
- context_provider, viz::TestContextProvider::CreateWorker(), nullptr,
- viz::RendererSettings(), &debug_settings, task_runner_provider.get(),
- synchronous_composite, disable_display_vsync, refresh_rate);
- layer_tree_frame_sink->SetClient(&test_client);
-
- CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
-
- LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10));
- struct Helper {
- std::unique_ptr<viz::CopyOutputResult> unprocessed_result;
- void OnResult(base::OnceClosure finished,
- std::unique_ptr<viz::CopyOutputResult> result) {
- unprocessed_result = std::move(result);
- std::move(finished).Run();
- }
- } helper;
-
- GetEffectNode(root)->has_copy_request = true;
- base::RunLoop copy_request_run_loop;
- GetPropertyTrees(root)->effect_tree_mutable().AddCopyRequest(
- root->effect_tree_index(),
- std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA,
- viz::CopyOutputRequest::ResultDestination::kNativeTextures,
- base::BindOnce(&Helper::OnResult, base::Unretained(&helper),
- copy_request_run_loop.QuitClosure())));
- DrawFrame();
-
- auto* sii = context_provider->SharedImageInterface();
- // The CopyOutputResult has a ref on the viz::ContextProvider and a shared
- // image allocated.
- copy_request_run_loop.Run();
- EXPECT_TRUE(helper.unprocessed_result);
- EXPECT_FALSE(context_provider->HasOneRef());
- EXPECT_EQ(1u, sii->shared_image_count());
-
- host_impl_->ReleaseLayerTreeFrameSink();
- host_impl_ = nullptr;
-
- // The texture release callback that was given to the CopyOutputResult has
- // been canceled, and the shared image deleted.
- EXPECT_TRUE(context_provider->HasOneRef());
- EXPECT_EQ(0u, sii->shared_image_count());
-
- // When resetting the CopyOutputResult, it will run its texture release
- // callback. This should not cause a crash, etc.
- helper.unprocessed_result.reset();
-}
-
// This tests the case where hit testing only on scrollable layers returns a
// layer that's outside the scroll chain of the first hit test *any* layer. See
// LayerTreeHostImpl::IsInitialScrollHitTestReliable for details.
@@ -13729,6 +13626,65 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
host_impl_ = nullptr;
}
+// Tests that no scrolls occur when thumb_len equals track_len.
+TEST_P(ScrollUnifiedLayerTreeHostImplTest, ScrollOnLargeThumb) {
+ LayerTreeSettings settings = DefaultSettings();
+ settings.compositor_threaded_scrollbar_scrolling = true;
+ CreateHostImpl(settings, CreateLayerTreeFrameSink());
+
+ // Setup the viewport.
+ const gfx::Size viewport_size = gfx::Size(360, 600);
+ const gfx::Size content_size = gfx::Size(345, 3800);
+ SetupViewportLayersOuterScrolls(viewport_size, content_size);
+ LayerImpl* scroll_layer = OuterViewportScrollLayer();
+
+ // Set up the scrollbar and its dimensions.
+ LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
+ layer_tree_impl->set_painted_device_scale_factor(2.5f);
+ auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>(
+ layer_tree_impl, ScrollbarOrientation::VERTICAL, false, true);
+ SetupScrollbarLayerCommon(scroll_layer, scrollbar);
+ scrollbar->SetHitTestable(true);
+
+ const gfx::Size scrollbar_size = gfx::Size(15, 600);
+ scrollbar->SetBounds(scrollbar_size);
+
+ // Set up the thumb dimensions.
+ scrollbar->SetThumbThickness(15);
+ scrollbar->SetThumbLength(575);
+ scrollbar->SetTrackRect(gfx::Rect(0, 15, 15, 575));
+ scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0));
+
+ TestInputHandlerClient input_handler_client;
+ GetInputHandler().BindToClient(&input_handler_client);
+
+ // PointerDown on the scrollbar should populate drag_state.
+ GetInputHandler().MouseDown(gfx::PointF(350, 300),
+ /*jump_key_modifier*/ false);
+ EXPECT_TRUE(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->drag_state_.has_value());
+
+ // Moving the mouse downwards should result in no scroll.
+ InputHandlerPointerResult res =
+ GetInputHandler().MouseMoveAt(gfx::Point(350, 600));
+ EXPECT_EQ(res.scroll_delta.y(), 0);
+
+ // Moving the mouse upwards should result in no scroll.
+ res = GetInputHandler().MouseMoveAt(gfx::Point(350, 0));
+ EXPECT_EQ(res.scroll_delta.y(), 0);
+
+ // End the scroll.
+ GetInputHandler().MouseUp(gfx::PointF(350, 0));
+ EXPECT_TRUE(!GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->drag_state_.has_value());
+
+ // Tear down the LayerTreeHostImpl before the InputHandlerClient.
+ host_impl_->ReleaseLayerTreeFrameSink();
+ host_impl_ = nullptr;
+}
+
// Tests that deleting a horizontal scrollbar doesn't affect the autoscroll task
// for the vertical scrollbar.
TEST_P(ScrollUnifiedLayerTreeHostImplTest, AutoscrollOnDeletedScrollbar) {
@@ -13777,12 +13733,45 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, AutoscrollOnDeletedScrollbar) {
->AutoscrollTaskIsScheduled());
// If a call comes in to delete the scrollbar layer for which the autoscroll
- // was scheduled, the autoscroll task should be cancelled.
- host_impl_->DidUnregisterScrollbarLayer(scroll_layer->element_id(),
- ScrollbarOrientation::VERTICAL);
- EXPECT_FALSE(GetInputHandler()
- .scrollbar_controller_for_testing()
- ->AutoscrollTaskIsScheduled());
+ // was scheduled, the autoscroll task should set a waiting state instead of
+ // initiating an autoscroll, in case the scrollbar comes back.
+ layer_tree_impl->UnregisterScrollbar(scrollbar);
+
+ EXPECT_TRUE(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->AutoscrollTaskIsScheduled());
+
+ GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->cancelable_autoscroll_task_->callback()
+ .Run();
+ GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->cancelable_autoscroll_task_.reset();
+ EXPECT_EQ(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->autoscroll_state_->status,
+ ScrollbarController::AutoScrollStatus::AUTOSCROLL_READY);
+
+ // Re-register the scrollbar. An autoscroll task should be posted that
+ // actually starts a scroll animation
+ layer_tree_impl->RegisterScrollbar(scrollbar);
+
+ EXPECT_TRUE(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->AutoscrollTaskIsScheduled());
+
+ GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->cancelable_autoscroll_task_->callback()
+ .Run();
+ GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->cancelable_autoscroll_task_.reset();
+ EXPECT_EQ(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->autoscroll_state_->status,
+ ScrollbarController::AutoScrollStatus::AUTOSCROLL_SCROLLING);
// End the scroll.
GetInputHandler().MouseUp(gfx::PointF(350, 580));
@@ -14336,9 +14325,10 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, ThumbDragAfterJumpClick) {
scrollbar->SetBounds(scrollbar_size);
host_impl_->set_force_smooth_wheel_scrolling_for_testing(true);
+ const int thumb_len = 50;
// Set up the thumb dimensions.
scrollbar->SetThumbThickness(15);
- scrollbar->SetThumbLength(50);
+ scrollbar->SetThumbLength(thumb_len);
scrollbar->SetTrackRect(gfx::Rect(0, 15, 15, 575));
// Set up scrollbar arrows.
@@ -14371,11 +14361,17 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, ThumbDragAfterJumpClick) {
.scrollbar_controller_for_testing()
->drag_state_.has_value());
- // This verifies that the jump click delta was accounted for correctly.
+ // This verifies that the start/snap-back position is the scroll position
+ // before any jump-click
EXPECT_FLOAT_EQ(GetInputHandler()
.scrollbar_controller_for_testing()
->drag_state_->scroll_position_at_start_,
- 243.80952f);
+ 0.0f);
+
+ EXPECT_FLOAT_EQ(GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->drag_state_->drag_origin.y(),
+ 15.0f + thumb_len / 2.0f);
}
// Tear down the LayerTreeHostImpl before the InputHandlerClient.
@@ -14454,10 +14450,16 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
// existing scroll offset animations are aborted and a new autoscroll
// animation is created. Test passes if unit test doesn't hit any DCHECK
// failures.
+ GetInputHandler().scrollbar_controller_for_testing()->autoscroll_state_ =
+ ScrollbarController::AutoScrollState();
+ GetInputHandler()
+ .scrollbar_controller_for_testing()
+ ->autoscroll_state_->velocity = 800;
GetInputHandler()
.scrollbar_controller_for_testing()
- ->StartAutoScrollAnimation(/*scroll_velocity*/ 800,
- ScrollbarPart::FORWARD_TRACK);
+ ->autoscroll_state_->pressed_scrollbar_part =
+ ScrollbarPart::FORWARD_TRACK;
+ GetInputHandler().scrollbar_controller_for_testing()->StartAutoScroll();
EXPECT_TRUE(GetImplAnimationHost()->ImplOnlyScrollAnimatingElement());
}
@@ -15797,7 +15799,7 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest,
}
TEST_P(ScrollUnifiedLayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
- // Check page scale factor update in property trees when an update is made
+ // Check page scale factor updates the property trees when an update is made
// on the active tree.
CreatePendingTree();
host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 3);
@@ -15816,20 +15818,26 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
EXPECT_EQ(gfx::Vector2dF(2, 2), active_tree_node->local.To2dScale());
EXPECT_EQ(gfx::Point3F(), active_tree_node->origin);
EXPECT_EQ(2, host_impl_->active_tree()->current_page_scale_factor());
+ EXPECT_EQ(2, host_impl_->active_tree()
+ ->property_trees()
+ ->transform_tree()
+ .page_scale_factor());
TransformNode* pending_tree_node =
host_impl_->pending_tree()->PageScaleTransformNode();
- // Before pending tree updates draw properties, its properties are still
- // based on 1.0 page scale, except for current_page_scale_factor() which is a
- // shared data between the active and pending trees.
- EXPECT_TRUE(pending_tree_node->local.IsIdentity());
+
+ // Since the pending tree shares the scale factor with the active tree, its
+ // value and property trees should also have been updated.
+ EXPECT_TRUE(pending_tree_node->local.IsScale2d());
+ EXPECT_EQ(gfx::Vector2dF(2, 2), pending_tree_node->local.To2dScale());
EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin);
EXPECT_EQ(2, host_impl_->pending_tree()->current_page_scale_factor());
- EXPECT_EQ(1, host_impl_->pending_tree()
+ EXPECT_EQ(2, host_impl_->pending_tree()
->property_trees()
->transform_tree()
.page_scale_factor());
+ // Update draw properties doesn't change the correct values
host_impl_->pending_tree()->set_needs_update_draw_properties();
UpdateDrawProperties(host_impl_->pending_tree());
pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode();
@@ -16168,7 +16176,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, CheckerImagingTileInvalidation) {
host_impl_->WillBeginImplFrame(begin_frame_args);
// Create the pending tree.
- host_impl_->BeginCommit(0);
+ host_impl_->BeginCommit(0, /*trace_id=*/1);
LayerTreeImpl* pending_tree = host_impl_->pending_tree();
auto* root = SetupRootLayer<FakePictureLayerImpl>(pending_tree, layer_size,
raster_source);
@@ -16303,7 +16311,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, RasterColorSpaceHDR) {
EXPECT_EQ(wcg_params.sdr_max_luminance_nits, kCustomWhiteLevel);
EXPECT_EQ(wcg_params.hdr_max_luminance_relative, 1.f);
- EXPECT_EQ(hdr_params.color_space, hdr);
+ EXPECT_EQ(hdr_params.color_space, gfx::ColorSpace::CreateExtendedSRGB());
EXPECT_EQ(hdr_params.sdr_max_luminance_nits, kCustomWhiteLevel);
EXPECT_EQ(hdr_params.hdr_max_luminance_relative, kHDRMaxLuminanceRelative);
}
@@ -18295,4 +18303,62 @@ TEST_F(LayerTreeHostImplTest, CollectRegionCaptureBounds) {
collected_bounds.bounds().find(kFourthId)->second);
}
+// Check if picturelayer's ScrollInteractionInProgress() return true even when
+// BrowserControl is consuming ScrollUpdate.
+TEST_P(LayerTreeHostImplBrowserControlsTest,
+ BrowserControlsScrollInteractionInProgress) {
+ gfx::Size inner_size = gfx::Size(100, 100);
+ gfx::Size outer_size = gfx::Size(100, 100);
+ gfx::Size content_size = gfx::Size(100, 200);
+ SetupBrowserControlsAndScrollLayerWithVirtualViewport(inner_size, outer_size,
+ content_size);
+
+ LayerTreeImpl* active_tree = host_impl_->active_tree();
+
+ // Create a content layer beneath the outer viewport scroll layer.
+ scoped_refptr<FakeRasterSource> raster_source(
+ FakeRasterSource::CreateFilled(content_size));
+
+ auto* picture_layer =
+ AddLayer<FakePictureLayerImpl>(host_impl_->active_tree(), raster_source);
+ CopyProperties(OuterViewportScrollLayer(), picture_layer);
+ picture_layer->SetBounds(content_size);
+ picture_layer->SetDrawsContent(true);
+ picture_layer->SetNeedsPushProperties();
+ active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 2.0f);
+ DrawFrame();
+
+ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
+ GetInputHandler()
+ .ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 50),
+ ui::ScrollInputType::kTouchscreen)
+ .get(),
+ ui::ScrollInputType::kTouchscreen)
+ .thread);
+ // shownratio == 1
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), false);
+
+ // 0 < shownratio <1
+ GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(),
+ gfx::Vector2dF(0, 25),
+ ui::ScrollInputType::kTouchscreen)
+ .get());
+ EXPECT_GT(host_impl_->active_tree()->CurrentTopControlsShownRatio(), 0);
+ EXPECT_LT(host_impl_->active_tree()->CurrentTopControlsShownRatio(), 1);
+ EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), true);
+
+ GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(),
+ gfx::Vector2dF(0, 30),
+ ui::ScrollInputType::kTouchscreen)
+ .get());
+ // now shownratio == 0
+ EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), true);
+
+ GetInputHandler().ScrollEnd();
+ // scroll end, shownratio == 0
+ EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), false);
+}
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index f8b31c672ca..fc3d5a9f063 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -63,7 +63,6 @@ using RenderPassOptions = uint32_t;
const uint32_t kUseMasks = 1 << 0;
const uint32_t kUseAntialiasing = 1 << 1;
const uint32_t kUseColorMatrix = 1 << 2;
-const uint32_t kForceShaders = 1 << 3;
class LayerTreeHostBlendingPixelTest
: public LayerTreeHostPixelResourceTest,
@@ -72,8 +71,7 @@ class LayerTreeHostBlendingPixelTest
public:
LayerTreeHostBlendingPixelTest()
: LayerTreeHostPixelResourceTest(resource_type()),
- force_antialiasing_(false),
- force_blending_with_shaders_(false) {
+ force_antialiasing_(false) {
pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
}
@@ -93,8 +91,6 @@ class LayerTreeHostBlendingPixelTest
override {
viz::RendererSettings modified_renderer_settings = renderer_settings;
modified_renderer_settings.force_antialiasing = force_antialiasing_;
- modified_renderer_settings.force_blending_with_shaders =
- force_blending_with_shaders_;
return LayerTreeHostPixelResourceTest::CreateLayerTreeFrameSink(
modified_renderer_settings, refresh_rate, compositor_context_provider,
worker_context_provider);
@@ -211,10 +207,6 @@ class LayerTreeHostBlendingPixelTest
const int kRootWidth = 2;
const int kRootHeight = kRootWidth * kCSSTestColorsCount;
- // Force shaders only applies to gl renderer.
- if (renderer_type_ != viz::RendererType::kGL && flags & kForceShaders)
- return;
-
SCOPED_TRACE(TestTypeToString());
SCOPED_TRACE(SkBlendMode_Name(current_blend_mode()));
@@ -229,10 +221,8 @@ class LayerTreeHostBlendingPixelTest
CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags);
force_antialiasing_ = (flags & kUseAntialiasing);
- force_blending_with_shaders_ = (flags & kForceShaders);
- if ((renderer_type_ == viz::RendererType::kGL && force_antialiasing_) ||
- renderer_type_ == viz::RendererType::kSkiaVk) {
+ if (renderer_type_ == viz::RendererType::kSkiaVk) {
// Blending results might differ with one pixel.
float percentage_pixels_error = 35.f;
float percentage_pixels_small_error = 0.f;
@@ -252,7 +242,6 @@ class LayerTreeHostBlendingPixelTest
}
bool force_antialiasing_;
- bool force_blending_with_shaders_;
FakeContentLayerClient mask_client_;
FakeContentLayerClient backdrop_client_;
SkColor misc_opaque_color_ = 0xffc86464;
@@ -261,9 +250,6 @@ class LayerTreeHostBlendingPixelTest
std::vector<RasterTestConfig> const kTestCases = {
{viz::RendererType::kSoftware, TestRasterType::kBitmap},
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- {viz::RendererType::kGL, TestRasterType::kZeroCopy},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
{viz::RendererType::kSkiaGL, TestRasterType::kGpu},
#endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
#if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS)
@@ -423,44 +409,6 @@ TEST_P(LayerTreeHostBlendingPixelTest,
RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix);
}
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders) {
- RunBlendingWithRenderPass(kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA) {
- RunBlendingWithRenderPass(kUseAntialiasing | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersWithMask) {
- RunBlendingWithRenderPass(kUseMasks | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
- BlendingWithRenderPassShadersWithMaskAA) {
- RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
- BlendingWithRenderPassShadersColorMatrix) {
- RunBlendingWithRenderPass(kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
- BlendingWithRenderPassShadersColorMatrixAA) {
- RunBlendingWithRenderPass(kUseAntialiasing | kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
- BlendingWithRenderPassShadersWithMaskColorMatrix) {
- RunBlendingWithRenderPass(kUseMasks | kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
- BlendingWithRenderPassShadersWithMaskColorMatrixAA) {
- RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix |
- kForceShaders);
-}
-
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 40114681266..e4b55f0fee0 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -32,8 +32,6 @@ class LayerTreeHostFiltersPixelTest
// generating separate base line file paths.
const char* GetRendererSuffix() {
switch (renderer_type_) {
- case viz::RendererType::kGL:
- return "gl";
case viz::RendererType::kSkiaGL:
return "skia_gl";
case viz::RendererType::kSkiaVk:
@@ -151,12 +149,9 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterInvalid) {
}
TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) {
-#if BUILDFLAG(IS_FUCHSIA)
- // TODO(crbug.com/1311459): This test case fails on SwiftShader FEMU due
- // to a new implementation of log/exp functions in SwiftShader. We should
- // re-enable the test case once the bug is fixed.
+#if defined(MEMORY_SANITIZER)
if (renderer_type() == viz::RendererType::kSkiaVk) {
- GTEST_SKIP();
+ GTEST_SKIP() << "TODO(crbug.com/1324336): Uninitialized data error";
}
#endif
if (use_software_renderer()) {
@@ -180,7 +175,9 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) {
gfx::RRectF backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())), 0);
blur->SetBackdropFilterBounds(backdrop_filter_bounds);
-#if BUILDFLAG(IS_WIN) || defined(ARCH_CPU_ARM64)
+#if BUILDFLAG(IS_FUCHSIA)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
+#elif BUILDFLAG(IS_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;
@@ -249,6 +246,11 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRounded) {
}
TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) {
+#if defined(MEMORY_SANITIZER)
+ if (renderer_type() == viz::RendererType::kSkiaVk) {
+ GTEST_SKIP() << "TODO(crbug.com/1324336): Uninitialized data error";
+ }
+#endif
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -553,14 +555,6 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterClipped) {
}
TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) {
-#if BUILDFLAG(IS_FUCHSIA)
- // TODO(crbug.com/1311459): This test case fails on SwiftShader FEMU due
- // to a new implementation of log/exp functions in SwiftShader. We should
- // re-enable the test case once the bug is fixed.
- if (renderer_type() == viz::RendererType::kSkiaVk) {
- GTEST_SKIP();
- }
-#endif
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
@@ -599,7 +593,11 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) {
filter->SetBackdropFilters(filters);
filter->ClearBackdropFilterBounds();
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \
+#if BUILDFLAG(IS_FUCHSIA)
+ if (renderer_type() == viz::RendererType::kSkiaVk) {
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
+ }
+#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \
defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if BUILDFLAG(IS_WIN)
// Windows has 153 pixels off by at most 2: crbug.com/225027
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 6666f037039..c6bb12f88f5 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -31,11 +31,6 @@ namespace {
std::vector<RasterTestConfig> const kTestCases = {
{viz::RendererType::kSoftware, TestRasterType::kBitmap},
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- {viz::RendererType::kGL, TestRasterType::kGpu},
- {viz::RendererType::kGL, TestRasterType::kOneCopy},
- {viz::RendererType::kGL, TestRasterType::kZeroCopy},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
{viz::RendererType::kSkiaGL, TestRasterType::kGpu},
{viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy},
@@ -69,13 +64,13 @@ class MaskContentLayerClient : public ContentLayerClient {
display_list->push<SaveOp>();
display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()),
SkClipOp::kIntersect, false);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
display_list->push<DrawColorOp>(color, SkBlendMode::kSrc);
PaintFlags flags;
flags.setStyle(PaintFlags::kStroke_Style);
flags.setStrokeWidth(SkIntToScalar(2));
- flags.setColor(SK_ColorWHITE);
+ flags.setColor(SkColors::kWhite);
gfx::Rect inset_rect(bounds_);
while (!inset_rect.IsEmpty()) {
@@ -259,7 +254,7 @@ class LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask
LayerList layers = layer_tree_host()->root_layer()->children();
DCHECK_EQ(3u, layers.size());
// Set background to red.
- layers[0]->SetBackgroundColor(SK_ColorRED);
+ layers[0]->SetBackgroundColor(SkColors::kRed);
// Remove the green layer.
layers.erase(layers.begin() + 1);
layer_tree_host()->root_layer()->SetChildLayerList(layers);
@@ -449,7 +444,7 @@ class CheckerContentLayerClient : public ContentLayerClient {
display_list->push<SaveOp>();
display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()),
SkClipOp::kIntersect, false);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
display_list->push<DrawColorOp>(color, SkBlendMode::kSrc);
PaintFlags flags;
@@ -496,7 +491,7 @@ class CircleContentLayerClient : public ContentLayerClient {
display_list->push<SaveOp>();
display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()),
SkClipOp::kIntersect, false);
- SkColor color = SK_ColorTRANSPARENT;
+ SkColor4f color = SkColors::kTransparent;
display_list->push<DrawColorOp>(color, SkBlendMode::kSrc);
PaintFlags flags;
@@ -788,8 +783,10 @@ class LayerTreeHostMaskAsBlendingPixelTest
static scoped_refptr<Layer> CreateCheckerboardLayer(const gfx::Size& bounds) {
constexpr int kGridSize = 8;
- static const SkColor color_even = SkColorSetRGB(153, 153, 153);
- static const SkColor color_odd = SkColorSetRGB(102, 102, 102);
+ static const SkColor4f color_even =
+ SkColor4f::FromColor(SkColorSetRGB(153, 153, 153));
+ static const SkColor4f color_odd =
+ SkColor4f::FromColor(SkColorSetRGB(102, 102, 102));
auto display_list = base::MakeRefCounted<DisplayItemList>();
display_list->StartPaint();
@@ -873,15 +870,6 @@ class LayerTreeHostMaskAsBlendingPixelTest
MaskTestConfig const kTestConfigs[] = {
MaskTestConfig{{viz::RendererType::kSoftware, TestRasterType::kBitmap}, 0},
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, 0},
- MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
- kUseAntialiasing},
- MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
- kForceShaders},
- MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
- kUseAntialiasing | kForceShaders},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, 0},
MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy},
kUseAntialiasing},
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index 873f6469fc5..12d20437f73 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -441,10 +441,6 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) {
ReadbackTestConfig const kTestConfigs[] = {
ReadbackTestConfig{viz::RendererType::kSoftware, TestReadBackType::kBitmap},
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kTexture},
- ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kBitmap},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kTexture},
ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kBitmap},
#endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 76fc847c36a..fa8d72496d7 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -12,6 +12,7 @@
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/pixel_comparator.h"
#include "cc/test/test_layer_tree_frame_sink.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/test/buildflags.h"
@@ -222,10 +223,6 @@ class LayerTreeHostTilesTestRasterColorSpace
std::vector<RasterTestConfig> const kTestCases = {
{viz::RendererType::kSoftware, TestRasterType::kBitmap},
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- {viz::RendererType::kGL, TestRasterType::kOneCopy},
- {viz::RendererType::kGL, TestRasterType::kGpu},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
{viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
{viz::RendererType::kSkiaGL, TestRasterType::kGpu},
#endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
@@ -265,9 +262,6 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidation, FullRaster) {
std::vector<RasterTestConfig> const kTestCasesMultiThread = {
#if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
- {viz::RendererType::kGL, TestRasterType::kOneCopy},
-#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
{viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
#endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
#if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS)
@@ -335,11 +329,18 @@ TEST_P(LayerTreeHostTilesTestRasterColorSpace, GenericRGB) {
SetColorSpace(gfx::ColorSpace(gfx::ColorSpace::PrimaryID::APPLE_GENERIC_RGB,
gfx::ColorSpace::TransferID::GAMMA18));
- RunPixelTest(picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("primary_colors.png")));
+ // Software rasterizer ignores XYZD50 matrix
+ const auto* target_png =
+ renderer_type() == viz::RendererType::kSoftware
+ ? FILE_PATH_LITERAL("primary_colors.png")
+ : FILE_PATH_LITERAL("primary_colors_sRGB_in_AdobeRGB.png");
+ RunPixelTest(picture_layer_, base::FilePath(target_png));
}
TEST_P(LayerTreeHostTilesTestRasterColorSpace, CustomColorSpace) {
+#if BUILDFLAG(IS_FUCHSIA)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
+#endif
// Create a color space with a different blue point.
SkColorSpacePrimaries primaries;
skcms_Matrix3x3 to_XYZD50;
@@ -355,8 +356,11 @@ TEST_P(LayerTreeHostTilesTestRasterColorSpace, CustomColorSpace) {
SetColorSpace(gfx::ColorSpace::CreateCustom(
to_XYZD50, gfx::ColorSpace::TransferID::SRGB));
- RunPixelTest(picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("primary_colors.png")));
+ // Software rasterizer ignores XYZD50 matrix
+ const auto* target_png = renderer_type() == viz::RendererType::kSoftware
+ ? FILE_PATH_LITERAL("primary_colors.png")
+ : FILE_PATH_LITERAL("primary_colors_icced.png");
+ RunPixelTest(picture_layer_, base::FilePath(target_png));
}
// This test doesn't work on Vulkan because on our hardware we can't render to
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index a2c426e4e93..c66f51e04c6 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -79,6 +79,7 @@
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/service/display/output_surface.h"
+#include "components/viz/service/display/skia_output_surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_gles2_interface.h"
@@ -109,10 +110,6 @@ using testing::StrictMock;
namespace cc {
namespace {
-const char kUserInteraction[] = "Compositor.UserInteraction";
-const char kCheckerboardArea[] = "CheckerboardedContentArea";
-const char kCheckerboardAreaRatio[] = "CheckerboardedContentAreaRatio";
-const char kMissingTiles[] = "NumMissingTiles";
bool LayerSubtreeHasCopyRequest(Layer* layer) {
const LayerTreeHost* host = layer->layer_tree_host();
@@ -315,15 +312,12 @@ class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest {
public:
void BeginTest() override {
PostSetNeedsCommitToMainThread();
- EXPECT_EQ(0, main_frame_scheduled_count_);
EXPECT_EQ(0, main_frame_run_count_);
}
- void DidScheduleBeginMainFrame() override { main_frame_scheduled_count_++; }
void DidRunBeginMainFrame() override { main_frame_run_count_++; }
void DidBeginMainFrame() override {
- EXPECT_EQ(1, main_frame_scheduled_count_);
EXPECT_EQ(1, main_frame_run_count_);
EndTest();
}
@@ -331,7 +325,6 @@ class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest {
void AfterTest() override {}
private:
- int main_frame_scheduled_count_ = 0;
int main_frame_run_count_ = 0;
};
@@ -7391,30 +7384,6 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
// thread.
MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
-class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
- : public LayerTreeHostTestCrispUpAfterPinchEnds {
- protected:
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- scoped_refptr<viz::TestContextProvider> display_context_provider =
- viz::TestContextProvider::Create();
- viz::TestGLES2Interface* gl =
- display_context_provider->UnboundTestContextGL();
- gl->set_support_sync_query(true);
-#if BUILDFLAG(IS_MAC)
- gl->set_support_texture_rectangle(true);
-#endif
- display_context_provider->BindToCurrentThread();
- return LayerTreeTest::CreateDisplayOutputSurfaceOnThread(
- std::move(display_context_provider));
- }
-};
-
-// This test does pinching on the impl side which is not supported in single
-// thread.
-MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
-
class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
protected:
void SetUpUnboundContextProviders(
@@ -8534,7 +8503,7 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest {
// LayerTreeFrameSink was not released. We must receive the ack.
EXPECT_TRUE(received_ack_);
// Cause damage so that we draw and swap.
- layer_tree_host()->root_layer()->SetBackgroundColor(SK_ColorGREEN);
+ layer_tree_host()->root_layer()->SetBackgroundColor(SkColors::kGreen);
break;
case 2:
// LayerTreeFrameSink was released. The ack must be discarded.
@@ -8782,74 +8751,6 @@ class LayerTreeHostTestImageDecodingHints : public LayerTreeHostTest {
MULTI_THREAD_TEST_F(LayerTreeHostTestImageDecodingHints);
-class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
- public:
- LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")),
- ukm_source_id_(123) {}
- void BeginTest() override {
- PostSetNeedsCommitToMainThread();
- layer_tree_host()->SetSourceURL(ukm_source_id_, url_);
- }
-
- void SetupTree() override {
- gfx::Size layer_size(100, 100);
- content_layer_client_.set_bounds(layer_size);
- content_layer_client_.set_fill_with_nonsolid_color(true);
- layer_tree_host()->SetRootLayer(
- FakePictureLayer::Create(&content_layer_client_));
- layer_tree_host()->root_layer()->SetBounds(layer_size);
- LayerTreeTest::SetupTree();
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- if (impl->active_tree()->source_frame_number() != 0)
- return;
-
- // We have an active tree. Start a pinch gesture so we start recording
- // stats.
- impl->GetInputHandler().PinchGestureBegin(
- gfx::Point(100, 100), ui::ScrollInputType::kTouchscreen);
- }
-
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- if (!impl->GetInputHandler().pinch_gesture_active())
- return;
-
- // We just drew a frame, stats for it should have been recorded. End the
- // gesture so they are flushed to the recorder.
- impl->GetInputHandler().PinchGestureEnd(gfx::Point(50, 50));
-
- // RenewTreePriority will run when the smoothness expiration timer fires.
- // Synthetically do it here so the UkmManager is notified.
- impl->RenewTreePriorityForTesting();
-
- auto* recorder = static_cast<ukm::TestUkmRecorder*>(
- impl->ukm_manager()->recorder_for_testing());
- // Tie the source id to the URL. In production, this is already done in
- // Document, and the source id is passed down to cc.
- recorder->UpdateSourceURL(ukm_source_id_, url_);
-
- const auto& entries = recorder->GetEntriesByName(kUserInteraction);
- EXPECT_EQ(1u, entries.size());
- for (const auto* entry : entries) {
- recorder->ExpectEntrySourceHasUrl(entry, url_);
- recorder->ExpectEntryMetric(entry, kCheckerboardArea, 0);
- recorder->ExpectEntryMetric(entry, kMissingTiles, 0);
- recorder->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 0);
- }
-
- EndTest();
- }
-
- private:
- const GURL url_;
- const ukm::SourceId ukm_source_id_;
- FakeContentLayerClient content_layer_client_;
-};
-
-// Only multi-thread mode needs to record UKMs.
-MULTI_THREAD_TEST_F(LayerTreeHostTestCheckerboardUkm);
-
class DontUpdateLayersWithEmptyBounds : public LayerTreeTest {
protected:
void SetupTree() override {
@@ -10122,7 +10023,7 @@ class LayerTreeHostTestOccludedTileReleased
void AddLayerThatObscuresPictureLayer() {
auto covering_layer = SolidColorLayer::Create();
covering_layer->SetBounds(gfx::Size(100, 100));
- covering_layer->SetBackgroundColor(SK_ColorRED);
+ covering_layer->SetBackgroundColor(SkColors::kRed);
covering_layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(covering_layer);
added_obscuring_layer_ = true;
@@ -10146,5 +10047,292 @@ class LayerTreeHostTestNoCommitDeadlock : public LayerTreeHostTest {
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoCommitDeadlock);
+
+// In real site, problem happened like this
+// 1. commit
+// 2. tiling is delayed, so NotifyReadyToActivate is not triggered
+// 3. Draw is called and NotifyReadyToActivate is triggered
+// during PrepareDraw() by TileManager's CheckForCompletedTask().
+// 4. pending_tree()::UpdateDrawProperties() is called after PrepareDraw(),
+// and tiling is recreated if transform is changed
+// 5. Activation happen right after the Draw
+// So tiling with empty tiles will be activated to active tree.
+class LayerTreeHostTestDelayRecreateTiling
+ : public LayerTreeHostTestWithHelper {
+ public:
+ LayerTreeHostTestDelayRecreateTiling() {}
+
+ void SetupTree() override {
+ client_.set_fill_with_nonsolid_color(true);
+ scoped_refptr<FakePictureLayer> root_layer =
+ FakePictureLayer::Create(&client_);
+ root_layer->SetBounds(gfx::Size(150, 150));
+ root_layer->SetIsDrawable(true);
+
+ layer_on_main_ =
+ CreateAndAddFakePictureLayer(gfx::Size(30, 30), root_layer.get());
+
+ // initial transform to force transform node
+ gfx::Transform transform;
+ transform.Scale(2.0f, 1.0f);
+ layer_on_main_->SetTransform(transform);
+
+ layer_tree_host()->SetRootLayer(root_layer);
+
+ LayerTreeHostTest::SetupTree();
+ client_.set_bounds(root_layer->bounds());
+
+ layer_id_ = layer_on_main_->id();
+ }
+
+ void WillCommit(const CommitState&) override {
+ TransformTree& transform_tree =
+ layer_tree_host()->property_trees()->transform_tree_mutable();
+ TransformNode* node =
+ transform_tree.Node(layer_on_main_->transform_tree_index());
+
+ gfx::Transform transform;
+ transform.Scale(2.0f, 1.0f);
+ transform.Translate(0.0f, 0.8f);
+
+ switch (layer_tree_host()->SourceFrameNumber()) {
+ case 1:
+ // in frame1, translation changed and animation start
+ transform_tree.OnTransformAnimated(layer_on_main_->element_id(),
+ transform);
+ node->has_potential_animation = true;
+ break;
+ }
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>(
+ host_impl->pending_tree()->LayerById(layer_id_));
+
+ TransformTree& transform_tree =
+ host_impl->pending_tree()->property_trees()->transform_tree_mutable();
+ TransformNode* node =
+ transform_tree.Node(layer_impl->transform_tree_index());
+
+ if (host_impl->pending_tree()->source_frame_number() == 2) {
+ // delay Activation for this pending tree
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
+
+ // to reproduce problem, conditions to recreate tiling should be changed
+ // after commitcomplete
+ // e.g., transform change, animation status change
+ // commitcomplete -> beginimpl -> draw (pending's updatedrawproperties)
+ // in beginimpl, scroll can be handled, so transform can be changed
+ // in draw, UpdateAnimationState can change animation status
+ node->has_potential_animation = false;
+ transform_tree.set_needs_update(true);
+ host_impl->pending_tree()->set_needs_update_draw_properties();
+
+ // to make sure Draw happen
+ host_impl->SetNeedsRedraw();
+ }
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ if (host_impl->pending_tree() &&
+ host_impl->pending_tree()->source_frame_number() == 2) {
+ host_impl->BlockNotifyReadyToActivateForTesting(false, false);
+ // BlockNotifyReadyToActivateForTesting(false) call NotifyReadyToActivate,
+ // but NotifyReadyToActivate should be called directly instead of PostTask
+ // because it should called inside PrepareToDraw()
+ host_impl->NotifyReadyToActivate();
+ }
+ return draw_result;
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(layer_id_));
+
+ gfx::AxisTransform2d tiling_transform =
+ layer_impl->HighResTiling()->raster_transform();
+
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 1:
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 2:
+ if (should_delay_recreating_tiling_) {
+ // translation is changed in frame2, but recreating tiling should not
+ // happen because ReadyToActivate is true
+ ASSERT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f));
+ ASSERT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0));
+ should_delay_recreating_tiling_ = false;
+ } else {
+ // Invalidating implside will trigger recreating tiling without next
+ // commit
+ ASSERT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f));
+ ASSERT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0.8f));
+ EndTest();
+ }
+ break;
+ case 3:
+ NOTREACHED() << "We shouldn't see another commit in this test";
+ break;
+ }
+ }
+
+ protected:
+ FakeContentLayerClient client_;
+ // to access layer information in main and impl
+ int layer_id_;
+ // to access layer information in main's WillCommit()
+ scoped_refptr<FakePictureLayer> layer_on_main_;
+ bool should_delay_recreating_tiling_ = true;
+};
+MULTI_THREAD_TEST_F(LayerTreeHostTestDelayRecreateTiling);
+
+// This test validate that recreating tiling is delayed by veto conditions and
+// the delayed tiling is created again when the veto conditions are reset.
+class LayerTreeHostTestInvalidateImplSideForRerasterTiling
+ : public LayerTreeHostTestWithHelper {
+ public:
+ void SetupTree() override {
+ client_.set_fill_with_nonsolid_color(true);
+ scoped_refptr<FakePictureLayer> root_layer =
+ FakePictureLayer::Create(&client_);
+ root_layer->SetBounds(gfx::Size(150, 150));
+ root_layer->SetIsDrawable(true);
+
+ layer_on_main_ =
+ CreateAndAddFakePictureLayer(gfx::Size(30, 30), root_layer.get());
+
+ // initial transform to force transform node
+ gfx::Transform transform;
+ transform.Scale(2.0f, 1.0f);
+ layer_on_main_->SetTransform(transform);
+
+ layer_tree_host()->SetRootLayer(root_layer);
+
+ LayerTreeHostTest::SetupTree();
+ client_.set_bounds(root_layer->bounds());
+
+ layer_id_ = layer_on_main_->id();
+ }
+
+ void WillCommit(const CommitState&) override {
+ TransformTree& transform_tree =
+ layer_tree_host()->property_trees()->transform_tree_mutable();
+ TransformNode* node =
+ transform_tree.Node(layer_on_main_->transform_tree_index());
+
+ gfx::Transform transform;
+ transform.Scale(2.0f, 1.0f);
+ transform.Translate(0.0f, 0.8f);
+
+ switch (layer_tree_host()->SourceFrameNumber()) {
+ case 1:
+ // in frame1, translation changed and animation start
+ transform_tree.OnTransformAnimated(layer_on_main_->element_id(),
+ transform);
+ node->has_potential_animation = true;
+ break;
+ }
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void ClearAnimationForLayer(LayerTreeImpl* tree_impl,
+ FakePictureLayerImpl* layer_impl) {
+ if (!tree_impl)
+ return;
+
+ TransformTree& transform_tree =
+ tree_impl->property_trees()->transform_tree_mutable();
+ TransformNode* node =
+ transform_tree.Node(layer_impl->transform_tree_index());
+
+ node->has_potential_animation = false;
+ transform_tree.set_needs_update(true);
+ tree_impl->set_needs_update_draw_properties();
+ }
+
+ TransformNode* TransformNodeForLayer(LayerTreeImpl* tree_impl,
+ FakePictureLayerImpl* layer_impl) {
+ TransformTree& transform_tree =
+ tree_impl->property_trees()->transform_tree_mutable();
+ TransformNode* node =
+ transform_tree.Node(layer_impl->transform_tree_index());
+ return node;
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+ if (host_impl->active_tree()->source_frame_number() == 2) {
+ FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(layer_id_));
+ gfx::AxisTransform2d tiling_transform =
+ target_layer->HighResTiling()->raster_transform();
+ TransformNode* node =
+ TransformNodeForLayer(host_impl->active_tree(), target_layer);
+ if (node->has_potential_animation) {
+ // in frame 2, active tree still have old tiling because animation is
+ // still active.
+ EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f));
+ EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0));
+
+ // now clear animation and trigger a new draw to check if invalidation
+ // implside will be requested for rerastering tiling.
+ ClearAnimationForLayer(host_impl->active_tree(), target_layer);
+ ClearAnimationForLayer(host_impl->recycle_tree(), target_layer);
+ host_impl->SetNeedsRedraw();
+ }
+ }
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(layer_id_));
+ gfx::AxisTransform2d tiling_transform =
+ target_layer->HighResTiling()->raster_transform();
+ TransformNode* node =
+ TransformNodeForLayer(host_impl->active_tree(), target_layer);
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 1:
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 2:
+ if (node->has_potential_animation) {
+ // translation is changed in frame2, but recreating tiling should not
+ // happen because animation is still active.
+ EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f));
+ EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0));
+
+ // trigger draw to check if invalidating implside is not triggered
+ // if animation is still active.
+ host_impl->SetNeedsRedraw();
+ } else {
+ // check if invalidation implside was requested successfully.
+ // new tiling should be created.
+ EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f));
+ EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0.8f));
+ EndTest();
+ }
+ break;
+ }
+ }
+
+ protected:
+ FakeContentLayerClient client_;
+ // to access layer information in main and impl
+ int layer_id_;
+ // to access layer information in main's WillCommit()
+ scoped_refptr<FakePictureLayer> layer_on_main_;
+};
+MULTI_THREAD_TEST_F(LayerTreeHostTestInvalidateImplSideForRerasterTiling);
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index 0a61548c68a..8dd6266cc57 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -60,6 +60,14 @@ class LayerTreeHostAnimationTest : public LayerTreeTest {
timeline_->AttachAnimation(animation_child_.get());
}
+ void DetachAnimationsFromTimeline() {
+ if (animation_)
+ timeline_->DetachAnimation(animation_.get());
+ if (animation_child_)
+ timeline_->DetachAnimation(animation_child_.get());
+ animation_host()->RemoveAnimationTimeline(timeline_.get());
+ }
+
void GetImplTimelineAndAnimationByID(const LayerTreeHostImpl& host_impl) {
AnimationHost* animation_host_impl = GetImplAnimationHost(&host_impl);
timeline_impl_ = animation_host_impl->GetTimelineById(timeline_id_);
@@ -71,6 +79,14 @@ class LayerTreeHostAnimationTest : public LayerTreeTest {
EXPECT_TRUE(animation_child_impl_);
}
+ void CleanupBeforeDestroy() override {
+ // This needs to happen on the main thread (so can't happen in
+ // EndTest()), and needs to happen before DestroyLayerTreeHost()
+ // (which will trigger assertions if we don't do this), so it can't
+ // happen in AfterTest().
+ DetachAnimationsFromTimeline();
+ }
+
AnimationHost* GetImplAnimationHost(
const LayerTreeHostImpl* host_impl) const {
return static_cast<AnimationHost*>(host_impl->mutator_host());
@@ -902,10 +918,8 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted
scroll_layer_element_id_ = scroll_layer_->element_id();
}
- KeyframeEffect& ScrollOffsetKeyframeEffect(
- const LayerTreeHostImpl& host_impl,
- scoped_refptr<FakePictureLayer> layer,
- ElementId element_id) const {
+ KeyframeEffect& ScrollOffsetKeyframeEffect(const LayerTreeHostImpl& host_impl,
+ ElementId element_id) const {
scoped_refptr<ElementAnimations> element_animations =
GetImplAnimationHost(&host_impl)
->GetElementAnimationsForElementId(element_id);
@@ -941,8 +955,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted
// This happens after the impl-only animation is added in
// WillCommitCompleteOnThread.
gfx::KeyframeModel* keyframe_model =
- ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_,
- scroll_layer_element_id_)
+ ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_element_id_)
.GetKeyframeModel(TargetProperty::SCROLL_OFFSET);
DCHECK(keyframe_model);
const ScrollOffsetAnimationCurve* curve =
@@ -969,8 +982,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
if (host_impl->sync_tree()->source_frame_number() == 2) {
gfx::KeyframeModel* keyframe_model =
- ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_,
- scroll_layer_element_id_)
+ ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_element_id_)
.GetKeyframeModel(TargetProperty::SCROLL_OFFSET);
DCHECK(keyframe_model);
const ScrollOffsetAnimationCurve* curve =
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index 6c47500d499..838e0a4b151 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -15,8 +15,6 @@
namespace cc {
namespace {
-const char kRenderingEvent[] = "Compositor.Rendering";
-const char kCheckerboardImagesMetric[] = "CheckerboardedImagesCount";
class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
public:
@@ -29,26 +27,6 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
PostSetNeedsCommitToMainThread();
}
- void VerifyUkmAndEndTest(LayerTreeHostImpl* impl) {
- auto* recorder = static_cast<ukm::TestUkmRecorder*>(
- impl->ukm_manager()->recorder_for_testing());
- // Tie the source id to the URL. In production, this is already done in
- // Document, and the source id is passed down to cc.
- recorder->UpdateSourceURL(ukm_source_id_, url_);
-
- // Change the source to ensure any accumulated metrics are flushed.
- ukm::SourceId newSourceId = ukm::AssignNewSourceId();
- impl->ukm_manager()->SetSourceId(newSourceId);
- recorder->UpdateSourceURL(newSourceId, GURL("chrome://test2"));
-
- const auto& entries = recorder->GetEntriesByName(kRenderingEvent);
- ASSERT_EQ(1u, entries.size());
- auto* entry = entries[0];
- recorder->ExpectEntrySourceHasUrl(entry, url_);
- recorder->ExpectEntryMetric(entry, kCheckerboardImagesMetric, 1);
- EndTest();
- }
-
void InitializeSettings(LayerTreeSettings* settings) override {
settings->enable_checker_imaging = true;
settings->min_image_bytes_to_checker = 512 * 1024;
@@ -154,7 +132,7 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame
expected_update_rect.Union(gfx::Rect(600, 0, 50, 500));
EXPECT_EQ(sync_layer_impl->update_rect(), expected_update_rect);
- VerifyUkmAndEndTest(host_impl);
+ EndTest();
} break;
default:
NOTREACHED();
@@ -219,7 +197,7 @@ class LayerTreeHostCheckerImagingTestImplSideTree
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
num_of_activations_++;
if (num_of_activations_ == 2) {
- VerifyUkmAndEndTest(host_impl);
+ EndTest();
}
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index ce695f67d4a..992af86c6d0 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -204,26 +204,12 @@ class LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder
return nullptr;
}
- std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread(
+ std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread(
viz::DisplayCompositorMemoryAndTaskController*) override {
auto skia_output_surface = viz::FakeSkiaOutputSurface::Create3d();
skia_output_surface->SetOutOfOrderCallbacks(true);
return skia_output_surface;
}
-
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- // Since this test does not override CreateLayerTreeFrameSink, the
- // |compositor_context_provider| will be a viz::TestContextProvider.
- auto* context_support = static_cast<viz::TestContextSupport*>(
- compositor_context_provider->ContextSupport());
- context_support->set_out_of_order_callbacks(true);
-
- return viz::FakeOutputSurface::Create3d(
- std::move(compositor_context_provider));
- }
};
INSTANTIATE_TEST_SUITE_P(
@@ -888,25 +874,13 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage
// and there is no overlay support.
return nullptr;
}
- std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread(
+ std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread(
viz::DisplayCompositorMemoryAndTaskController*) override {
display_context_provider_ = viz::TestContextProvider::Create();
display_context_provider_->BindToCurrentThread();
return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
}
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- // Since this test does not override CreateLayerTreeFrameSink, the
- // |compositor_context_provider| will be a viz::TestContextProvider.
- display_context_provider_ = static_cast<viz::TestContextProvider*>(
- compositor_context_provider.get());
- return viz::FakeOutputSurface::Create3d(
- std::move(compositor_context_provider));
- }
-
void SetupTree() override {
root_ = FakePictureLayer::Create(&client_);
root_->SetBounds(gfx::Size(20, 20));
@@ -1045,25 +1019,13 @@ class LayerTreeHostCopyRequestTestCountSharedImages
// and there is no overlay support.
return nullptr;
}
- std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread(
+ std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread(
viz::DisplayCompositorMemoryAndTaskController*) override {
display_context_provider_ = viz::TestContextProvider::Create();
display_context_provider_->BindToCurrentThread();
return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
}
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- // Since this test does not override CreateLayerTreeFrameSink, the
- // |compositor_context_provider| will be a viz::TestContextProvider.
- display_context_provider_ = static_cast<viz::TestContextProvider*>(
- compositor_context_provider.get());
- return viz::FakeOutputSurface::Create3d(
- std::move(compositor_context_provider));
- }
-
void SetupTree() override {
// The layers in this test have solid color content, so they don't
// actually allocate any textures, making counting easier.
diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
index 92c066cc2e7..364df3eb933 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -387,7 +387,7 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA
// case above). We unblock activate to allow this main frame to commit.
auto unblock = base::BindOnce(
&LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting,
- base::Unretained(impl), false);
+ base::Unretained(impl), false, true);
// Post the unblock instead of doing it immediately so that the main
// frame is fully processed by the compositor thread, and it has a full
// opportunity to wrongly unblock the main thread.
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index bb4c9a09d73..13788d94cba 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -166,7 +166,6 @@ LayerTreeImpl::LayerTreeImpl(
needs_full_tree_sync_(true),
needs_surface_ranges_sync_(false),
next_activation_forces_redraw_(false),
- has_ever_been_drawn_(false),
handle_visibility_changed_(false),
have_scroll_event_handlers_(false),
event_listener_properties_(),
@@ -735,8 +734,6 @@ void LayerTreeImpl::PullLayerTreePropertiesFrom(CommitState& commit_state) {
if (commit_state.force_send_metadata_request)
RequestForceSendMetadata();
- set_has_ever_been_drawn(false);
-
// TODO(ericrk): The viewport changes caused by |top_controls_shown_ratio_|
// changes should propagate back to the main tree. This does not currently
// happen, so we must force the impl tree to update its viewports if
@@ -755,6 +752,10 @@ void LayerTreeImpl::PullLayerTreePropertiesFrom(CommitState& commit_state) {
// Transfer page transition directives.
for (auto& request : commit_state.document_transition_requests)
AddDocumentTransitionRequest(std::move(request));
+
+ SetVisualUpdateDurations(
+ commit_state.previous_surfaces_visual_update_duration,
+ commit_state.visual_update_duration);
}
void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) {
@@ -844,6 +845,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
// This should match the property synchronization in
// LayerTreeHost::finishCommitOnImplThread().
target_tree->set_source_frame_number(source_frame_number());
+ target_tree->set_trace_id(trace_id());
target_tree->set_background_color(background_color());
target_tree->set_have_scroll_event_handlers(have_scroll_event_handlers());
target_tree->set_event_listener_properties(
@@ -862,8 +864,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
else
target_tree->set_hud_layer(nullptr);
- target_tree->has_ever_been_drawn_ = false;
-
// Note: this needs to happen after SetPropertyTrees.
target_tree->HandleTickmarksVisibilityChange();
target_tree->HandleScrollbarShowRequests();
@@ -881,6 +881,9 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
for (auto& request : TakeDocumentTransitionRequests())
target_tree->AddDocumentTransitionRequest(std::move(request));
+
+ target_tree->SetVisualUpdateDurations(
+ previous_surfaces_visual_update_duration_, visual_update_duration_);
}
void LayerTreeImpl::HandleTickmarksVisibilityChange() {
@@ -1153,23 +1156,45 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id,
int transform_node_index) {
// This includes all animations, even those that are finished but
// haven't yet been deleted.
- if (mutator_host()->HasAnyAnimationTargetingProperty(
- element_id, TargetProperty::TRANSFORM)) {
- TransformTree& transform_tree = property_trees()->transform_tree_mutable();
- if (TransformNode* node = transform_tree.Node(transform_node_index)) {
- ElementListType list_type = GetElementTypeForAnimation();
- bool has_potential_animation =
- mutator_host()->HasPotentiallyRunningTransformAnimation(element_id,
- list_type);
- if (node->has_potential_animation != has_potential_animation) {
- node->has_potential_animation = has_potential_animation;
- node->maximum_animation_scale =
- mutator_host()->MaximumScale(element_id, list_type);
- transform_tree.set_needs_update(true);
- set_needs_update_draw_properties();
+
+ // A given ElementId should be associated with only a single transform
+ // property. However, the ElementId is opaque to cc. (If it comes from
+ // blink, it was constructed with a CompositorElementIdNamespace specific to
+ // the correct property. Otherwise, only the transform property should be
+ // used.)
+ const TargetProperty::Type transform_properties[] = {
+ TargetProperty::TRANSFORM, TargetProperty::SCALE, TargetProperty::ROTATE,
+ TargetProperty::TRANSLATE};
+#if DCHECK_IS_ON()
+ unsigned property_count = 0u;
+#endif
+
+ for (TargetProperty::Type property : transform_properties) {
+ if (mutator_host()->HasAnyAnimationTargetingProperty(element_id,
+ property)) {
+#if DCHECK_IS_ON()
+ ++property_count;
+#endif
+ TransformTree& transform_tree =
+ property_trees()->transform_tree_mutable();
+ if (TransformNode* node = transform_tree.Node(transform_node_index)) {
+ ElementListType list_type = GetElementTypeForAnimation();
+ bool has_potential_animation =
+ mutator_host()->HasPotentiallyRunningAnimationForProperty(
+ element_id, list_type, property);
+ if (node->has_potential_animation != has_potential_animation) {
+ node->has_potential_animation = has_potential_animation;
+ node->maximum_animation_scale =
+ mutator_host()->MaximumScale(element_id, list_type);
+ transform_tree.set_needs_update(true);
+ set_needs_update_draw_properties();
+ }
}
}
}
+#if DCHECK_IS_ON()
+ DCHECK_LE(property_count, 1u);
+#endif
}
void LayerTreeImpl::UpdatePageScaleNode() {
@@ -1187,7 +1212,7 @@ void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
float clamped_page_scale = ClampPageScaleFactorToLimits(active_page_scale);
// Temporary crash logging for https://crbug.com/845097.
static bool has_dumped_without_crashing = false;
- if (host_impl_->settings().is_layer_tree_for_subframe &&
+ if (!host_impl_->settings().is_for_scalable_page &&
clamped_page_scale != 1.f && !has_dumped_without_crashing) {
has_dumped_without_crashing = true;
static auto* psf_oopif_error = base::debug::AllocateCrashKeyString(
@@ -1196,10 +1221,8 @@ void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
psf_oopif_error, base::StringPrintf("%f", clamped_page_scale));
base::debug::DumpWithoutCrashing();
}
- if (page_scale_factor()->SetCurrent(clamped_page_scale)) {
+ if (page_scale_factor()->SetCurrent(clamped_page_scale))
DidUpdatePageScale();
- UpdatePageScaleNode();
- }
}
void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
@@ -1230,10 +1253,6 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
if (changed_page_scale)
DidUpdatePageScale();
-
- DCHECK(lifecycle().AllowsPropertyTreeAccess());
- if (page_scale_factor)
- UpdatePageScaleNode();
}
void LayerTreeImpl::SetBrowserControlsParams(
@@ -1338,27 +1357,33 @@ bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
}
void LayerTreeImpl::DidUpdatePageScale() {
- if (IsActiveTree())
+ if (IsActiveTree()) {
page_scale_factor()->SetCurrent(
ClampPageScaleFactorToLimits(current_page_scale_factor()));
- set_needs_update_draw_properties();
-
- // Viewport scrollbar sizes depend on the page scale factor.
- SetScrollbarGeometriesNeedUpdate();
+ // Ensure the other trees are kept in sync.
+ if (host_impl_->pending_tree())
+ host_impl_->pending_tree()->DidUpdatePageScale();
+ if (host_impl_->recycle_tree())
+ host_impl_->recycle_tree()->DidUpdatePageScale();
- if (IsActiveTree()) {
if (settings().scrollbar_flash_after_any_scroll_update) {
host_impl_->FlashAllScrollbars(true);
- return;
- }
- if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) {
+ } else if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) {
if (ScrollbarAnimationController* controller =
host_impl_->ScrollbarAnimationControllerForElementId(
scroll_node->element_id))
controller->DidScrollUpdate();
}
}
+
+ DCHECK(lifecycle().AllowsPropertyTreeAccess());
+ UpdatePageScaleNode();
+
+ set_needs_update_draw_properties();
+
+ // Viewport scrollbar sizes depend on the page scale factor.
+ SetScrollbarGeometriesNeedUpdate();
}
void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
@@ -1564,11 +1589,14 @@ bool LayerTreeImpl::UpdateDrawProperties(
this, &render_surface_list_, output_update_layer_list_for_testing);
if (const char* client_name = GetClientNameForMetrics()) {
- UMA_HISTOGRAM_COUNTS_1M(
- base::StringPrintf(
- "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs",
- client_name),
- timer.Elapsed().InMicroseconds());
+ // This metric is only recorded for the Browser.
+ if (settings().single_thread_proxy_scheduler) {
+ UMA_HISTOGRAM_COUNTS_1M(
+ base::StringPrintf(
+ "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs",
+ client_name),
+ timer.Elapsed().InMicroseconds());
+ }
UMA_HISTOGRAM_COUNTS_100(
base::StringPrintf("Compositing.%s.NumRenderSurfaces", client_name),
base::saturated_cast<int>(render_surface_list_.size()));
@@ -1854,6 +1882,10 @@ bool LayerTreeImpl::IsSyncTree() const {
return host_impl_->sync_tree() == this;
}
+bool LayerTreeImpl::HasPendingTree() const {
+ return host_impl_->pending_tree() != nullptr;
+}
+
LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
LayerTreeImpl* tree = host_impl_->active_tree();
if (!tree)
@@ -2154,6 +2186,11 @@ void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) {
*scrollbar_layer_id = scrollbar_layer->id();
+ if (IsActiveTree()) {
+ host_impl_->DidRegisterScrollbarLayer(scroll_element_id,
+ scrollbar_layer->orientation());
+ }
+
if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() &&
scrollbar_layer->GetScrollbarAnimator() !=
LayerTreeSettings::NO_ANIMATOR) {
@@ -2895,4 +2932,25 @@ bool LayerTreeImpl::HasDocumentTransitionRequests() const {
return !document_transition_requests_.empty();
}
+bool LayerTreeImpl::IsReadyToActivate() const {
+ return host_impl_->IsReadyToActivate();
+}
+
+void LayerTreeImpl::ClearVisualUpdateDurations() {
+ previous_surfaces_visual_update_duration_ = base::TimeDelta();
+ visual_update_duration_ = base::TimeDelta();
+}
+
+void LayerTreeImpl::SetVisualUpdateDurations(
+ base::TimeDelta previous_surfaces_visual_update_duration,
+ base::TimeDelta visual_update_duration) {
+ previous_surfaces_visual_update_duration_ =
+ previous_surfaces_visual_update_duration;
+ visual_update_duration_ = visual_update_duration;
+}
+
+void LayerTreeImpl::RequestImplSideInvalidationForRerasterTiling() {
+ host_impl_->RequestImplSideInvalidationForRerasterTiling();
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index fd335404e21..172bcc07769 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -139,6 +139,7 @@ class CC_EXPORT LayerTreeImpl {
bool IsPendingTree() const;
bool IsRecycleTree() const;
bool IsSyncTree() const;
+ bool HasPendingTree() const;
LayerImpl* FindActiveTreeLayerById(int id);
LayerImpl* FindPendingTreeLayerById(int id);
// TODO(bokan): PinchGestureActive is a layering violation, it's not related
@@ -165,6 +166,8 @@ class CC_EXPORT LayerTreeImpl {
const scoped_refptr<DisplayItemList>& display_list);
TargetColorParams GetTargetColorParams(
gfx::ContentColorUsage content_color_usage) const;
+ bool IsReadyToActivate() const;
+ void RequestImplSideInvalidationForRerasterTiling();
// Tree specific methods exposed to layer-impl tree.
// ---------------------------------------------------------------------------
@@ -221,9 +224,14 @@ class CC_EXPORT LayerTreeImpl {
// Adapts an iterator of std::unique_ptr<LayerImpl> to an iterator of
// LayerImpl*.
template <typename Iterator>
- class IteratorAdapter
- : public std::iterator<std::forward_iterator_tag, LayerImpl*> {
+ class IteratorAdapter {
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = LayerImpl*;
+ using difference_type = std::ptrdiff_t;
+ using pointer = LayerImpl**;
+ using reference = LayerImpl*&;
+
explicit IteratorAdapter(Iterator it) : it_(it) {}
bool operator==(IteratorAdapter o) const { return it_ == o.it_; }
bool operator!=(IteratorAdapter o) const { return !(*this == o); }
@@ -278,6 +286,9 @@ class CC_EXPORT LayerTreeImpl {
source_frame_number_ = frame_number;
}
+ uint64_t trace_id() const { return trace_id_; }
+ void set_trace_id(uint64_t val) { trace_id_ = val; }
+
bool is_first_frame_after_commit() const {
return source_frame_number_ != is_first_frame_after_commit_tracker_;
}
@@ -432,13 +443,17 @@ class CC_EXPORT LayerTreeImpl {
float page_scale_factor_for_scroll() const {
DCHECK(external_page_scale_factor_ == 1.f ||
current_page_scale_factor() == 1.f ||
- !settings().is_layer_tree_for_subframe);
+ settings().is_for_scalable_page);
return external_page_scale_factor_ * current_page_scale_factor();
}
const gfx::DisplayColorSpaces& display_color_spaces() const {
return display_color_spaces_;
}
+ const ViewportPropertyIds& viewport_property_ids() const {
+ return viewport_property_ids_;
+ }
+
SyncedElasticOverscroll* elastic_overscroll() {
return elastic_overscroll_.get();
}
@@ -492,11 +507,6 @@ class CC_EXPORT LayerTreeImpl {
void ForceRedrawNextActivation() { next_activation_forces_redraw_ = true; }
- void set_has_ever_been_drawn(bool has_drawn) {
- has_ever_been_drawn_ = has_drawn;
- }
- bool has_ever_been_drawn() const { return has_ever_been_drawn_; }
-
void set_ui_resource_request_queue(UIResourceRequestQueue queue);
const RenderSurfaceList& GetRenderSurfaceList() const;
@@ -783,6 +793,17 @@ class CC_EXPORT LayerTreeImpl {
bool HasDocumentTransitionRequests() const;
+ void ClearVisualUpdateDurations();
+ void SetVisualUpdateDurations(
+ base::TimeDelta previous_surfaces_visual_update_duration,
+ base::TimeDelta visual_update_duration);
+ base::TimeDelta previous_surfaces_visual_update_duration() const {
+ return previous_surfaces_visual_update_duration_;
+ }
+ base::TimeDelta visual_update_duration() const {
+ return visual_update_duration_;
+ }
+
protected:
float ClampPageScaleFactorToLimits(float page_scale_factor) const;
void PushPageScaleFactorAndLimits(const float* page_scale_factor,
@@ -810,6 +831,7 @@ class CC_EXPORT LayerTreeImpl {
raw_ptr<LayerTreeHostImpl> host_impl_;
int source_frame_number_;
+ uint64_t trace_id_ = 0;
int is_first_frame_after_commit_tracker_;
raw_ptr<HeadsUpDisplayLayerImpl> hud_layer_;
PropertyTrees property_trees_;
@@ -896,8 +918,6 @@ class CC_EXPORT LayerTreeImpl {
bool next_activation_forces_redraw_;
- bool has_ever_been_drawn_;
-
bool handle_visibility_changed_;
std::vector<std::unique_ptr<SwapPromise>> swap_promise_list_;
@@ -942,6 +962,13 @@ class CC_EXPORT LayerTreeImpl {
// Document transition requests to be transferred to Viz.
std::vector<std::unique_ptr<DocumentTransitionRequest>>
document_transition_requests_;
+
+ // The cumulative time spent performing visual updates for all Surfaces before
+ // this one.
+ base::TimeDelta previous_surfaces_visual_update_duration_;
+ // The cumulative time spent performing visual updates for the current
+ // Surface.
+ base::TimeDelta visual_update_duration_;
};
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index fa3b501754c..939a54f9115 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -5,18 +5,19 @@
#ifndef CC_TREES_LAYER_TREE_MUTATOR_H_
#define CC_TREES_LAYER_TREE_MUTATOR_H_
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
#include "base/callback_forward.h"
+#include "base/check.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/trees/animation_effect_timings.h"
#include "cc/trees/animation_options.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
namespace cc {
// TOOD(kevers): Remove kDrop once confirmed that it is no longer needed under
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index f6094a5defe..8dfe968b631 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -114,7 +114,11 @@ class CC_EXPORT LayerTreeSettings {
// Indicates the case when a sub-frame gets its own LayerTree because it's
// rendered in a different process from its ancestor frames.
- bool is_layer_tree_for_subframe = false;
+ bool is_for_embedded_frame = false;
+
+ // Indicates when the LayerTree is for a portal element, GuestView, or top
+ // level frame. In all these cases we may have a page scale.
+ bool is_for_scalable_page = true;
// Determines whether we disallow non-exact matches when finding resources
// in ResourcePool. Only used for layout or pixel tests, as non-deterministic
@@ -204,6 +208,10 @@ class CC_EXPORT LayerTreeSettings {
// even if the layer is not drawn. For example, if the layer is occluded it is
// still considered drawn and will not be impacted by this feature.
bool release_tile_resources_for_hidden_layers = false;
+
+ // Whether Fluent scrollbar is enabled. Please check https://crbug.com/1292117
+ // to find the link to the Fluent Scrollbar spec and related CLs.
+ bool enable_fluent_scrollbar = false;
};
class CC_EXPORT LayerListSettings : public LayerTreeSettings {
diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h
index 0c344bb1b9e..819856cde5a 100644
--- a/chromium/cc/trees/mutator_host.h
+++ b/chromium/cc/trees/mutator_host.h
@@ -82,29 +82,14 @@ class MutatorHost {
virtual bool ScrollOffsetAnimationWasInterrupted(
ElementId element_id) const = 0;
- virtual bool IsAnimatingFilterProperty(ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool IsAnimatingBackdropFilterProperty(
- ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool IsAnimatingOpacityProperty(ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool IsAnimatingTransformProperty(
- ElementId element_id,
- ElementListType list_type) const = 0;
+ virtual bool IsAnimatingProperty(ElementId element_id,
+ ElementListType list_type,
+ TargetProperty::Type property) const = 0;
- virtual bool HasPotentiallyRunningFilterAnimation(
- ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool HasPotentiallyRunningBackdropFilterAnimation(
+ virtual bool HasPotentiallyRunningAnimationForProperty(
ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool HasPotentiallyRunningOpacityAnimation(
- ElementId element_id,
- ElementListType list_type) const = 0;
- virtual bool HasPotentiallyRunningTransformAnimation(
- ElementId element_id,
- ElementListType list_type) const = 0;
+ ElementListType list_type,
+ TargetProperty::Type property) const = 0;
virtual bool HasAnyAnimationTargetingProperty(
ElementId element_id,
@@ -156,6 +141,7 @@ class MutatorHost {
virtual bool HasCanvasInvalidation() const = 0;
virtual bool HasJSAnimation() const = 0;
virtual bool HasSmilAnimation() const = 0;
+ virtual bool HasSharedElementTransition() const = 0;
// Iterates through all animations and returns the minimum tick interval.
// Returns 0 if there is a continuous animation which should be ticked
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index 5a2ac9990a6..7a3bb079487 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -22,6 +22,7 @@
#include "cc/trees/property_tree.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
+#include "cc/trees/viewport_property_ids.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "ui/gfx/geometry/outsets_f.h"
#include "ui/gfx/geometry/point_conversions.h"
@@ -57,7 +58,6 @@ PropertyTree<T>& PropertyTree<T>::operator=(const PropertyTree<T>&) = default;
TransformTree::TransformTree(PropertyTrees* property_trees)
: PropertyTree<TransformNode>(property_trees),
page_scale_factor_(1.f),
- overscroll_node_id_(kInvalidPropertyNodeId),
fixed_elements_dont_overscroll_(false),
device_scale_factor_(1.f),
device_transform_scale_factor_(1.f) {
@@ -128,7 +128,6 @@ void TransformTree::clear() {
PropertyTree<TransformNode>::clear();
page_scale_factor_ = 1.f;
- overscroll_node_id_ = kInvalidPropertyNodeId;
fixed_elements_dont_overscroll_ = false;
device_scale_factor_ = 1.f;
device_transform_scale_factor_ = 1.f;
@@ -174,14 +173,16 @@ void TransformTree::ResetChangeTracking() {
}
}
-void TransformTree::UpdateTransforms(int id) {
+void TransformTree::UpdateTransforms(
+ int id,
+ const ViewportPropertyIds* viewport_property_ids) {
TransformNode* node = Node(id);
TransformNode* parent_node = parent(node);
DCHECK(parent_node);
// TODO(flackr): Only dirty when scroll offset changes.
if (node->sticky_position_constraint_id >= 0 ||
node->needs_local_transform_update || ShouldUndoOverscroll(node)) {
- UpdateLocalTransform(node);
+ UpdateLocalTransform(node, viewport_property_ids);
} else {
UndoSnapping(node);
}
@@ -460,12 +461,19 @@ bool TransformTree::ShouldUndoOverscroll(const TransformNode* node) const {
void TransformTree::UpdateFixedNodeTransformAndClip(
const TransformNode* node,
- gfx::Vector2dF& fixed_position_adjustment) {
- if (!ShouldUndoOverscroll(node) ||
- overscroll_node_id_ == kInvalidPropertyNodeId)
+ gfx::Vector2dF& fixed_position_adjustment,
+ const ViewportPropertyIds* viewport_property_ids) {
+ const int transform_id =
+ viewport_property_ids
+ ? viewport_property_ids->overscroll_elasticity_transform
+ : kInvalidPropertyNodeId;
+ const int clip_id = viewport_property_ids ? viewport_property_ids->outer_clip
+ : kInvalidPropertyNodeId;
+ if (!ShouldUndoOverscroll(node) || transform_id == kInvalidPropertyNodeId ||
+ clip_id == kInvalidPropertyNodeId)
return;
- const TransformNode* overscroll_node = Node(overscroll_node_id_);
+ const TransformNode* overscroll_node = Node(transform_id);
const gfx::Vector2dF overscroll_offset =
overscroll_node->scroll_offset.OffsetFromOrigin();
if (overscroll_offset.IsZero())
@@ -475,24 +483,24 @@ void TransformTree::UpdateFixedNodeTransformAndClip(
gfx::ScaleVector2d(overscroll_offset, 1.f / page_scale_factor());
ClipTree& clip_tree = property_trees()->clip_tree_mutable();
- ClipNode* clip_node = clip_tree.Node(clip_tree.overscroll_node_id());
-
- if (clip_node) {
- // Inflate the clip rect based on the overscroll direction.
- gfx::OutsetsF outsets;
- fixed_position_adjustment.x() < 0
- ? outsets.set_left(-fixed_position_adjustment.x())
- : outsets.set_right(fixed_position_adjustment.x());
- fixed_position_adjustment.y() < 0
- ? outsets.set_top(-fixed_position_adjustment.y())
- : outsets.set_bottom(fixed_position_adjustment.y());
-
- clip_node->clip.Outset(outsets);
- clip_tree.set_needs_update(true);
- }
-}
-
-void TransformTree::UpdateLocalTransform(TransformNode* node) {
+ ClipNode* clip_node = clip_tree.Node(clip_id);
+ DCHECK(clip_node);
+
+ // Inflate the clip rect based on the overscroll direction.
+ gfx::OutsetsF outsets;
+ fixed_position_adjustment.x() < 0
+ ? outsets.set_left(-fixed_position_adjustment.x())
+ : outsets.set_right(fixed_position_adjustment.x());
+ fixed_position_adjustment.y() < 0
+ ? outsets.set_top(-fixed_position_adjustment.y())
+ : outsets.set_bottom(fixed_position_adjustment.y());
+ clip_node->clip.Outset(outsets);
+ clip_tree.set_needs_update(true);
+}
+
+void TransformTree::UpdateLocalTransform(
+ TransformNode* node,
+ const ViewportPropertyIds* viewport_property_ids) {
gfx::Transform transform;
transform.Translate3d(node->post_translation.x() + node->origin.x(),
node->post_translation.y() + node->origin.y(),
@@ -504,7 +512,8 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) {
property_trees()->outer_viewport_container_bounds_delta().y());
}
- UpdateFixedNodeTransformAndClip(node, fixed_position_adjustment);
+ UpdateFixedNodeTransformAndClip(node, fixed_position_adjustment,
+ viewport_property_ids);
transform.Translate(fixed_position_adjustment -
node->scroll_offset.OffsetFromOrigin());
transform.Translate(StickyPositionOffset(node));
@@ -709,7 +718,6 @@ void TransformTree::SetToScreen(int node_id, const gfx::Transform& transform) {
bool TransformTree::operator==(const TransformTree& other) const {
return PropertyTree::operator==(other) &&
page_scale_factor_ == other.page_scale_factor() &&
- overscroll_node_id_ == other.overscroll_node_id() &&
fixed_elements_dont_overscroll_ ==
other.fixed_elements_dont_overscroll() &&
device_scale_factor_ == other.device_scale_factor() &&
@@ -1265,8 +1273,7 @@ EffectTree::CopyRequestMap EffectTree::TakeCopyRequests() {
}
ClipTree::ClipTree(PropertyTrees* property_trees)
- : PropertyTree<ClipNode>(property_trees),
- overscroll_node_id_(kInvalidPropertyNodeId) {}
+ : PropertyTree<ClipNode>(property_trees) {}
void ClipTree::SetViewportClip(gfx::RectF viewport_rect) {
if (size() < 2)
@@ -1286,8 +1293,7 @@ gfx::RectF ClipTree::ViewportClip() const {
#if DCHECK_IS_ON()
bool ClipTree::operator==(const ClipTree& other) const {
- return PropertyTree::operator==(other) &&
- overscroll_node_id_ == other.overscroll_node_id();
+ return PropertyTree::operator==(other);
}
#endif
@@ -1964,6 +1970,9 @@ bool PropertyTrees::ElementIsAnimatingChanged(
const ElementId element_id = it->second;
switch (property) {
case TargetProperty::TRANSFORM:
+ case TargetProperty::SCALE:
+ case TargetProperty::ROTATE:
+ case TargetProperty::TRANSLATE:
if (TransformNode* transform_node =
transform_tree_mutable().FindNodeFromElementId(element_id)) {
if (mask.currently_running[property])
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 12ecb6eb4af..78f52a32cbc 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -53,6 +53,7 @@ class LayerTreeImpl;
class RenderSurfaceImpl;
struct RenderSurfacePropertyChangedFlags;
struct CompositorCommitData;
+struct ViewportPropertyIds;
using SyncedScrollOffset =
SyncedProperty<AdditionGroup<gfx::PointF, gfx::Vector2dF>>;
@@ -182,7 +183,9 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
const gfx::Transform& transform);
void ResetChangeTracking();
// Updates the parent, target, and screen space transforms and snapping.
- void UpdateTransforms(int id);
+ void UpdateTransforms(
+ int id,
+ const ViewportPropertyIds* viewport_property_ids = nullptr);
void UpdateTransformChanged(TransformNode* node, TransformNode* parent_node);
void UpdateNodeAndAncestorsAreAnimatedOrInvertible(
TransformNode* node,
@@ -199,8 +202,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
}
float page_scale_factor() const { return page_scale_factor_; }
- void set_overscroll_node_id(int id) { overscroll_node_id_ = id; }
- int overscroll_node_id() const { return overscroll_node_id_; }
void set_fixed_elements_dont_overscroll(bool value) {
fixed_elements_dont_overscroll_ = value;
}
@@ -249,7 +250,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
bool ShouldUndoOverscroll(const TransformNode* node) const;
void UpdateFixedNodeTransformAndClip(
const TransformNode* node,
- gfx::Vector2dF& fixed_position_adjustment);
+ gfx::Vector2dF& fixed_position_adjustment,
+ const ViewportPropertyIds* viewport_property_ids);
const StickyPositionNodeData* GetStickyPositionData(int node_id) const {
return const_cast<TransformTree*>(this)->MutableStickyPositionData(node_id);
@@ -276,7 +278,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
StickyPositionNodeData* MutableStickyPositionData(int node_id);
gfx::Vector2dF StickyPositionOffset(TransformNode* node);
- void UpdateLocalTransform(TransformNode* node);
+ void UpdateLocalTransform(TransformNode* node,
+ const ViewportPropertyIds* viewport_property_ids);
void UpdateScreenSpaceTransform(TransformNode* node,
TransformNode* parent_node);
void UpdateAnimationProperties(TransformNode* node,
@@ -291,7 +294,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
// scale is calculated using page scale factor, device scale factor and the
// scale factor of device transform. So we need to store them explicitly.
float page_scale_factor_;
- int overscroll_node_id_;
bool fixed_elements_dont_overscroll_;
float device_scale_factor_;
float device_transform_scale_factor_;
@@ -333,14 +335,6 @@ class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> {
void SetViewportClip(gfx::RectF viewport_rect);
gfx::RectF ViewportClip() const;
-
- void set_overscroll_node_id(int id) { overscroll_node_id_ = id; }
- int overscroll_node_id() const { return overscroll_node_id_; }
-
- private:
- // Used to track the ClipNode that is corresponding to the overscroll
- // TransformNode.
- int overscroll_node_id_;
};
class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index 20c374bd36d..00eb3a85b00 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -112,14 +112,16 @@ class PropertyTreeBuilderContext {
// Methods to query state from the AnimationHost ----------------------
bool OpacityIsAnimating(const MutatorHost& host, Layer* layer) {
- return host.IsAnimatingOpacityProperty(layer->element_id(),
- layer->GetElementTypeForAnimation());
+ return host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::OPACITY);
}
bool HasPotentiallyRunningOpacityAnimation(const MutatorHost& host,
Layer* layer) {
- return host.HasPotentiallyRunningOpacityAnimation(
- layer->element_id(), layer->GetElementTypeForAnimation());
+ return host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::OPACITY);
}
bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) {
@@ -128,25 +130,49 @@ bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) {
}
bool FilterIsAnimating(const MutatorHost& host, Layer* layer) {
- return host.IsAnimatingFilterProperty(layer->element_id(),
- layer->GetElementTypeForAnimation());
+ return host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::FILTER);
}
bool HasPotentiallyRunningFilterAnimation(const MutatorHost& host,
Layer* layer) {
- return host.HasPotentiallyRunningFilterAnimation(
- layer->element_id(), layer->GetElementTypeForAnimation());
+ return host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::FILTER);
}
bool TransformIsAnimating(const MutatorHost& host, Layer* layer) {
- return host.IsAnimatingTransformProperty(layer->element_id(),
- layer->GetElementTypeForAnimation());
+ DCHECK(!host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::SCALE) &&
+ !host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::ROTATE) &&
+ !host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSLATE))
+ << "individual transform properties only supported in layer lists mode";
+ return host.IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSFORM);
}
bool HasPotentiallyRunningTransformAnimation(const MutatorHost& host,
Layer* layer) {
- return host.HasPotentiallyRunningTransformAnimation(
- layer->element_id(), layer->GetElementTypeForAnimation());
+ DCHECK(!host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::SCALE) &&
+ !host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::ROTATE) &&
+ !host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSLATE))
+ << "individual transform properties only supported in layer lists mode";
+ return host.HasPotentiallyRunningAnimationForProperty(
+ layer->element_id(), layer->GetElementTypeForAnimation(),
+ TargetProperty::TRANSFORM);
}
float MaximumAnimationScale(const MutatorHost& host, Layer* layer) {
@@ -236,6 +262,13 @@ bool PropertyTreeBuilderContext::AddTransformNodeIfNeeded(
// the Running state right after commit on the compositor thread.
const bool has_any_transform_animation = HasAnyAnimationTargetingProperty(
mutator_host_, layer, TargetProperty::TRANSFORM);
+ DCHECK(!HasAnyAnimationTargetingProperty(mutator_host_, layer,
+ TargetProperty::SCALE) &&
+ !HasAnyAnimationTargetingProperty(mutator_host_, layer,
+ TargetProperty::ROTATE) &&
+ !HasAnyAnimationTargetingProperty(mutator_host_, layer,
+ TargetProperty::TRANSLATE))
+ << "individual transform properties only supported in layer lists mode";
const bool has_surface = created_render_surface;
@@ -683,13 +716,15 @@ void PropertyTreeBuilderContext::AddScrollNodeIfNeeded(
void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor,
Layer* layer,
DataForRecursion* data_for_children) {
- SkColor background_color = layer->background_color();
+ // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+ SkColor background_color = layer->background_color().toSkColor();
data_for_children->safe_opaque_background_color =
SkColorGetA(background_color) == 255
? background_color
: data_from_ancestor.safe_opaque_background_color;
+ // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
layer->SetSafeOpaqueBackgroundColor(
- data_for_children->safe_opaque_background_color);
+ SkColor4f::FromColor(data_for_children->safe_opaque_background_color));
}
void PropertyTreeBuilderContext::BuildPropertyTreesInternal(
diff --git a/chromium/cc/trees/property_tree_builder_unittest.cc b/chromium/cc/trees/property_tree_builder_unittest.cc
index b5639ee0e11..5b5f96f4476 100644
--- a/chromium/cc/trees/property_tree_builder_unittest.cc
+++ b/chromium/cc/trees/property_tree_builder_unittest.cc
@@ -489,8 +489,9 @@ TEST_F(PropertyTreeBuilderTest, AnimatedOpacityCreatesRenderSurface) {
static bool FilterIsAnimating(LayerImpl* layer) {
MutatorHost* host = layer->layer_tree_impl()->mutator_host();
- return host->IsAnimatingFilterProperty(layer->element_id(),
- layer->GetElementTypeForAnimation());
+ return host->IsAnimatingProperty(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ TargetProperty::FILTER);
}
// Verify that having an animated filter (but no current filter, as these
@@ -526,8 +527,9 @@ TEST_F(PropertyTreeBuilderTest, AnimatedFilterCreatesRenderSurface) {
bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) {
MutatorHost* host = layer.layer_tree_impl()->mutator_host();
- return host->HasPotentiallyRunningFilterAnimation(
- layer.element_id(), layer.GetElementTypeForAnimation());
+ return host->HasPotentiallyRunningAnimationForProperty(
+ layer.element_id(), layer.GetElementTypeForAnimation(),
+ TargetProperty::FILTER);
}
// Verify that having a filter animation with a delayed start time creates a
diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc
index b2ec896d7a4..13dcfc9ab46 100644
--- a/chromium/cc/trees/property_tree_unittest.cc
+++ b/chromium/cc/trees/property_tree_unittest.cc
@@ -16,6 +16,7 @@
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
+#include "cc/trees/viewport_property_ids.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/test/geometry_util.h"
@@ -202,6 +203,7 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) {
FakeProtectedSequenceSynchronizer synchronizer;
PropertyTrees property_trees(synchronizer);
+ ViewportPropertyIds viewport_property_ids;
ClipTree& clip_tree = property_trees.clip_tree_mutable();
const gfx::RectF clip_rect(0, 0, 100, 100);
ClipNode clip_node;
@@ -209,20 +211,20 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) {
clip_node.parent_id = 0;
clip_node.clip = clip_rect;
clip_tree.Insert(clip_node, 0);
- clip_tree.set_overscroll_node_id(clip_node.id);
+ viewport_property_ids.outer_clip = clip_node.id;
TransformTree& transform_tree = property_trees.transform_tree_mutable();
TransformNode contents_root;
contents_root.local.Translate(2, 2);
contents_root.id = transform_tree.Insert(contents_root, 0);
- transform_tree.UpdateTransforms(1);
+ transform_tree.UpdateTransforms(1, &viewport_property_ids);
const gfx::PointF overscroll_offset(0, 10);
TransformNode overscroll_node;
overscroll_node.scroll_offset = overscroll_offset;
overscroll_node.id = transform_tree.Insert(overscroll_node, 1);
+ viewport_property_ids.overscroll_elasticity_transform = overscroll_node.id;
- transform_tree.set_overscroll_node_id(overscroll_node.id);
transform_tree.set_fixed_elements_dont_overscroll(true);
TransformNode fixed_node;
@@ -231,8 +233,9 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) {
EXPECT_TRUE(transform_tree.ShouldUndoOverscroll(&fixed_node));
- transform_tree.UpdateTransforms(2); // overscroll_node
- transform_tree.UpdateTransforms(3); // fixed_node
+ transform_tree.UpdateTransforms(2,
+ &viewport_property_ids); // overscroll_node
+ transform_tree.UpdateTransforms(3, &viewport_property_ids); // fixed_node
gfx::Transform expected;
expected.Translate(overscroll_offset.OffsetFromOrigin());
@@ -240,7 +243,7 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) {
gfx::RectF expected_clip_rect(clip_rect);
expected_clip_rect.set_height(clip_rect.height() + overscroll_offset.y());
- EXPECT_EQ(clip_tree.Node(clip_tree.overscroll_node_id())->clip,
+ EXPECT_EQ(clip_tree.Node(viewport_property_ids.outer_clip)->clip,
expected_clip_rect);
}
@@ -279,7 +282,7 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
tree.Node(grand_child)->local = rotation_about_x;
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
property_trees.ResetCachedData();
gfx::Transform flattened_rotation_about_x = rotation_about_x;
@@ -306,7 +309,7 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
// Remove flattening at grand_child, and recompute transforms.
tree.Node(grand_child)->flattens_inherited_transform = false;
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
property_trees.GetToTarget(grand_child, effect_parent, &to_target);
EXPECT_TRANSFORM_EQ(rotation_about_x * rotation_about_x, to_target);
@@ -417,7 +420,7 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) {
tree.Node(grand_parent_id)->needs_local_transform_update = true;
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
transform.MakeIdentity();
tree.CombineTransformsBetween(child_id, grand_parent_id, &transform);
@@ -428,7 +431,7 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) {
tree.Node(grand_parent_id)->needs_local_transform_update = true;
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
transform.MakeIdentity();
tree.CombineTransformsBetween(child_id, grand_parent_id, &transform);
@@ -456,7 +459,7 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) {
tree.Node(grand_child)->flattens_inherited_transform = true;
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
gfx::Transform flattened_rotation_about_x = rotation_about_x;
flattened_rotation_about_x.FlattenTo2d();
@@ -511,7 +514,7 @@ TEST(PropertyTreeTest, SingularTransformSnapTest) {
child_node->local.Translate(1.3f, 1.3f);
tree.set_needs_update(true);
- draw_property_utils::ComputeTransforms(&tree);
+ draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds());
property_trees.ResetCachedData();
gfx::Transform from_target;
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index ce648e1d98c..6c879ed922d 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -101,9 +101,6 @@ class CC_EXPORT Proxy {
virtual void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) = 0;
- virtual void SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) = 0;
-
// Returns a percentage representing average throughput of last X seconds.
// Only implemenented for single threaded proxy.
virtual uint32_t GetAverageThroughput() const = 0;
diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h
index d8b8725949a..a1d9117c252 100644
--- a/chromium/cc/trees/proxy_common.h
+++ b/chromium/cc/trees/proxy_common.h
@@ -31,6 +31,7 @@ struct CC_EXPORT BeginMainFrameAndCommitState {
ActiveFrameSequenceTrackers active_sequence_trackers = 0;
bool evicted_ui_resources = false;
std::vector<uint32_t> finished_transition_request_sequence_ids;
+ uint64_t trace_id = 0;
};
} // namespace cc
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index d7a12d0a16f..e253b21d1ba 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -77,9 +77,9 @@ class ScopedCommitCompletionEvent {
}
private:
- CompletionEvent* const event_;
+ const raw_ptr<CompletionEvent> event_;
CommitTimestamps commit_timestamps_;
- base::SingleThreadTaskRunner* main_thread_task_runner_;
+ raw_ptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::WeakPtr<ProxyMain> proxy_main_weak_ptr_;
};
@@ -188,10 +188,34 @@ void ProxyImpl::InitializeLayerTreeFrameSinkOnImpl(
scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
}
-void ProxyImpl::SetDeferBeginMainFrameOnImpl(
- bool defer_begin_main_frame) const {
+bool ProxyImpl::ShouldDeferBeginMainFrame() const {
+ return main_wants_defer_begin_main_frame_ ||
+ impl_wants_defer_begin_main_frame_;
+}
+
+void ProxyImpl::SetDeferBeginMainFrameFromMain(bool defer_begin_main_frame) {
+ // This is the impl-side update of a main-thread request (that is, through
+ // ProxyMain::SetDeferMainFrameUpdate) to defer BeginMainFrame.
+ DCHECK(IsImplThread());
+ bool was_deferring = ShouldDeferBeginMainFrame();
+
+ main_wants_defer_begin_main_frame_ = defer_begin_main_frame;
+
+ bool should_defer = ShouldDeferBeginMainFrame();
+ if (was_deferring != should_defer)
+ scheduler_->SetDeferBeginMainFrame(ShouldDeferBeginMainFrame());
+}
+
+void ProxyImpl::SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) {
+ // This is a request from the impl thread to defer BeginMainFrame.
DCHECK(IsImplThread());
- scheduler_->SetDeferBeginMainFrame(defer_begin_main_frame);
+ bool was_deferring = ShouldDeferBeginMainFrame();
+
+ impl_wants_defer_begin_main_frame_ = defer_begin_main_frame;
+
+ bool should_defer = ShouldDeferBeginMainFrame();
+ if (was_deferring != should_defer)
+ scheduler_->SetDeferBeginMainFrame(ShouldDeferBeginMainFrame());
}
void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
@@ -201,7 +225,6 @@ void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
}
void ProxyImpl::SetNeedsCommitOnImpl() {
- DCHECK(IsImplThread());
SetNeedsCommitOnImplThread();
}
@@ -287,6 +310,14 @@ void ProxyImpl::FrameSinksToThrottleUpdated(
NOTREACHED();
}
+void ProxyImpl::ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) {
+ DCHECK(IsImplThread());
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&ProxyMain::ReportEventLatency,
+ proxy_main_weak_ptr_, std::move(latencies)));
+}
+
void ProxyImpl::NotifyReadyToCommitOnImpl(
CompletionEvent* completion_event,
std::unique_ptr<CommitState> commit_state,
@@ -295,7 +326,12 @@ void ProxyImpl::NotifyReadyToCommitOnImpl(
const viz::BeginFrameArgs& commit_args,
CommitTimestamps* commit_timestamps,
bool commit_timeout) {
- TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToCommitOnImpl");
+ {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.NotifyReadyToCommitOnImpl",
+ TRACE_ID_LOCAL(commit_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ }
DCHECK(!data_for_commit_.get());
DCHECK(IsImplThread());
DCHECK(base::FeatureList::IsEnabled(features::kNonBlockingCommit) ||
@@ -381,11 +417,22 @@ void ProxyImpl::OnCanDrawStateChanged(bool can_draw) {
}
void ProxyImpl::NotifyReadyToActivate() {
- TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToActivate");
+ if (host_impl_->sync_tree() &&
+ !scheduler_->pending_tree_is_ready_for_activation()) {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.NotifyReadyToActivate",
+ TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ }
DCHECK(IsImplThread());
scheduler_->NotifyReadyToActivate();
}
+bool ProxyImpl::IsReadyToActivate() {
+ DCHECK(IsImplThread());
+ return scheduler_->IsReadyToActivate();
+}
+
void ProxyImpl::NotifyReadyToDraw() {
TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToDraw");
DCHECK(IsImplThread());
@@ -458,11 +505,6 @@ void ProxyImpl::RenewTreePriority() {
bool user_interaction_in_progress =
non_scroll_interaction_in_progress || scroll_type_considered_interaction;
- if (host_impl_->ukm_manager()) {
- host_impl_->ukm_manager()->SetUserInteractionInProgress(
- user_interaction_in_progress);
- }
-
if (host_impl_->CurrentScrollCheckerboardsDueToNoRecording() &&
base::FeatureList::IsEnabled(
features::kPreferNewContentForCheckerboardedScrolls)) {
@@ -665,7 +707,20 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(
host_impl_->FrameSequenceTrackerActiveTypes();
begin_main_frame_state->evicted_ui_resources =
host_impl_->EvictedUIResourcesExist();
+ begin_main_frame_state->trace_id =
+ (0x1llu << 51) | // Signature bit chosen at random to avoid collisions
+ (args.frame_id.source_id << 32) |
+ (args.frame_id.sequence_number & 0xffffffff);
host_impl_->WillSendBeginMainFrame();
+ {
+ TRACE_EVENT_WITH_FLOW1(
+ "viz,benchmark", "Graphics.Pipeline", TRACE_ID_GLOBAL(args.trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN, "step", "SendBeginMainFrame");
+ TRACE_EVENT_WITH_FLOW0("viz,benchmark",
+ "MainFrame.SendBeginMainFrameOnImpl",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_OUT);
+ }
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
@@ -693,7 +748,12 @@ DrawResult ProxyImpl::ScheduledActionDrawForced() {
}
void ProxyImpl::ScheduledActionCommit() {
- TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionCommit");
+ {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.BeginCommit",
+ TRACE_ID_LOCAL(data_for_commit_->commit_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ }
DCHECK(IsImplThread());
DCHECK(base::FeatureList::IsEnabled(features::kNonBlockingCommit) ||
IsMainThreadBlocked());
@@ -707,8 +767,9 @@ void ProxyImpl::ScheduledActionCommit() {
allow_cross_thread_ref_count_access;
auto* commit_state = data_for_commit_->commit_state.get();
- auto* unsafe_state = data_for_commit_->unsafe_state;
- host_impl_->BeginCommit(commit_state->source_frame_number);
+ auto* unsafe_state = data_for_commit_->unsafe_state.get();
+ host_impl_->BeginCommit(commit_state->source_frame_number,
+ commit_state->trace_id);
host_impl_->FinishCommit(*commit_state, *unsafe_state);
base::TimeTicks finish_time = base::TimeTicks::Now();
if (data_for_commit_->commit_timestamps)
@@ -725,16 +786,30 @@ void ProxyImpl::ScheduledActionCommit() {
}
data_for_commit_.reset();
- scheduler_->DidCommit();
- // Delay this step until afer the main thread has been released as it's
- // often a good bit of work to update the tree and prepare the new frame.
- host_impl_->CommitComplete();
+}
+
+void ProxyImpl::ScheduledActionPostCommit() {
+ DCHECK(IsImplThread());
+ TRACE_EVENT_WITH_FLOW0("viz,benchmark", "MainFrame.CommitComplete",
+ TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ // This is run as a separate step from commit because it can be time-consuming
+ // and ought not delay sending the next BeginMainFrame.
+ host_impl_->CommitComplete();
+ // TODO(szager): This should be set at activation time. crbug.com/1323906
next_frame_is_newly_committed_frame_ = true;
}
void ProxyImpl::ScheduledActionActivateSyncTree() {
- TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionActivateSyncTree");
+ if (host_impl_->sync_tree() &&
+ host_impl_->sync_tree()->source_frame_number() !=
+ host_impl_->active_tree()->source_frame_number()) {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.Activate",
+ TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ }
DCHECK(IsImplThread());
host_impl_->ActivateSyncTree();
}
@@ -785,6 +860,10 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
DCHECK(IsImplThread());
DCHECK(host_impl_.get());
+ TRACE_EVENT_WITH_FLOW0("viz,benchmark", "MainFrame.Draw",
+ TRACE_ID_LOCAL(host_impl_->active_tree()->trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
base::AutoReset<bool> mark_inside(&inside_draw_, true);
// This method is called on a forced draw, regardless of whether we are able
@@ -887,11 +966,6 @@ void ProxyImpl::SetRenderFrameObserver(
host_impl_->SetRenderFrameObserver(std::move(observer));
}
-void ProxyImpl::SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) {
- host_impl_->SetEnableFrameRateThrottling(enable_frame_rate_throttling);
-}
-
ProxyImpl::DataForCommit::DataForCommit(
std::unique_ptr<ScopedCommitCompletionEvent> commit_completion_event,
std::unique_ptr<CommitState> commit_state,
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 19cd52164e5..53859c996e7 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -56,7 +56,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator);
void InitializePaintWorkletLayerPainterOnImpl(
std::unique_ptr<PaintWorkletLayerPainter> painter);
- void SetDeferBeginMainFrameOnImpl(bool defer_begin_main_frame) const;
+ void SetDeferBeginMainFrameFromMain(bool defer_begin_main_frame);
void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect);
void SetNeedsCommitOnImpl();
void SetTargetLocalSurfaceIdOnImpl(
@@ -81,7 +81,6 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
base::WritableSharedMemoryMapping ukm_smoothness_data);
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
- void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling);
void MainFrameWillHappenOnImplForTesting(CompletionEvent* completion,
bool* main_frame_will_happen);
@@ -97,6 +96,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void DidReceiveCompositorFrameAckOnImplThread() override;
void OnCanDrawStateChanged(bool can_draw) override;
void NotifyReadyToActivate() override;
+ bool IsReadyToActivate() override;
void NotifyReadyToDraw() override;
// Please call these 2 functions through
// LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsOneBeginImplFrame().
@@ -105,6 +105,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void SetNeedsPrepareTilesOnImplThread() override;
void SetNeedsCommitOnImplThread() override;
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override;
+ void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override;
bool IsInsideDraw() override;
void RenewTreePriority() override;
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
@@ -133,6 +134,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
bool IsInSynchronousComposite() const override;
void FrameSinksToThrottleUpdated(
const base::flat_set<viz::FrameSinkId>& id) override;
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) override;
// SchedulerClient implementation
bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
@@ -146,6 +149,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
DrawResult ScheduledActionDrawIfPossible() override;
DrawResult ScheduledActionDrawForced() override;
void ScheduledActionCommit() override;
+ void ScheduledActionPostCommit() override;
void ScheduledActionActivateSyncTree() override;
void ScheduledActionBeginLayerTreeFrameSinkCreation() override;
void ScheduledActionPrepareTiles() override;
@@ -162,6 +166,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
bool IsImplThread() const;
bool IsMainThreadBlocked() const;
base::SingleThreadTaskRunner* MainThreadTaskRunner();
+ bool ShouldDeferBeginMainFrame() const;
const int layer_tree_host_id_;
@@ -181,10 +186,10 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
// Set when the main thread is waiting on a commit to complete.
std::unique_ptr<ScopedCommitCompletionEvent> commit_completion_event;
std::unique_ptr<CommitState> commit_state;
- const ThreadUnsafeCommitState* unsafe_state;
+ raw_ptr<const ThreadUnsafeCommitState> unsafe_state;
// This is passed from the main thread so the impl thread can record
// timestamps at the beginning and end of commit.
- CommitTimestamps* commit_timestamps = nullptr;
+ raw_ptr<CommitTimestamps> commit_timestamps = nullptr;
};
std::unique_ptr<DataForCommit> data_for_commit_;
@@ -218,6 +223,10 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
// A weak pointer to ProxyMain that is invalidated when LayerTreeFrameSink is
// released.
base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_;
+
+ // Either thread can request deferring BeginMainFrame; keep track of both.
+ bool main_wants_defer_begin_main_frame_ = false;
+ bool impl_wants_defer_begin_main_frame_ = false;
};
} // namespace cc
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 0f36361559d..4bd1151680d 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -131,11 +131,19 @@ void ProxyMain::BeginMainFrame(
DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_);
DCHECK(!layer_tree_host_->in_commit());
+ {
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.BeginMainFrameOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ }
base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now();
+ const viz::BeginFrameArgs& frame_args =
+ begin_main_frame_state->begin_frame_args;
benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
benchmark_instrumentation::kDoBeginFrame,
- begin_main_frame_state->begin_frame_args.frame_id.sequence_number);
+ frame_args.frame_id.sequence_number);
// This needs to run unconditionally, so do it before any early-returns.
if (layer_tree_host_->scheduling_client())
@@ -156,6 +164,10 @@ void ProxyMain::BeginMainFrame(
if (!layer_tree_host_->IsVisible()) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_WITH_FLOW1(
+ "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN, "reason", "ABORTED_NOT_VISIBLE");
// In this case, since the commit is deferred to a later time, gathered
// events metrics are not discarded so that they can be reported if the
// commit happens in the future.
@@ -180,6 +192,11 @@ void ProxyMain::BeginMainFrame(
if (defer_main_frame_update_) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_WITH_FLOW1("viz,benchmark",
+ "MainFrame.BeginMainFrameAbortedOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN, "reason",
+ "ABORTED_DEFERRED_MAIN_FRAME_UPDATE");
// In this case, since the commit is deferred to a later time, gathered
// events metrics are not discarded so that they can be reported if the
// commit happens in the future.
@@ -243,12 +260,11 @@ void ProxyMain::BeginMainFrame(
// See LayerTreeHostClient::BeginMainFrame for more documentation on
// what this does.
- layer_tree_host_->BeginMainFrame(begin_main_frame_state->begin_frame_args);
+ layer_tree_host_->BeginMainFrame(frame_args);
// Updates cc animations on the main-thread. This is necessary in order
// to track animation states such that they are cleaned up properly.
- layer_tree_host_->AnimateLayers(
- begin_main_frame_state->begin_frame_args.frame_time);
+ layer_tree_host_->AnimateLayers(frame_args.frame_time);
// Recreates all UI resources if the compositor thread evicted UI resources
// because it became invisible or there was a lost context when the compositor
@@ -269,13 +285,17 @@ void ProxyMain::BeginMainFrame(
// When we don't need to produce a CompositorFrame, there's also no need to
// commit our updates. We still need to run layout and paint though, as it can
// have side effects on page loading behavior.
- skip_commit |= begin_main_frame_state->begin_frame_args.animate_only;
+ skip_commit |= frame_args.animate_only;
if (skip_commit) {
current_pipeline_stage_ = NO_PIPELINE_STAGE;
layer_tree_host_->DidBeginMainFrame();
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_WITH_FLOW1(
+ "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN, "reason", "ABORTED_DEFERRED_COMMIT");
layer_tree_host_->RecordEndOfFrameMetrics(
begin_main_frame_start_time,
begin_main_frame_state->active_sequence_trackers);
@@ -324,8 +344,7 @@ void ProxyMain::BeginMainFrame(
final_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
commit_trace_ = std::make_unique<devtools_instrumentation::ScopedCommitTrace>(
- layer_tree_host_->GetId(),
- begin_main_frame_state->begin_frame_args.frame_id.sequence_number);
+ layer_tree_host_->GetId(), frame_args.frame_id.sequence_number);
auto completion_event_ptr = std::make_unique<CompletionEvent>(
base::WaitableEvent::ResetPolicy::MANUAL);
@@ -336,6 +355,12 @@ void ProxyMain::BeginMainFrame(
std::unique_ptr<CommitState> commit_state = layer_tree_host_->WillCommit(
std::move(completion_event_ptr), has_updates);
DCHECK_EQ(has_updates, (bool)commit_state.get());
+ if (commit_state.get()) {
+ commit_state->trace_id =
+ (0x1llu << 52) | // Signature bit chosen at random to avoid collisions
+ (frame_args.frame_id.source_id << 32) |
+ (commit_state->source_frame_number & 0xffffffff);
+ }
current_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
if (!has_updates) {
@@ -344,6 +369,10 @@ void ProxyMain::BeginMainFrame(
layer_tree_host_->DidBeginMainFrame();
TRACE_EVENT_INSTANT0("cc,raf_investigation", "EarlyOut_NoUpdates",
TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_WITH_FLOW1(
+ "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN, "reason", "FINISHED_NO_UPDATES");
std::vector<std::unique_ptr<SwapPromise>> swap_promises =
layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises();
@@ -383,6 +412,15 @@ void ProxyMain::BeginMainFrame(
CommitTimestamps commit_timestamps;
bool blocking = !base::FeatureList::IsEnabled(features::kNonBlockingCommit);
{
+ TRACE_EVENT_WITH_FLOW0("viz,benchmark",
+ "MainFrame.NotifyReadyToCommitOnMain",
+ TRACE_ID_LOCAL(begin_main_frame_state->trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN);
+ TRACE_EVENT_WITH_FLOW0(
+ "viz,benchmark", "MainFrame.NotifyReadyToCommitOnMain",
+ TRACE_ID_LOCAL(commit_state->trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+ }
+ {
TRACE_EVENT0("cc,raf_investigation", "ProxyMain::BeginMainFrame::commit");
absl::optional<DebugScopedSetMainThreadBlocked> main_thread_blocked;
@@ -390,13 +428,13 @@ void ProxyMain::BeginMainFrame(
main_thread_blocked.emplace(task_runner_provider_);
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl,
- base::Unretained(proxy_impl_.get()),
- completion_event, std::move(commit_state),
- &unsafe_state, begin_main_frame_start_time,
- begin_main_frame_state->begin_frame_args,
- blocking ? &commit_timestamps : nullptr,
- commit_timeout));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl,
+ base::Unretained(proxy_impl_.get()), completion_event,
+ std::move(commit_state), &unsafe_state,
+ begin_main_frame_start_time, frame_args,
+ blocking ? &commit_timestamps : nullptr,
+ commit_timeout));
if (blocking)
layer_tree_host_->WaitForProtectedSequenceCompletion();
}
@@ -442,6 +480,11 @@ void ProxyMain::DidObserveFirstScrollDelay(
first_scroll_timestamp);
}
+void ProxyMain::ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) {
+ layer_tree_host_->ReportEventLatency(std::move(latencies));
+}
+
bool ProxyMain::IsStarted() const {
DCHECK(IsMainThread());
return started_;
@@ -542,7 +585,7 @@ void ProxyMain::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
// The impl thread needs to know that it should not issue BeginMainFrame.
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::SetDeferBeginMainFrameOnImpl,
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetDeferBeginMainFrameFromMain,
base::Unretained(proxy_impl_.get()),
defer_main_frame_update));
}
@@ -760,14 +803,6 @@ void ProxyMain::SetRenderFrameObserver(
base::Unretained(proxy_impl_.get()), std::move(observer)));
}
-void ProxyMain::SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) {
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::SetEnableFrameRateThrottling,
- base::Unretained(proxy_impl_.get()),
- enable_frame_rate_throttling));
-}
-
uint32_t ProxyMain::GetAverageThroughput() const {
NOTIMPLEMENTED();
return 0u;
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index 79c20cae77d..1f0be862d15 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
+#include "cc/metrics/event_latency_tracker.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/paint_holding_reason.h"
#include "cc/trees/proxy.h"
@@ -71,6 +72,8 @@ class CC_EXPORT ProxyMain : public Proxy {
void NotifyThroughputTrackerResults(CustomTrackerResults results);
void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp);
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies);
CommitPipelineStage max_requested_pipeline_stage() const {
return max_requested_pipeline_stage_;
@@ -117,7 +120,6 @@ class CC_EXPORT ProxyMain : public Proxy {
base::WritableSharedMemoryMapping ukm_smoothness_data) override;
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
- void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling) override;
uint32_t GetAverageThroughput() const override;
// Returns |true| if the request was actually sent, |false| if one was
diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc
index 9e9e03db514..51add834b40 100644
--- a/chromium/cc/trees/render_frame_metadata.cc
+++ b/chromium/cc/trees/render_frame_metadata.cc
@@ -36,6 +36,10 @@ bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
external_page_scale_factor == other.external_page_scale_factor &&
top_controls_height == other.top_controls_height &&
top_controls_shown_ratio == other.top_controls_shown_ratio &&
+ previous_surfaces_visual_update_duration ==
+ other.previous_surfaces_visual_update_duration &&
+ current_surface_visual_update_duration ==
+ other.current_surface_visual_update_duration &&
#if BUILDFLAG(IS_ANDROID)
bottom_controls_height == other.bottom_controls_height &&
bottom_controls_shown_ratio == other.bottom_controls_shown_ratio &&
diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h
index c83dd6b387c..0c0395e5eb5 100644
--- a/chromium/cc/trees/render_frame_metadata.h
+++ b/chromium/cc/trees/render_frame_metadata.h
@@ -5,6 +5,7 @@
#ifndef CC_TREES_RENDER_FRAME_METADATA_H_
#define CC_TREES_RENDER_FRAME_METADATA_H_
+#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/cc_export.h"
#include "components/viz/common/quads/selection.h"
@@ -114,6 +115,14 @@ class CC_EXPORT RenderFrameMetadata {
viz::VerticalScrollDirection new_vertical_scroll_direction =
viz::VerticalScrollDirection::kNull;
+ // The cumulative time spent performing visual updates for all
+ // `local_surface_id` before this one.
+ base::TimeDelta previous_surfaces_visual_update_duration;
+
+ // The cumulative time spent performing visual updates for the current
+ // `local_surface_id`.
+ base::TimeDelta current_surface_visual_update_duration;
+
#if BUILDFLAG(IS_ANDROID)
// Used to position Android bottom bar, whose position is computed by the
// renderer compositor.
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index c23b716f2da..0066ee64b58 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -230,39 +230,42 @@ void SingleThreadProxy::DoCommit(const viz::BeginFrameArgs& commit_args) {
layer_tree_host_->GetId(), commit_args.frame_id.sequence_number);
// Commit immediately.
- {
- DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
- DebugScopedSetImplThread impl(task_runner_provider_);
+ DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
+ DebugScopedSetImplThread impl(task_runner_provider_);
- host_impl_->BeginCommit(commit_state->source_frame_number);
+ host_impl_->BeginCommit(commit_state->source_frame_number,
+ commit_state->trace_id);
- host_impl_->FinishCommit(*commit_state, unsafe_state);
- commit_state.reset();
- completion_event->Signal();
+ host_impl_->FinishCommit(*commit_state, unsafe_state);
+ commit_state.reset();
+ completion_event->Signal();
- if (scheduler_on_impl_thread_)
- scheduler_on_impl_thread_->DidCommit();
+ {
+ DebugScopedSetMainThread main(task_runner_provider_);
+ IssueImageDecodeFinishedCallbacks();
+ }
+}
- {
- DebugScopedSetMainThread main(task_runner_provider_);
- IssueImageDecodeFinishedCallbacks();
- }
- host_impl_->CommitComplete();
+void SingleThreadProxy::DoPostCommit() {
+ TRACE_EVENT0("cc", "SingleThreadProxy::DoPostCommit");
+ DCHECK(task_runner_provider_->IsMainThread());
- std::vector<uint32_t> ids =
- host_impl_->TakeFinishedTransitionRequestSequenceIds();
- {
- DebugScopedSetMainThread main(task_runner_provider_);
- layer_tree_host_->NotifyTransitionRequestsFinished(ids);
- }
+ DebugScopedSetImplThread impl(task_runner_provider_);
+ host_impl_->CommitComplete();
- // Commit goes directly to the active tree, but we need to synchronously
- // "activate" the tree still during commit to satisfy any potential
- // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
- // might not be ready to draw, so DidActivateSyncTree must set
- // the flag to force the tree to not draw until textures are ready.
- NotifyReadyToActivate();
+ std::vector<uint32_t> ids =
+ host_impl_->TakeFinishedTransitionRequestSequenceIds();
+ {
+ DebugScopedSetMainThread main(task_runner_provider_);
+ layer_tree_host_->NotifyTransitionRequestsFinished(ids);
}
+
+ // Commit goes directly to the active tree, but we need to synchronously
+ // "activate" the tree still during commit to satisfy any potential
+ // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
+ // might not be ready to draw, so DidActivateSyncTree must set
+ // the flag to force the tree to not draw until textures are ready.
+ NotifyReadyToActivate();
}
void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() {
@@ -444,6 +447,13 @@ void SingleThreadProxy::NotifyReadyToActivate() {
scheduler_on_impl_thread_->NotifyReadyToActivate();
}
+bool SingleThreadProxy::IsReadyToActivate() {
+ DCHECK(!task_runner_provider_->HasImplThread() ||
+ task_runner_provider_->IsImplThread());
+ return scheduler_on_impl_thread_ &&
+ scheduler_on_impl_thread_->IsReadyToActivate();
+}
+
void SingleThreadProxy::NotifyReadyToDraw() {
DCHECK(!task_runner_provider_->HasImplThread() ||
task_runner_provider_->IsImplThread());
@@ -707,6 +717,7 @@ void SingleThreadProxy::CompositeImmediatelyForTest(
base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
if (layer_tree_frame_sink_lost_) {
+ auto sync = layer_tree_host_->ForceSyncCompositeForTest(); // IN-TEST
RequestNewLayerTreeFrameSink();
// RequestNewLayerTreeFrameSink could have synchronously created an output
// surface, so check again before returning.
@@ -741,6 +752,7 @@ void SingleThreadProxy::CompositeImmediatelyForTest(
commit_requested_ = false;
DoPainting(begin_frame_args);
DoCommit(begin_frame_args);
+ DoPostCommit();
DCHECK_EQ(
0u,
@@ -882,6 +894,14 @@ size_t SingleThreadProxy::CommitDurationSampleCountForTesting() const {
->CommitDurationSampleCountForTesting(); // IN-TEST
}
+void SingleThreadProxy::ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) {
+ DCHECK(!task_runner_provider_->HasImplThread() ||
+ task_runner_provider_->IsImplThread());
+ DebugScopedSetMainThread main(task_runner_provider_);
+ layer_tree_host_->ReportEventLatency(std::move(latencies));
+}
+
void SingleThreadProxy::SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) {
DCHECK(task_runner_provider_->IsMainThread());
@@ -889,11 +909,6 @@ void SingleThreadProxy::SetRenderFrameObserver(
host_impl_->SetRenderFrameObserver(std::move(observer));
}
-void SingleThreadProxy::SetEnableFrameRateThrottling(
- bool enable_frame_rate_throttling) {
- DCHECK(task_runner_provider_->IsMainThread());
-}
-
uint32_t SingleThreadProxy::GetAverageThroughput() const {
DebugScopedSetImplThread impl(task_runner_provider_);
return host_impl_->dropped_frame_counter()->GetAverageThroughput();
@@ -1114,6 +1129,14 @@ void SingleThreadProxy::ScheduledActionCommit() {
DoCommit(scheduler_on_impl_thread_->last_dispatched_begin_main_frame_args());
}
+void SingleThreadProxy::ScheduledActionPostCommit() {
+ // DebugScopedSetImplThread here is just a formality; all SchedulerClient
+ // methods should have it.
+ DebugScopedSetImplThread impl(task_runner_provider_);
+ DebugScopedSetMainThread main(task_runner_provider_);
+ DoPostCommit();
+}
+
void SingleThreadProxy::ScheduledActionActivateSyncTree() {
DebugScopedSetImplThread impl(task_runner_provider_);
host_impl_->ActivateSyncTree();
@@ -1130,6 +1153,7 @@ void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() {
ScheduleRequestNewLayerTreeFrameSink();
} else {
DebugScopedSetMainThread main(task_runner_provider_);
+ auto sync = layer_tree_host_->ForceSyncCompositeForTest(); // IN-TEST
RequestNewLayerTreeFrameSink();
}
}
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 76ed39ca284..fef5133be31 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -76,7 +76,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
base::WritableSharedMemoryMapping ukm_smoothness_data) override;
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
- void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling) override;
uint32_t GetAverageThroughput() const override;
void UpdateBrowserControlsState(BrowserControlsState constraints,
@@ -95,6 +94,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
DrawResult ScheduledActionDrawIfPossible() override;
DrawResult ScheduledActionDrawForced() override;
void ScheduledActionCommit() override;
+ void ScheduledActionPostCommit() override;
void ScheduledActionActivateSyncTree() override;
void ScheduledActionBeginLayerTreeFrameSinkCreation() override;
void ScheduledActionPrepareTiles() override;
@@ -112,12 +112,14 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void DidReceiveCompositorFrameAckOnImplThread() override;
void OnCanDrawStateChanged(bool can_draw) override;
void NotifyReadyToActivate() override;
+ bool IsReadyToActivate() override;
void NotifyReadyToDraw() override;
void SetNeedsRedrawOnImplThread() override;
void SetNeedsOneBeginImplFrameOnImplThread() override;
void SetNeedsPrepareTilesOnImplThread() override;
void SetNeedsCommitOnImplThread() override;
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override;
+ void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override {}
bool IsInsideDraw() override;
void RenewTreePriority() override;
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
@@ -145,6 +147,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
const base::flat_set<viz::FrameSinkId>& ids) override;
void ClearHistory() override;
size_t CommitDurationSampleCountForTesting() const override;
+ void ReportEventLatency(
+ std::vector<EventLatencyTracker::LatencyData> latencies) override;
void RequestNewLayerTreeFrameSink();
@@ -168,6 +172,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void DoBeginMainFrame(const viz::BeginFrameArgs& begin_frame_args);
void DoPainting(const viz::BeginFrameArgs& commit_args);
void DoCommit(const viz::BeginFrameArgs& commit_args);
+ void DoPostCommit();
DrawResult DoComposite(LayerTreeHostImpl::FrameData* frame);
void DoSwap();
void DidCommitAndDrawFrame();
diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h
index a60b371119c..184e1b74a96 100644
--- a/chromium/cc/trees/target_property.h
+++ b/chromium/cc/trees/target_property.h
@@ -14,6 +14,9 @@ namespace TargetProperty {
// Must be zero-based as this will be stored in a bitset.
enum Type {
TRANSFORM = 0,
+ SCALE,
+ ROTATE,
+ TRANSLATE,
OPACITY,
FILTER,
SCROLL_OFFSET,
diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h
index b6177e0a92e..e3e7ca9f0d7 100644
--- a/chromium/cc/trees/transform_node.h
+++ b/chromium/cc/trees/transform_node.h
@@ -112,7 +112,8 @@ struct CC_EXPORT TransformNode {
// visibility, not this transform one.
bool delegates_to_parent_for_backface : 1;
- // Set to true, if the compositing reason is will-change:transform.
+ // Set to true, if the compositing reason is will-change:transform, scale,
+ // rotate, or translate (for the CSS property that created this node).
bool will_change_transform : 1;
// Set to true, if the node or it's parent |will_change_transform| is true.
diff --git a/chromium/cc/trees/ukm_manager.cc b/chromium/cc/trees/ukm_manager.cc
index 2685122aaf0..6d8e8540aad 100644
--- a/chromium/cc/trees/ukm_manager.cc
+++ b/chromium/cc/trees/ukm_manager.cc
@@ -22,82 +22,12 @@ UkmManager::UkmManager(std::unique_ptr<ukm::UkmRecorder> recorder)
DCHECK(recorder_);
}
-UkmManager::~UkmManager() {
- RecordCheckerboardUkm();
- RecordRenderingUkm();
-}
+UkmManager::~UkmManager() = default;
void UkmManager::SetSourceId(ukm::SourceId source_id) {
- // If we accumulated any metrics, record them before resetting the source.
- RecordCheckerboardUkm();
- RecordRenderingUkm();
-
source_id_ = source_id;
}
-void UkmManager::SetUserInteractionInProgress(bool in_progress) {
- if (user_interaction_in_progress_ == in_progress)
- return;
-
- user_interaction_in_progress_ = in_progress;
- if (!user_interaction_in_progress_)
- RecordCheckerboardUkm();
-}
-
-void UkmManager::AddCheckerboardStatsForFrame(int64_t checkerboard_area,
- int64_t num_missing_tiles,
- int64_t total_visible_area) {
- DCHECK_GE(total_visible_area, checkerboard_area);
- if (source_id_ == ukm::kInvalidSourceId || !user_interaction_in_progress_)
- return;
-
- checkerboarded_content_area_ += checkerboard_area;
- num_missing_tiles_ += num_missing_tiles;
- total_visible_area_ += total_visible_area;
- num_of_frames_++;
-}
-
-void UkmManager::AddCheckerboardedImages(int num_of_checkerboarded_images) {
- if (user_interaction_in_progress_) {
- num_of_images_checkerboarded_during_interaction_ +=
- num_of_checkerboarded_images;
- }
- total_num_of_checkerboarded_images_ += num_of_checkerboarded_images;
-}
-
-void UkmManager::RecordCheckerboardUkm() {
- // Only make a recording if there was any visible area from PictureLayers,
- // which can be checkerboarded.
- if (num_of_frames_ > 0 && total_visible_area_ > 0) {
- DCHECK_NE(source_id_, ukm::kInvalidSourceId);
- ukm::builders::Compositor_UserInteraction(source_id_)
- .SetCheckerboardedContentArea(checkerboarded_content_area_ /
- num_of_frames_)
- .SetNumMissingTiles(num_missing_tiles_ / num_of_frames_)
- .SetCheckerboardedContentAreaRatio(
- (checkerboarded_content_area_ * 100) / total_visible_area_)
- .SetCheckerboardedImagesCount(
- num_of_images_checkerboarded_during_interaction_)
- .Record(recorder_.get());
- }
-
- checkerboarded_content_area_ = 0;
- num_missing_tiles_ = 0;
- num_of_frames_ = 0;
- total_visible_area_ = 0;
- num_of_images_checkerboarded_during_interaction_ = 0;
-}
-
-void UkmManager::RecordRenderingUkm() {
- if (source_id_ == ukm::kInvalidSourceId)
- return;
-
- ukm::builders::Compositor_Rendering(source_id_)
- .SetCheckerboardedImagesCount(total_num_of_checkerboarded_images_)
- .Record(recorder_.get());
- total_num_of_checkerboarded_images_ = 0;
-}
-
void UkmManager::RecordThroughputUKM(
FrameSequenceTrackerType tracker_type,
FrameInfo::SmoothEffectDrivingThread thread_type,
@@ -121,7 +51,11 @@ void UkmManager::RecordThroughputUKM(
CASE_FOR_MAIN_THREAD_TRACKER(CanvasAnimation);
CASE_FOR_MAIN_THREAD_TRACKER(JSAnimation);
#undef CASE_FOR_MAIN_THREAD_TRACKER
- default:
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
+ break;
+ case FrameSequenceTrackerType::kCustom:
+ case FrameSequenceTrackerType::kMaxType:
NOTREACHED();
break;
}
@@ -144,7 +78,13 @@ void UkmManager::RecordThroughputUKM(
CASE_FOR_COMPOSITOR_THREAD_TRACKER(Video);
CASE_FOR_COMPOSITOR_THREAD_TRACKER(WheelScroll);
#undef CASE_FOR_COMPOSITOR_THREAD_TRACKER
- default:
+ case FrameSequenceTrackerType::kCanvasAnimation:
+ case FrameSequenceTrackerType::kJSAnimation:
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
+ break;
+ case FrameSequenceTrackerType::kCustom:
+ case FrameSequenceTrackerType::kMaxType:
NOTREACHED();
break;
}
@@ -208,7 +148,7 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame);
CASE_FOR_STAGE(TotalLatency);
#undef CASE_FOR_STAGE
- default:
+ case StageType::kStageTypeCount:
NOTREACHED();
break;
}
@@ -227,6 +167,7 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_BLINK_BREAKDOWN(Animate);
CASE_FOR_BLINK_BREAKDOWN(StyleUpdate);
CASE_FOR_BLINK_BREAKDOWN(LayoutUpdate);
+ CASE_FOR_BLINK_BREAKDOWN(Accessibility);
CASE_FOR_BLINK_BREAKDOWN(Prepaint);
CASE_FOR_BLINK_BREAKDOWN(CompositingInputs);
CASE_FOR_BLINK_BREAKDOWN(Paint);
@@ -234,7 +175,7 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_BLINK_BREAKDOWN(UpdateLayers);
CASE_FOR_BLINK_BREAKDOWN(BeginMainSentToStarted);
#undef CASE_FOR_BLINK_BREAKDOWN
- default:
+ case CompositorFrameReporter::BlinkBreakdown::kBreakdownCount:
NOTREACHED();
break;
}
@@ -259,7 +200,7 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_VIZ_BREAKDOWN(BufferReadyToLatch);
CASE_FOR_VIZ_BREAKDOWN(LatchToSwapEnd);
#undef CASE_FOR_VIZ_BREAKDOWN
- default:
+ case CompositorFrameReporter::VizBreakdown::kBreakdownCount:
NOTREACHED();
break;
}
@@ -287,7 +228,11 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_TRACKER(CanvasAnimation);
CASE_FOR_TRACKER(JSAnimation);
#undef CASE_FOR_TRACKER
- default:
+ case FrameSequenceTrackerType::kSETCompositorAnimation:
+ case FrameSequenceTrackerType::kSETMainThreadAnimation:
+ break;
+ case FrameSequenceTrackerType::kCustom:
+ case FrameSequenceTrackerType::kMaxType:
NOTREACHED();
break;
}
@@ -397,15 +342,13 @@ void UkmManager::RecordEventLatencyUKM(
auto stage_it = std::find_if(
stage_history.begin(), stage_history.end(),
[dispatch_timestamp](const CompositorFrameReporter::StageData& stage) {
- return stage.start_time > dispatch_timestamp;
+ return stage.start_time >= dispatch_timestamp;
});
- // TODO(crbug.com/1079116): Ideally, at least the start time of
+ // TODO(crbug.com/1330903): Ideally, at least the start time of
// SubmitCompositorFrameToPresentationCompositorFrame stage should be
- // greater than the final event dispatch timestamp, but apparently, this is
- // not always the case (see crbug.com/1093698). For now, skip to the next
- // event in such cases. Hopefully, the work to reduce discrepancies between
- // the new EventLatency and the old Event.Latency metrics would fix this
- // issue. If not, we need to reconsider investigating this issue.
+ // greater than or equal to the final event dispatch timestamp, but
+ // apparently, this is not always the case (see crbug.com/1330903). Skip
+ // recording compositor stages for now until we investigate the issue.
if (stage_it == stage_history.end())
continue;
@@ -426,7 +369,8 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame,
SubmitCompositorFrame);
#undef CASE_FOR_STAGE
- default:
+ case StageType::kTotalLatency:
+ case StageType::kStageTypeCount:
NOTREACHED();
break;
}
@@ -447,7 +391,8 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame,
SubmitCompositorFrame);
#undef CASE_FOR_STAGE
- default:
+ case StageType::kTotalLatency:
+ case StageType::kStageTypeCount:
NOTREACHED();
break;
}
@@ -456,7 +401,6 @@ void UkmManager::RecordEventLatencyUKM(
NOTREACHED();
break;
}
-
for (; stage_it != stage_history.end(); ++stage_it) {
// Total latency is calculated since the event timestamp.
const base::TimeTicks start_time =
@@ -478,7 +422,7 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame);
CASE_FOR_STAGE(TotalLatency);
#undef CASE_FOR_STAGE
- default:
+ case StageType::kStageTypeCount:
NOTREACHED();
break;
}
@@ -497,6 +441,7 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_BLINK_BREAKDOWN(Animate);
CASE_FOR_BLINK_BREAKDOWN(StyleUpdate);
CASE_FOR_BLINK_BREAKDOWN(LayoutUpdate);
+ CASE_FOR_BLINK_BREAKDOWN(Accessibility);
CASE_FOR_BLINK_BREAKDOWN(Prepaint);
CASE_FOR_BLINK_BREAKDOWN(CompositingInputs);
CASE_FOR_BLINK_BREAKDOWN(Paint);
@@ -504,7 +449,7 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_BLINK_BREAKDOWN(UpdateLayers);
CASE_FOR_BLINK_BREAKDOWN(BeginMainSentToStarted);
#undef CASE_FOR_BLINK_BREAKDOWN
- default:
+ case CompositorFrameReporter::BlinkBreakdown::kBreakdownCount:
NOTREACHED();
break;
}
@@ -529,7 +474,7 @@ void UkmManager::RecordEventLatencyUKM(
CASE_FOR_VIZ_BREAKDOWN(BufferReadyToLatch);
CASE_FOR_VIZ_BREAKDOWN(LatchToSwapEnd);
#undef CASE_FOR_VIZ_BREAKDOWN
- default:
+ case CompositorFrameReporter::VizBreakdown::kBreakdownCount:
NOTREACHED();
break;
}
diff --git a/chromium/cc/trees/ukm_manager.h b/chromium/cc/trees/ukm_manager.h
index 1345e2482f1..1c0a157c036 100644
--- a/chromium/cc/trees/ukm_manager.h
+++ b/chromium/cc/trees/ukm_manager.h
@@ -38,15 +38,6 @@ class CC_EXPORT UkmManager {
void SetSourceId(ukm::SourceId source_id);
- // These metrics are recorded while a user interaction is in progress.
- void SetUserInteractionInProgress(bool in_progress);
- void AddCheckerboardStatsForFrame(int64_t checkerboard_area,
- int64_t num_missing_tiles,
- int64_t total_visible_area);
-
- // These metrics are recorded until the source URL changes.
- void AddCheckerboardedImages(int num_of_checkerboarded_images);
-
void RecordThroughputUKM(FrameSequenceTrackerType tracker_type,
FrameInfo::SmoothEffectDrivingThread thread_type,
int64_t throughput) const;
@@ -72,18 +63,6 @@ class CC_EXPORT UkmManager {
ukm::UkmRecorder* recorder_for_testing() { return recorder_.get(); }
private:
- void RecordCheckerboardUkm();
- void RecordRenderingUkm();
-
- bool user_interaction_in_progress_ = false;
- int64_t num_of_images_checkerboarded_during_interaction_ = 0;
- int64_t checkerboarded_content_area_ = 0;
- int64_t num_missing_tiles_ = 0;
- int64_t total_visible_area_ = 0;
- int64_t num_of_frames_ = 0;
-
- int total_num_of_checkerboarded_images_ = 0;
-
ukm::SourceId source_id_ = ukm::kInvalidSourceId;
std::unique_ptr<ukm::UkmRecorder> recorder_;
};
diff --git a/chromium/cc/trees/ukm_manager_unittest.cc b/chromium/cc/trees/ukm_manager_unittest.cc
index 2fa9afde6da..abb3a9bdbb5 100644
--- a/chromium/cc/trees/ukm_manager_unittest.cc
+++ b/chromium/cc/trees/ukm_manager_unittest.cc
@@ -25,15 +25,6 @@ namespace {
const char kTestUrl[] = "https://example.com/foo";
const int64_t kTestSourceId1 = 100;
-const int64_t kTestSourceId2 = 200;
-
-const char kUserInteraction[] = "Compositor.UserInteraction";
-const char kRendering[] = "Compositor.Rendering";
-
-const char kCheckerboardArea[] = "CheckerboardedContentArea";
-const char kCheckerboardAreaRatio[] = "CheckerboardedContentAreaRatio";
-const char kMissingTiles[] = "NumMissingTiles";
-const char kCheckerboardedImagesCount[] = "CheckerboardedImagesCount";
// Names of compositor/event latency UKM events.
const char kCompositorLatency[] = "Graphics.Smoothness.Latency";
@@ -244,64 +235,6 @@ class UkmManagerTest : public testing::Test {
base::SimpleTestTickClock test_tick_clock_;
};
-TEST_F(UkmManagerTest, Basic) {
- manager_->SetUserInteractionInProgress(true);
- manager_->AddCheckerboardStatsForFrame(5, 1, 10);
- manager_->AddCheckerboardStatsForFrame(15, 3, 30);
- manager_->AddCheckerboardedImages(6);
- manager_->SetUserInteractionInProgress(false);
-
- // We should see a single entry for the interaction above.
- const auto& entries = test_ukm_recorder_->GetEntriesByName(kUserInteraction);
- ukm::SourceId original_id = ukm::kInvalidSourceId;
- EXPECT_EQ(1u, entries.size());
- for (const auto* entry : entries) {
- original_id = entry->source_id;
- EXPECT_NE(ukm::kInvalidSourceId, entry->source_id);
- test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardArea, 10);
- test_ukm_recorder_->ExpectEntryMetric(entry, kMissingTiles, 2);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 50);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 6);
- }
- test_ukm_recorder_->Purge();
-
- // Try pushing some stats while no user interaction is happening. No entries
- // should be pushed.
- manager_->AddCheckerboardStatsForFrame(6, 1, 10);
- manager_->AddCheckerboardStatsForFrame(99, 3, 100);
- EXPECT_EQ(0u, test_ukm_recorder_->entries_count());
- manager_->SetUserInteractionInProgress(true);
- EXPECT_EQ(0u, test_ukm_recorder_->entries_count());
-
- // Record a few entries and change the source before the interaction ends. The
- // stats collected up till this point should be recorded before the source is
- // swapped.
- manager_->AddCheckerboardStatsForFrame(10, 1, 100);
- manager_->AddCheckerboardStatsForFrame(30, 5, 100);
-
- manager_->SetSourceId(kTestSourceId2);
-
- const auto& entries2 = test_ukm_recorder_->GetEntriesByName(kUserInteraction);
- EXPECT_EQ(1u, entries2.size());
- for (const auto* entry : entries2) {
- EXPECT_EQ(original_id, entry->source_id);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardArea, 20);
- test_ukm_recorder_->ExpectEntryMetric(entry, kMissingTiles, 3);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 20);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 0);
- }
-
- // An entry for rendering is emitted when the URL changes.
- const auto& entries_rendering =
- test_ukm_recorder_->GetEntriesByName(kRendering);
- EXPECT_EQ(1u, entries_rendering.size());
- for (const auto* entry : entries_rendering) {
- EXPECT_EQ(original_id, entry->source_id);
- test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 6);
- }
-}
-
class UkmManagerCompositorLatencyTest
: public UkmManagerTest,
public testing::WithParamInterface<