summaryrefslogtreecommitdiff
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 16:23:34 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:37:21 +0000
commit38a9a29f4f9436cace7f0e7abf9c586057df8a4e (patch)
treec4e8c458dc595bc0ddb435708fa2229edfd00bd4 /chromium/cc
parente684a3455bcc29a6e3e66a004e352dea4e1141e7 (diff)
downloadqtwebengine-chromium-38a9a29f4f9436cace7f0e7abf9c586057df8a4e.tar.gz
BASELINE: Update Chromium to 73.0.3683.37
Change-Id: I08c9af2948b645f671e5d933aca1f7a90ea372f2 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn16
-rw-r--r--chromium/cc/OWNERS40
-rw-r--r--chromium/cc/README.md4
-rw-r--r--chromium/cc/animation/animation_host.cc9
-rw-r--r--chromium/cc/animation/element_animations.cc69
-rw-r--r--chromium/cc/animation/element_animations.h11
-rw-r--r--chromium/cc/animation/keyframe_model.cc106
-rw-r--r--chromium/cc/animation/keyframe_model.h11
-rw-r--r--chromium/cc/animation/keyframe_model_unittest.cc183
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve.cc6
-rw-r--r--chromium/cc/animation/scroll_timeline.h11
-rw-r--r--chromium/cc/animation/transform_operations.cc115
-rw-r--r--chromium/cc/animation/transform_operations.h22
-rw-r--r--chromium/cc/animation/transform_operations_unittest.cc166
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc26
-rw-r--r--chromium/cc/base/delayed_unique_notifier.cc7
-rw-r--r--chromium/cc/base/delayed_unique_notifier.h4
-rw-r--r--chromium/cc/base/delayed_unique_notifier_unittest.cc52
-rw-r--r--chromium/cc/base/index_rect_unittest.cc8
-rw-r--r--chromium/cc/base/switches.cc4
-rw-r--r--chromium/cc/base/switches.h1
-rw-r--r--chromium/cc/base/unique_notifier.cc7
-rw-r--r--chromium/cc/base/unique_notifier.h4
-rw-r--r--chromium/cc/base/unique_notifier_unittest.cc6
-rw-r--r--chromium/cc/benchmarks/micro_benchmark_controller_unittest.cc14
-rw-r--r--chromium/cc/benchmarks/rasterize_and_record_benchmark.cc4
-rw-r--r--chromium/cc/benchmarks/unittest_only_benchmark.cc4
-rw-r--r--chromium/cc/input/layer_selection_bound.cc7
-rw-r--r--chromium/cc/input/layer_selection_bound.h2
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.cc4
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.h4
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason_unittest.cc2
-rw-r--r--chromium/cc/input/scroll_snap_data.cc58
-rw-r--r--chromium/cc/input/scroll_snap_data.h9
-rw-r--r--chromium/cc/input/scroll_snap_data_unittest.cc78
-rw-r--r--chromium/cc/input/scrollbar_animation_controller.cc4
-rw-r--r--chromium/cc/input/scrollbar_animation_controller.h4
-rw-r--r--chromium/cc/input/scrollbar_animation_controller_unittest.cc66
-rw-r--r--chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc6
-rw-r--r--chromium/cc/input/snap_selection_strategy.cc8
-rw-r--r--chromium/cc/input/snap_selection_strategy.h3
-rw-r--r--chromium/cc/layers/append_quads_data.h6
-rw-r--r--chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc1
-rw-r--r--chromium/cc/layers/heads_up_display_layer.cc6
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc62
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.h4
-rw-r--r--chromium/cc/layers/layer.cc95
-rw-r--r--chromium/cc/layers/layer.h77
-rw-r--r--chromium/cc/layers/layer_impl.cc62
-rw-r--r--chromium/cc/layers/layer_impl.h27
-rw-r--r--chromium/cc/layers/layer_impl_test_properties.h3
-rw-r--r--chromium/cc/layers/layer_impl_unittest.cc8
-rw-r--r--chromium/cc/layers/layer_unittest.cc61
-rw-r--r--chromium/cc/layers/nine_patch_layer_impl.cc2
-rw-r--r--chromium/cc/layers/nine_patch_layer_impl.h2
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.cc16
-rw-r--r--chromium/cc/layers/picture_layer.cc1
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc13
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc23
-rw-r--r--chromium/cc/layers/render_surface_impl.cc16
-rw-r--r--chromium/cc/layers/render_surface_impl.h1
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc43
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc3
-rw-r--r--chromium/cc/layers/texture_layer.cc6
-rw-r--r--chromium/cc/layers/texture_layer_impl_unittest.cc4
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc38
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl.cc3
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl.h2
-rw-r--r--chromium/cc/layers/video_layer_impl_unittest.cc6
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc30
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h7
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc316
-rw-r--r--chromium/cc/paint/BUILD.gn2
-rw-r--r--chromium/cc/paint/color_space_transfer_cache_entry.cc5
-rw-r--r--chromium/cc/paint/color_space_transfer_cache_entry.h2
-rw-r--r--chromium/cc/paint/discardable_image_map.cc26
-rw-r--r--chromium/cc/paint/discardable_image_map_unittest.cc14
-rw-r--r--chromium/cc/paint/display_item_list.cc10
-rw-r--r--chromium/cc/paint/display_item_list.h5
-rw-r--r--chromium/cc/paint/filter_operation.cc16
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc8
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.h4
-rw-r--r--chromium/cc/paint/oop_pixeltest.cc9
-rw-r--r--chromium/cc/paint/paint_cache.cc2
-rw-r--r--chromium/cc/paint/paint_canvas.h4
-rw-r--r--chromium/cc/paint/paint_flags.cc40
-rw-r--r--chromium/cc/paint/paint_flags.h85
-rw-r--r--chromium/cc/paint/paint_image.h44
-rw-r--r--chromium/cc/paint/paint_image_builder.cc7
-rw-r--r--chromium/cc/paint/paint_image_builder.h5
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc26
-rw-r--r--chromium/cc/paint/paint_op_buffer.h27
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc5
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.cc4
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.h3
-rw-r--r--chromium/cc/paint/paint_op_buffer_unittest.cc67
-rw-r--r--chromium/cc/paint/paint_op_helper_unittest.cc83
-rw-r--r--chromium/cc/paint/paint_op_reader.cc62
-rw-r--r--chromium/cc/paint/paint_op_reader.h1
-rw-r--r--chromium/cc/paint/paint_op_writer.cc3
-rw-r--r--chromium/cc/paint/paint_worklet_input.h26
-rw-r--r--chromium/cc/paint/paint_worklet_layer_painter.h22
-rw-r--r--chromium/cc/paint/raw_memory_transfer_cache_entry.cc9
-rw-r--r--chromium/cc/paint/raw_memory_transfer_cache_entry.h2
-rw-r--r--chromium/cc/paint/record_paint_canvas.cc8
-rw-r--r--chromium/cc/paint/record_paint_canvas.h4
-rw-r--r--chromium/cc/paint/skia_paint_canvas.cc9
-rw-r--r--chromium/cc/paint/skia_paint_canvas.h4
-rw-r--r--chromium/cc/paint/solid_color_analyzer.cc110
-rw-r--r--chromium/cc/paint/solid_color_analyzer_unittest.cc87
-rw-r--r--chromium/cc/paint/transfer_cache_entry.h2
-rw-r--r--chromium/cc/paint/transfer_cache_serialize_helper.cc2
-rw-r--r--chromium/cc/paint/transfer_cache_serialize_helper.h6
-rw-r--r--chromium/cc/paint/transfer_cache_unittest.cc2
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc2
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.h2
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc14
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.h2
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc18
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.h2
-rw-r--r--chromium/cc/raster/paint_worklet_image_provider.cc25
-rw-r--r--chromium/cc/raster/paint_worklet_image_provider.h32
-rw-r--r--chromium/cc/raster/raster_buffer_provider.h2
-rw-r--r--chromium/cc/raster/raster_buffer_provider_perftest.cc2
-rw-r--r--chromium/cc/raster/raster_buffer_provider_unittest.cc13
-rw-r--r--chromium/cc/raster/raster_source.cc14
-rw-r--r--chromium/cc/raster/raster_source.h11
-rw-r--r--chromium/cc/raster/raster_source_unittest.cc59
-rw-r--r--chromium/cc/raster/single_thread_task_graph_runner.cc2
-rw-r--r--chromium/cc/raster/staging_buffer_pool.cc6
-rw-r--r--chromium/cc/raster/staging_buffer_pool.h2
-rw-r--r--chromium/cc/raster/task.h3
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.cc2
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.h2
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.cc15
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc15
-rw-r--r--chromium/cc/tiles/checker_image_tracker.cc4
-rw-r--r--chromium/cc/tiles/checker_image_tracker_unittest.cc6
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.cc24
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.h12
-rw-r--r--chromium/cc/tiles/decoded_image_tracker_unittest.cc36
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc2
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc15
-rw-r--r--chromium/cc/tiles/image_controller.cc77
-rw-r--r--chromium/cc/tiles/image_controller.h39
-rw-r--r--chromium/cc/tiles/image_controller_unittest.cc171
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache.cc61
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache.h52
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache_unittest.cc104
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.cc3
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_unittest.cc67
-rw-r--r--chromium/cc/tiles/tile_manager.cc55
-rw-r--r--chromium/cc/tiles/tile_manager.h5
-rw-r--r--chromium/cc/tiles/tile_manager_perftest.cc9
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc71
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc63
-rw-r--r--chromium/cc/trees/effect_node.cc1
-rw-r--r--chromium/cc/trees/effect_node.h2
-rw-r--r--chromium/cc/trees/element_id.cc16
-rw-r--r--chromium/cc/trees/element_id.h8
-rw-r--r--chromium/cc/trees/image_animation_controller.cc2
-rw-r--r--chromium/cc/trees/image_animation_controller_unittest.cc8
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.cc5
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h17
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h4
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_unittest.cc1
-rw-r--r--chromium/cc/trees/layer_tree_host.cc222
-rw-r--r--chromium/cc/trees/layer_tree_host.h60
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h13
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_common.h12
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc236
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc246
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h42
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc331
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc5
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc33
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc7
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_single_thread_client.h6
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc140
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_proxy.cc21
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc51
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc54
-rw-r--r--chromium/cc/trees/layer_tree_impl.h18
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc244
-rw-r--r--chromium/cc/trees/layer_tree_mutator.cc29
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h8
-rw-r--r--chromium/cc/trees/layer_tree_painter.h26
-rw-r--r--chromium/cc/trees/layer_tree_settings.h4
-rw-r--r--chromium/cc/trees/mutator_host_client.h2
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc2
-rw-r--r--chromium/cc/trees/occlusion_unittest.cc5
-rw-r--r--chromium/cc/trees/property_tree.cc49
-rw-r--r--chromium/cc/trees/property_tree.h11
-rw-r--r--chromium/cc/trees/property_tree_builder.cc53
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc4
-rw-r--r--chromium/cc/trees/proxy.h4
-rw-r--r--chromium/cc/trees/proxy_common.h2
-rw-r--r--chromium/cc/trees/proxy_impl.cc28
-rw-r--r--chromium/cc/trees/proxy_impl.h6
-rw-r--r--chromium/cc/trees/proxy_main.cc16
-rw-r--r--chromium/cc/trees/proxy_main.h9
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc21
-rw-r--r--chromium/cc/trees/single_thread_proxy.h8
-rw-r--r--chromium/cc/trees/target_property.h9
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc49
-rw-r--r--chromium/cc/trees/tree_synchronizer_unittest.cc8
211 files changed, 4100 insertions, 2186 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index 1c7b04e7a28..a03bd1fa818 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -150,6 +150,8 @@ cc_component("cc") {
"raster/gpu_raster_buffer_provider.h",
"raster/one_copy_raster_buffer_provider.cc",
"raster/one_copy_raster_buffer_provider.h",
+ "raster/paint_worklet_image_provider.cc",
+ "raster/paint_worklet_image_provider.h",
"raster/playback_image_provider.cc",
"raster/playback_image_provider.h",
"raster/raster_buffer.cc",
@@ -225,6 +227,8 @@ cc_component("cc") {
"tiles/image_decode_cache_utils.h",
"tiles/mipmap_util.cc",
"tiles/mipmap_util.h",
+ "tiles/paint_worklet_image_cache.cc",
+ "tiles/paint_worklet_image_cache.h",
"tiles/picture_layer_tiling.cc",
"tiles/picture_layer_tiling.h",
"tiles/picture_layer_tiling_set.cc",
@@ -297,7 +301,6 @@ cc_component("cc") {
"trees/layer_tree_impl.h",
"trees/layer_tree_mutator.cc",
"trees/layer_tree_mutator.h",
- "trees/layer_tree_painter.h",
"trees/layer_tree_settings.cc",
"trees/layer_tree_settings.h",
"trees/managed_memory_policy.cc",
@@ -346,9 +349,6 @@ cc_component("cc") {
"trees/ukm_manager.h",
]
- # TODO(khushalsagar): Remove once crbug.com/683263 is fixed.
- configs = [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
public_deps = [
"//cc/base",
"//cc/paint",
@@ -496,6 +496,10 @@ cc_test_static_library("test_support") {
"test/test_occlusion_tracker.h",
"test/test_options_provider.cc",
"test/test_options_provider.h",
+ "test/test_paint_worklet_input.cc",
+ "test/test_paint_worklet_input.h",
+ "test/test_paint_worklet_layer_painter.cc",
+ "test/test_paint_worklet_layer_painter.h",
"test/test_skcanvas.cc",
"test/test_skcanvas.h",
"test/test_task_graph_runner.cc",
@@ -641,6 +645,7 @@ cc_test("cc_unittests") {
"tiles/gpu_image_decode_cache_unittest.cc",
"tiles/image_controller_unittest.cc",
"tiles/mipmap_util_unittest.cc",
+ "tiles/paint_worklet_image_cache_unittest.cc",
"tiles/picture_layer_tiling_set_unittest.cc",
"tiles/picture_layer_tiling_unittest.cc",
"tiles/software_image_decode_cache_unittest.cc",
@@ -711,9 +716,6 @@ cc_test("cc_unittests") {
cflags = [ "/wd4250" ]
}
- # TODO(khushalsagar): Remove once crbug.com/683263 is fixed.
- configs = [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
deps = [
":cc",
":test_support",
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index 10a074fa7f1..e12309d4c86 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -1,52 +1,37 @@
# For patches touching specific topics, try the topic-specific OWNERS at the
# bottom of the file. For patches that touch multiple areas or if you aren't
-# sure, try the more general OWNERS at the top.
+# sure, try the more general OWNERS at the bottom.
#
# Folks listed as unofficial can't do OWNERS approvals but are good people to
# ask for informal reviews.
+# layers
enne@chromium.org
danakj@chromium.org
-vmpstr@chromium.org
-
-# layers / quads / passes
-enne@chromium.org
-danakj@chromium.org
-
-# ubercompositor
-piman@chromium.org
-danakj@chromium.org
+pdr@chromium.org
# mac-specific
ccameron@chromium.org
# scheduling / begin frames
-brianderson@chromium.org
-skyostil@chromium.org
sunnyps@chromium.org
-# texture uploading
-brianderson@chromium.org
-reveman@chromium.org
-skyostil@chromium.org
-
# tiles, tile management, and raster work
-reveman@chromium.org
vmpstr@chromium.org
ericrk@chromium.org
+# texture uploading
+sunnyps@chromium.org
+
# math / geometry
flackr@chromium.org
-vollick@chromium.org
# property trees
-ajuma@chromium.org
chrishtr@chromium.org
-vollick@chromium.org
weiliangc@chromium.org
+pdr@chromium.org
# animation
-ajuma@chromium.org
flackr@chromium.org
smcgruer@chromium.org
@@ -56,17 +41,18 @@ khushalsagar@chromium.org
vmpstr@chromium.org
# surfaces
-fsamuel@chromium.org
+enne@chromium.org
kylechar@chromium.org
samans@chromium.org
# input, scrolling
bokan@chromium.org
-# we miss you
-# jamesr@chromium.org
-# nduca@chromium.org
-# mithro@mithis.com / tansell@chromium.org
+# general
+enne@chromium.org
+danakj@chromium.org
+vmpstr@chromium.org
+piman@chromium.org
# TEAM: graphics-dev@chromium.org
# COMPONENT: Internals>Compositing
diff --git a/chromium/cc/README.md b/chromium/cc/README.md
index d1b5218d69b..5b3669d1b8e 100644
--- a/chromium/cc/README.md
+++ b/chromium/cc/README.md
@@ -42,6 +42,10 @@ composited browser contents into a backbuffer or a bitmap, respectively.
Design documents for the graphics stack can be found at
[chromium-graphics](https://www.chromium.org/developers/design-documents/chromium-graphics).
+## Other Docs
+
+* [How cc Works](https://docs.google.com/document/d/1yjzOWrPfFGviEd1nru3yzqxSHETC-zsEBSt9C8SvV-Q/edit)
+
## Glossaries
### Active CompositorFrame
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index b78c578afd6..f5d610983c9 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -158,10 +158,17 @@ void AnimationHost::UnregisterKeyframeEffectForElement(
scoped_refptr<ElementAnimations> element_animations =
GetElementAnimationsForElementId(element_id);
DCHECK(element_animations);
+
+ // |ClearAffectedElementTypes| requires an ElementId map in order to update
+ // the property trees. Generating that map requires walking the keyframe
+ // effects, so we have to do it before removing this one.
+ PropertyToElementIdMap element_id_map =
+ element_animations->GetPropertyToElementIdMap();
+
element_animations->RemoveKeyframeEffect(keyframe_effect);
if (element_animations->IsEmpty()) {
- element_animations->ClearAffectedElementTypes();
+ element_animations->ClearAffectedElementTypes(element_id_map);
element_to_animations_map_.erase(element_animations->element_id());
element_animations->SetAnimationHost(nullptr);
}
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
index f5d216cd5ab..dda8db90061 100644
--- a/chromium/cc/animation/element_animations.cc
+++ b/chromium/cc/animation/element_animations.cc
@@ -31,7 +31,7 @@ namespace {
// tracking is done on the KeyframeModel - https://crbug.com/900241
ElementId CalculateTargetElementId(const ElementAnimations* element_animations,
const KeyframeModel* keyframe_model) {
- if (keyframe_model->element_id())
+ if (LIKELY(keyframe_model->element_id()))
return keyframe_model->element_id();
return element_animations->element_id();
}
@@ -84,7 +84,8 @@ TargetProperties ElementAnimations::GetPropertiesMaskForAnimationState() {
return properties;
}
-void ElementAnimations::ClearAffectedElementTypes() {
+void ElementAnimations::ClearAffectedElementTypes(
+ const PropertyToElementIdMap& element_id_map) {
DCHECK(animation_host_);
TargetProperties disable_properties = GetPropertiesMaskForAnimationState();
@@ -96,7 +97,7 @@ void ElementAnimations::ClearAffectedElementTypes() {
// mutator_host_client() to be null.
if (has_element_in_active_list() && animation_host()->mutator_host_client()) {
animation_host()->mutator_host_client()->ElementIsAnimatingChanged(
- element_id(), ElementListType::ACTIVE, disabled_state_mask,
+ element_id_map, ElementListType::ACTIVE, disabled_state_mask,
disabled_state);
}
set_has_element_in_active_list(false);
@@ -104,7 +105,7 @@ void ElementAnimations::ClearAffectedElementTypes() {
if (has_element_in_pending_list() &&
animation_host()->mutator_host_client()) {
animation_host()->mutator_host_client()->ElementIsAnimatingChanged(
- element_id(), ElementListType::PENDING, disabled_state_mask,
+ element_id_map, ElementListType::PENDING, disabled_state_mask,
disabled_state);
}
set_has_element_in_pending_list(false);
@@ -349,15 +350,17 @@ void ElementAnimations::UpdateClientAnimationState() {
DCHECK(pending_state_.IsValid());
DCHECK(active_state_.IsValid());
+ PropertyToElementIdMap element_id_map = GetPropertyToElementIdMap();
+
if (has_element_in_active_list() && prev_active != active_state_) {
PropertyAnimationState diff_active = prev_active ^ active_state_;
animation_host()->mutator_host_client()->ElementIsAnimatingChanged(
- element_id(), ElementListType::ACTIVE, diff_active, active_state_);
+ element_id_map, ElementListType::ACTIVE, diff_active, active_state_);
}
if (has_element_in_pending_list() && prev_pending != pending_state_) {
PropertyAnimationState diff_pending = prev_pending ^ pending_state_;
animation_host()->mutator_host_client()->ElementIsAnimatingChanged(
- element_id(), ElementListType::PENDING, diff_pending, pending_state_);
+ element_id_map, ElementListType::PENDING, diff_pending, pending_state_);
}
}
@@ -467,6 +470,60 @@ gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const {
return gfx::ScrollOffset();
}
+PropertyToElementIdMap ElementAnimations::GetPropertyToElementIdMap() const {
+ // As noted in the header documentation, this method assumes that each
+ // property type maps to at most one ElementId. This is not conceptually true
+ // for cc/animations, but it is true for the current clients:
+ //
+ // * ui/ does not set per-keyframe-model ElementIds, so this map will be
+ // each property type mapping to the same ElementId (i.e. element_id()).
+ //
+ // * blink guarantees that any two keyframe models that it creates which
+ // target the same property on the same target will have the same ElementId.
+ //
+ // In order to make this as little of a footgun as possible for future-us,
+ // this method DCHECKs that the assumption holds.
+
+ std::vector<PropertyToElementIdMap::value_type> entries;
+ for (int property_index = TargetProperty::FIRST_TARGET_PROPERTY;
+ property_index <= TargetProperty::LAST_TARGET_PROPERTY;
+ ++property_index) {
+ TargetProperty::Type property =
+ static_cast<TargetProperty::Type>(property_index);
+ ElementId element_id_for_property;
+ for (auto& keyframe_effect : keyframe_effects_list_) {
+ KeyframeModel* model = keyframe_effect.GetKeyframeModel(property);
+ if (model) {
+ // We deliberately use two branches here so that the DCHECK can
+ // differentiate between models with different element ids, and the case
+ // where some models don't have an element id.
+ // TODO(crbug.com/900241): All KeyframeModels should have an ElementId.
+ if (model->element_id()) {
+ DCHECK(!element_id_for_property ||
+ element_id_for_property == model->element_id())
+ << "Different KeyframeModels for the same target must have the "
+ << "same ElementId";
+ element_id_for_property = model->element_id();
+ } else {
+ // This DCHECK isn't perfect; you could have a case where one model
+ // has an ElementId and the other doesn't, but model->element_id() ==
+ // this->element_id() and so the DCHECK passes. That is unlikely
+ // enough that we don't bother guarding against it specifically.
+ DCHECK(!element_id_for_property ||
+ element_id_for_property == element_id())
+ << "Either all models should have an ElementId or none should";
+ element_id_for_property = element_id();
+ }
+ }
+ }
+
+ if (element_id_for_property)
+ entries.emplace_back(property, element_id_for_property);
+ }
+
+ return PropertyToElementIdMap(std::move(entries));
+}
+
bool ElementAnimations::KeyframeModelAffectsActiveElements(
KeyframeModel* keyframe_model) const {
// When we force a keyframe_model update due to a notification, we do not have
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
index 7c51dc7900f..629379a3d2f 100644
--- a/chromium/cc/animation/element_animations.h
+++ b/chromium/cc/animation/element_animations.h
@@ -55,7 +55,7 @@ class CC_ANIMATION_EXPORT ElementAnimations
void SetAnimationHost(AnimationHost* host);
void InitAffectedElementTypes();
- void ClearAffectedElementTypes();
+ void ClearAffectedElementTypes(const PropertyToElementIdMap& element_id_map);
void ElementRegistered(ElementId element_id, ElementListType list_type);
void ElementUnregistered(ElementId element_id, ElementListType list_type);
@@ -164,6 +164,15 @@ class CC_ANIMATION_EXPORT ElementAnimations
gfx::ScrollOffset ScrollOffsetForAnimation() const;
+ // Returns a map of target property to the ElementId for that property, for
+ // KeyframeEffects associated with this ElementAnimations.
+ //
+ // This method makes the assumption that a given target property doesn't map
+ // to more than one ElementId. While conceptually this isn't true for
+ // cc/animations, it is true for the two current clients (ui/ and blink) and
+ // this is required to let BGPT ship (see http://crbug.com/912574).
+ PropertyToElementIdMap GetPropertyToElementIdMap() const;
+
private:
friend class base::RefCounted<ElementAnimations>;
diff --git a/chromium/cc/animation/keyframe_model.cc b/chromium/cc/animation/keyframe_model.cc
index 13b2f100cd1..d4b89dda44b 100644
--- a/chromium/cc/animation/keyframe_model.cc
+++ b/chromium/cc/animation/keyframe_model.cc
@@ -7,6 +7,7 @@
#include <cmath>
#include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
@@ -25,7 +26,7 @@ static const char* const s_runStateNames[] = {"WAITING_FOR_TARGET_AVAILABILITY",
"ABORTED_BUT_NEEDS_COMPLETION"};
static_assert(static_cast<int>(cc::KeyframeModel::LAST_RUN_STATE) + 1 ==
- arraysize(s_runStateNames),
+ base::size(s_runStateNames),
"RunStateEnumSize should equal the number of elements in "
"s_runStateNames");
@@ -33,7 +34,7 @@ static const char* const s_curveTypeNames[] = {
"COLOR", "FLOAT", "TRANSFORM", "FILTER", "SCROLL_OFFSET", "SIZE"};
static_assert(static_cast<int>(cc::AnimationCurve::LAST_CURVE_TYPE) + 1 ==
- arraysize(s_curveTypeNames),
+ base::size(s_curveTypeNames),
"CurveType enum should equal the number of elements in "
"s_runStateNames");
@@ -142,14 +143,10 @@ void KeyframeModel::SetRunState(RunState run_state,
}
void KeyframeModel::Pause(base::TimeDelta pause_offset) {
- // Convert pause offset to monotonic time.
-
- // TODO(crbug.com/840364): This conversion is incorrect. pause_offset is
- // actually a local time so to convert it to monotonic time we should include
- // total_paused_duration_ but exclude time_offset. The current calculation is
- // is incorrect for animations that have start-delay or are paused and
- // unpaused multiple times.
- base::TimeTicks monotonic_time = pause_offset + start_time_ + time_offset_;
+ // Convert pause offset which is in local time to monotonic time.
+ // TODO(yigu): This should be scaled by playbackrate. http://crbug.com/912407
+ base::TimeTicks monotonic_time =
+ pause_offset + start_time_ + total_paused_duration_;
SetRunState(PAUSED, monotonic_time);
}
@@ -168,12 +165,78 @@ bool KeyframeModel::IsFinishedAt(base::TimeTicks monotonic_time) const {
(ConvertMonotonicTimeToLocalTime(monotonic_time) + time_offset_);
}
+KeyframeModel::Phase KeyframeModel::CalculatePhaseForTesting(
+ base::TimeDelta local_time) const {
+ return CalculatePhase(local_time);
+}
+
+KeyframeModel::Phase KeyframeModel::CalculatePhase(
+ base::TimeDelta local_time) const {
+ base::TimeDelta opposite_time_offset = time_offset_ == base::TimeDelta::Min()
+ ? base::TimeDelta::Max()
+ : -time_offset_;
+ base::TimeDelta before_active_boundary_time =
+ std::max(opposite_time_offset, base::TimeDelta());
+ if (local_time < before_active_boundary_time ||
+ (local_time == before_active_boundary_time && playback_rate_ < 0)) {
+ return KeyframeModel::Phase::BEFORE;
+ }
+ // Scaling the duration is against spec but needed to comply with the cc
+ // implementation. By spec (in blink) the playback rate is an Animation level
+ // concept but in cc it's per KeyframeModel. We grab the active time
+ // calculated here and later scale it with the playback rate in order to get a
+ // proper progress. Therefore we need to un-scale it here. This can be fixed
+ // once we scale the local time by playback rate. See
+ // https://crbug.com/912407.
+ base::TimeDelta active_duration =
+ curve_->Duration() * iterations_ / std::abs(playback_rate_);
+ // TODO(crbug.com/909794): By spec end time = max(start delay + duration +
+ // end delay, 0). The logic should be updated once "end delay" is supported.
+ base::TimeDelta active_after_boundary_time =
+ // Negative iterations_ represents "infinite iterations".
+ iterations_ >= 0
+ ? std::max(opposite_time_offset + active_duration, base::TimeDelta())
+ : base::TimeDelta::Max();
+ if (local_time > active_after_boundary_time ||
+ (local_time == active_after_boundary_time && playback_rate_ > 0)) {
+ return KeyframeModel::Phase::AFTER;
+ }
+ return KeyframeModel::Phase::ACTIVE;
+}
+
+base::Optional<base::TimeDelta> KeyframeModel::CalculateActiveTime(
+ base::TimeTicks monotonic_time) const {
+ base::TimeDelta local_time = ConvertMonotonicTimeToLocalTime(monotonic_time);
+ KeyframeModel::Phase phase = CalculatePhase(local_time);
+ DCHECK(playback_rate_);
+ switch (phase) {
+ case KeyframeModel::Phase::BEFORE:
+ if (fill_mode_ == FillMode::BACKWARDS || fill_mode_ == FillMode::BOTH)
+ return std::max(local_time + time_offset_, base::TimeDelta());
+ return base::nullopt;
+ case KeyframeModel::Phase::ACTIVE:
+ return local_time + time_offset_;
+ case KeyframeModel::Phase::AFTER:
+ if (fill_mode_ == FillMode::FORWARDS || fill_mode_ == FillMode::BOTH) {
+ DCHECK_GE(iterations_, 0);
+ base::TimeDelta active_duration =
+ curve_->Duration() * iterations_ / std::abs(playback_rate_);
+ return std::max(std::min(local_time + time_offset_, active_duration),
+ base::TimeDelta());
+ }
+ return base::nullopt;
+ default:
+ NOTREACHED();
+ return base::nullopt;
+ }
+}
+
bool KeyframeModel::InEffect(base::TimeTicks monotonic_time) const {
- return ConvertMonotonicTimeToLocalTime(monotonic_time) + time_offset_ >=
- base::TimeDelta() ||
- (fill_mode_ == FillMode::BOTH || fill_mode_ == FillMode::BACKWARDS);
+ return CalculateActiveTime(monotonic_time).has_value();
}
+// TODO(yigu): Local time should be scaled by playback rate by spec.
+// https://crbug.com/912407.
base::TimeDelta KeyframeModel::ConvertMonotonicTimeToLocalTime(
base::TimeTicks monotonic_time) const {
// When waiting on receiving a start time, then our global clock is 'stuck' at
@@ -183,24 +246,17 @@ base::TimeDelta KeyframeModel::ConvertMonotonicTimeToLocalTime(
return base::TimeDelta();
// If we're paused, time is 'stuck' at the pause time.
- base::TimeTicks time =
- (run_state_ == PAUSED) ? pause_time_ - time_offset_ : monotonic_time;
+ base::TimeTicks time = (run_state_ == PAUSED) ? pause_time_ : monotonic_time;
return time - start_time_ - total_paused_duration_;
}
base::TimeDelta KeyframeModel::TrimTimeToCurrentIteration(
base::TimeTicks monotonic_time) const {
- base::TimeDelta local_time = ConvertMonotonicTimeToLocalTime(monotonic_time);
- return TrimLocalTimeToCurrentIteration(local_time);
-}
-
-base::TimeDelta KeyframeModel::TrimLocalTimeToCurrentIteration(
- base::TimeDelta local_time) const {
- // Check for valid parameters
DCHECK(playback_rate_);
DCHECK_GE(iteration_start_, 0);
- base::TimeDelta active_time = local_time + time_offset_;
+ DCHECK(InEffect(monotonic_time));
+ base::TimeDelta active_time = CalculateActiveTime(monotonic_time).value();
base::TimeDelta start_offset = curve_->Duration() * iteration_start_;
// Return start offset if we are before the start of the keyframe model
@@ -218,10 +274,6 @@ base::TimeDelta KeyframeModel::TrimLocalTimeToCurrentIteration(
base::TimeDelta active_duration =
repeated_duration / std::abs(playback_rate_);
- // Check if we are past active duration
- if (iterations_ > 0 && active_time >= active_duration)
- active_time = active_duration;
-
// Calculate the scaled active time
base::TimeDelta scaled_active_time;
if (playback_rate_ < 0) {
diff --git a/chromium/cc/animation/keyframe_model.h b/chromium/cc/animation/keyframe_model.h
index 39557caa3e4..cdbb2d5c236 100644
--- a/chromium/cc/animation/keyframe_model.h
+++ b/chromium/cc/animation/keyframe_model.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/optional.h"
#include "base/time/time.h"
#include "cc/animation/animation_export.h"
#include "cc/trees/element_id.h"
@@ -55,6 +56,8 @@ class CC_ANIMATION_EXPORT KeyframeModel {
enum class FillMode { NONE, FORWARDS, BACKWARDS, BOTH, AUTO };
+ enum class Phase { BEFORE, ACTIVE, AFTER };
+
static std::unique_ptr<KeyframeModel> Create(
std::unique_ptr<AnimationCurve> curve,
int keyframe_model_id,
@@ -169,6 +172,9 @@ class CC_ANIMATION_EXPORT KeyframeModel {
}
bool affects_pending_elements() const { return affects_pending_elements_; }
+ KeyframeModel::Phase CalculatePhaseForTesting(
+ base::TimeDelta local_time) const;
+
private:
KeyframeModel(std::unique_ptr<AnimationCurve> curve,
int keyframe_model_id,
@@ -202,8 +208,9 @@ class CC_ANIMATION_EXPORT KeyframeModel {
base::TimeDelta ConvertMonotonicTimeToLocalTime(
base::TimeTicks monotonic_time) const;
- base::TimeDelta TrimLocalTimeToCurrentIteration(
- base::TimeDelta local_time) const;
+ KeyframeModel::Phase CalculatePhase(base::TimeDelta local_time) const;
+ base::Optional<base::TimeDelta> CalculateActiveTime(
+ base::TimeTicks monotonic_time) const;
std::unique_ptr<AnimationCurve> curve_;
diff --git a/chromium/cc/animation/keyframe_model_unittest.cc b/chromium/cc/animation/keyframe_model_unittest.cc
index 3757df9ee9f..5c853eb1246 100644
--- a/chromium/cc/animation/keyframe_model_unittest.cc
+++ b/chromium/cc/animation/keyframe_model_unittest.cc
@@ -350,7 +350,7 @@ TEST(KeyframeModelTest, TrimTimeStartTimeReverse) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
keyframe_model->set_start_time(TicksFromSecondsF(4));
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(0,
+ EXPECT_EQ(1.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
.InSecondsF());
EXPECT_EQ(1.0,
@@ -399,9 +399,6 @@ TEST(KeyframeModelTest, TrimTimeTimeOffsetReverse) {
EXPECT_EQ(0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1.0))
.InSecondsF());
- EXPECT_EQ(0,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1.0))
- .InSecondsF());
}
TEST(KeyframeModelTest, TrimTimeNegativeTimeOffset) {
@@ -427,7 +424,7 @@ TEST(KeyframeModelTest, TrimTimeNegativeTimeOffsetReverse) {
keyframe_model->set_time_offset(TimeDelta::FromMilliseconds(-4000));
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_EQ(0,
+ EXPECT_EQ(1.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
.InSecondsF());
EXPECT_EQ(1.0,
@@ -441,16 +438,67 @@ TEST(KeyframeModelTest, TrimTimeNegativeTimeOffsetReverse) {
.InSecondsF());
}
+TEST(KeyframeModelTest, TrimTimePauseBasic) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
+ // When paused, the time returned is always the pause time
+ EXPECT_EQ(0.5,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(-1))
+ .InSecondsF());
+ EXPECT_EQ(0.5,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.2))
+ .InSecondsF());
+ EXPECT_EQ(0.5,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(2))
+ .InSecondsF());
+}
+
+TEST(KeyframeModelTest, TrimTimePauseAffectedByDelay) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ // Pause time is in local time so delay should apply on top of it.
+ keyframe_model->set_time_offset(TimeDelta::FromSecondsD(-0.2));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
+ EXPECT_EQ(0.3,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.1))
+ .InSecondsF());
+
+ keyframe_model->set_time_offset(TimeDelta::FromSecondsD(0.2));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
+ EXPECT_EQ(0.7,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.1))
+ .InSecondsF());
+}
+
+TEST(KeyframeModelTest, TrimTimePauseNotAffectedByStartTime) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ // Pause time is in local time so start time should not affect it.
+ keyframe_model->set_start_time(TicksFromSecondsF(0.2));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
+ EXPECT_EQ(0.5,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.1))
+ .InSecondsF());
+
+ keyframe_model->set_start_time(TicksFromSecondsF(0.4));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
+ EXPECT_EQ(0.5,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.1))
+ .InSecondsF());
+}
+
TEST(KeyframeModelTest, TrimTimePauseResume) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
EXPECT_EQ(0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
.InSecondsF());
- EXPECT_EQ(0.5,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
+ EXPECT_EQ(0.4,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.4))
.InSecondsF());
- keyframe_model->SetRunState(KeyframeModel::PAUSED, TicksFromSecondsF(0.5));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.5));
EXPECT_EQ(
0.5, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
.InSecondsF());
@@ -462,6 +510,15 @@ TEST(KeyframeModelTest, TrimTimePauseResume) {
EXPECT_EQ(
1, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.5))
.InSecondsF());
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.6));
+ EXPECT_EQ(
+ 0.6, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(2000.0))
+ .InSecondsF());
+ keyframe_model->SetRunState(KeyframeModel::RUNNING,
+ TicksFromSecondsF(2000.0));
+ EXPECT_EQ(
+ 0.7, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(2000.1))
+ .InSecondsF());
}
TEST(KeyframeModelTest, TrimTimePauseResumeReverse) {
@@ -474,7 +531,7 @@ TEST(KeyframeModelTest, TrimTimePauseResumeReverse) {
EXPECT_EQ(0.5,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
.InSecondsF());
- keyframe_model->SetRunState(KeyframeModel::PAUSED, TicksFromSecondsF(0.25));
+ keyframe_model->Pause(base::TimeDelta::FromSecondsD(0.25));
EXPECT_EQ(0.75, keyframe_model
->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
.InSecondsF());
@@ -739,11 +796,12 @@ TEST(KeyframeModelTest, TrimTimePlaybackFast) {
TEST(KeyframeModelTest, TrimTimePlaybackNormalReverse) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1, 2, -1));
- EXPECT_EQ(0,
+ EXPECT_EQ(2.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
.InSecondsF());
- EXPECT_EQ(2, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
- .InSecondsF());
+ EXPECT_EQ(2.0,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
+ .InSecondsF());
EXPECT_EQ(1.5,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
.InSecondsF());
@@ -764,11 +822,12 @@ TEST(KeyframeModelTest, TrimTimePlaybackNormalReverse) {
TEST(KeyframeModelTest, TrimTimePlaybackSlowReverse) {
std::unique_ptr<KeyframeModel> keyframe_model(
CreateKeyframeModel(1, 2, -0.5));
- EXPECT_EQ(0,
+ EXPECT_EQ(2.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
.InSecondsF());
- EXPECT_EQ(2, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
- .InSecondsF());
+ EXPECT_EQ(2.0,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
+ .InSecondsF());
EXPECT_EQ(1.75,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
.InSecondsF());
@@ -799,11 +858,12 @@ TEST(KeyframeModelTest, TrimTimePlaybackSlowReverse) {
TEST(KeyframeModelTest, TrimTimePlaybackFastReverse) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1, 2, -2));
- EXPECT_EQ(0,
+ EXPECT_EQ(2.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
.InSecondsF());
- EXPECT_EQ(2, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
- .InSecondsF());
+ EXPECT_EQ(2.0,
+ keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0))
+ .InSecondsF());
EXPECT_EQ(1.5,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
.InSecondsF());
@@ -927,7 +987,7 @@ TEST(KeyframeModelTest, TrimTimeAlternateTwoIterationsPlaybackFast) {
TEST(KeyframeModelTest, TrimTimeAlternateTwoIterationsPlaybackFastReverse) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(2, 2, 2));
keyframe_model->set_direction(KeyframeModel::Direction::ALTERNATE_REVERSE);
- EXPECT_EQ(0.0,
+ EXPECT_EQ(2.0,
keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
.InSecondsF());
EXPECT_EQ(2.0,
@@ -1193,9 +1253,12 @@ TEST(KeyframeModelTest,
TEST(KeyframeModelTest, InEffectFillMode) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ // Effect before start is not InEffect
EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ // Effect at start is InEffect
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
- EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+ // Effect at end is not InEffect
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::FORWARDS);
EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
@@ -1205,7 +1268,7 @@ TEST(KeyframeModelTest, InEffectFillMode) {
keyframe_model->set_fill_mode(KeyframeModel::FillMode::BACKWARDS);
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
- EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::BOTH);
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
@@ -1213,27 +1276,101 @@ TEST(KeyframeModelTest, InEffectFillMode) {
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
}
-TEST(KeyframeModelTest, InEffectFillModePlayback) {
+TEST(KeyframeModelTest, InEffectFillModeNoneWithNegativePlaybackRate) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1, 1, -1));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
- EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::FORWARDS);
EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::BACKWARDS);
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::BOTH);
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+}
+
+TEST(KeyframeModelTest, InEffectFillModeWithIterations) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(2, 1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::FORWARDS);
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::BACKWARDS);
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::BOTH);
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+}
+
+TEST(KeyframeModelTest, InEffectFillModeWithInfiniteIterations) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(-1, 1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::FORWARDS);
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::BACKWARDS);
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
keyframe_model->set_fill_mode(KeyframeModel::FillMode::BOTH);
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+}
+
+TEST(KeyframeModelTest, InEffectReverseWithIterations) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(2, 1));
+ keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
+ // KeyframeModel::direction_ doesn't affect InEffect.
+ keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(-1.0)));
+ EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(keyframe_model->InEffect(TicksFromSecondsF(1.0)));
+ EXPECT_FALSE(keyframe_model->InEffect(TicksFromSecondsF(2.0)));
+}
+
+// CalculatePhase uses -time_offset_ which may cause integer overflow when
+// time_offset_ is set to min(). This test makes sure that the code handles it
+// correctly. See https://crbug.com/921454.
+TEST(KeyframeModelTest, CalculatePhaseWithMinTimeOffset) {
+ std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
+ keyframe_model->set_time_offset(
+ TimeDelta::FromMilliseconds(std::numeric_limits<int64_t>::min()));
+
+ // Setting the time_offset_ to min implies that the effect has a max start
+ // delay and any local time will fall into the BEFORE phase.
+ EXPECT_EQ(
+ keyframe_model->CalculatePhaseForTesting(TimeDelta::FromSecondsD(1.0)),
+ KeyframeModel::Phase::BEFORE);
}
TEST(KeyframeModelTest, ToString) {
diff --git a/chromium/cc/animation/scroll_offset_animation_curve.cc b/chromium/cc/animation/scroll_offset_animation_curve.cc
index 39d75dc22ce..fe61dc63e15 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve.cc
+++ b/chromium/cc/animation/scroll_offset_animation_curve.cc
@@ -18,6 +18,9 @@ using DurationBehavior = cc::ScrollOffsetAnimationCurve::DurationBehavior;
const double kConstantDuration = 9.0;
const double kDurationDivisor = 60.0;
+// 3 seconds limit for long-distance programmatic scrolls
+const double kDeltaBasedMaxDuration = 180.0;
+
const double kInverseDeltaRampStartPx = 120.0;
const double kInverseDeltaRampEndPx = 480.0;
const double kInverseDeltaMinDuration = 6.0;
@@ -83,7 +86,8 @@ base::TimeDelta ScrollOffsetAnimationCurve::SegmentDuration(
duration = kConstantDuration;
break;
case DurationBehavior::DELTA_BASED:
- duration = std::sqrt(std::abs(MaximumDimension(delta)));
+ duration = std::min(double(std::sqrt(std::abs(MaximumDimension(delta)))),
+ kDeltaBasedMaxDuration);
break;
case DurationBehavior::INVERSE_DELTA:
duration = std::min(
diff --git a/chromium/cc/animation/scroll_timeline.h b/chromium/cc/animation/scroll_timeline.h
index c1a1dc34d76..0563ab97e6a 100644
--- a/chromium/cc/animation/scroll_timeline.h
+++ b/chromium/cc/animation/scroll_timeline.h
@@ -53,6 +53,17 @@ class CC_ANIMATION_EXPORT ScrollTimeline {
void PromoteScrollTimelinePendingToActive();
+ base::Optional<ElementId> GetActiveIdForTest() const { return active_id_; }
+ base::Optional<ElementId> GetPendingIdForTest() const { return pending_id_; }
+ ScrollDirection GetDirectionForTest() const { return direction_; }
+ base::Optional<double> GetStartScrollOffsetForTest() const {
+ return start_scroll_offset_;
+ }
+ base::Optional<double> GetEndScrollOffsetForTest() const {
+ return end_scroll_offset_;
+ }
+ double GetTimeRangeForTest() const { return time_range_; }
+
private:
// The scroller which this ScrollTimeline is based on. The same underlying
// scroll source may have different ids in the pending and active tree (see
diff --git a/chromium/cc/animation/transform_operations.cc b/chromium/cc/animation/transform_operations.cc
index 9b456185030..56061923ea2 100644
--- a/chromium/cc/animation/transform_operations.cc
+++ b/chromium/cc/animation/transform_operations.cc
@@ -17,17 +17,10 @@
namespace cc {
-TransformOperations::TransformOperations()
- : decomposed_transform_dirty_(true) {
-}
+TransformOperations::TransformOperations() {}
TransformOperations::TransformOperations(const TransformOperations& other) {
operations_ = other.operations_;
- decomposed_transform_dirty_ = other.decomposed_transform_dirty_;
- if (!decomposed_transform_dirty_) {
- decomposed_transform_.reset(
- new gfx::DecomposedTransform(*other.decomposed_transform_.get()));
- }
}
TransformOperations::~TransformOperations() = default;
@@ -35,21 +28,23 @@ TransformOperations::~TransformOperations() = default;
TransformOperations& TransformOperations::operator=(
const TransformOperations& other) {
operations_ = other.operations_;
- decomposed_transform_dirty_ = other.decomposed_transform_dirty_;
- if (!decomposed_transform_dirty_) {
- decomposed_transform_.reset(
- new gfx::DecomposedTransform(*other.decomposed_transform_.get()));
- }
return *this;
}
gfx::Transform TransformOperations::Apply() const {
+ return ApplyRemaining(0);
+}
+
+gfx::Transform TransformOperations::ApplyRemaining(size_t start) const {
gfx::Transform to_return;
- for (auto& operation : operations_)
- to_return.PreconcatTransform(operation.matrix);
+ for (size_t i = start; i < operations_.size(); i++) {
+ to_return.PreconcatTransform(operations_[i].matrix);
+ }
return to_return;
}
+// TODO(crbug.com/914397): Consolidate blink and cc implementations of transform
+// interpolation.
TransformOperations TransformOperations::Blend(const TransformOperations& from,
SkMScalar progress) const {
TransformOperations to_return;
@@ -197,6 +192,23 @@ bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
return true;
}
+size_t TransformOperations::MatchingPrefixLength(
+ const TransformOperations& other) const {
+ size_t num_operations =
+ std::min(operations_.size(), other.operations_.size());
+ for (size_t i = 0; i < num_operations; ++i) {
+ if (operations_[i].type != other.operations_[i].type) {
+ // Remaining operations in each operations list require matrix/matrix3d
+ // interpolation.
+ return i;
+ }
+ }
+ // If the operations match to the length of the shorter list, then pad its
+ // length with the matching identity operations.
+ // https://drafts.csswg.org/css-transforms/#transform-function-lists
+ return std::max(operations_.size(), other.operations_.size());
+}
+
bool TransformOperations::CanBlendWith(
const TransformOperations& other) const {
TransformOperations dummy;
@@ -213,7 +225,7 @@ void TransformOperations::AppendTranslate(SkMScalar x,
to_add.translate.y = y;
to_add.translate.z = z;
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendRotate(SkMScalar x,
@@ -228,7 +240,7 @@ void TransformOperations::AppendRotate(SkMScalar x,
to_add.rotate.angle = degrees;
to_add.Bake();
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendScale(SkMScalar x, SkMScalar y, SkMScalar z) {
@@ -239,7 +251,7 @@ void TransformOperations::AppendScale(SkMScalar x, SkMScalar y, SkMScalar z) {
to_add.scale.z = z;
to_add.Bake();
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendSkew(SkMScalar x, SkMScalar y) {
@@ -249,7 +261,7 @@ void TransformOperations::AppendSkew(SkMScalar x, SkMScalar y) {
to_add.skew.y = y;
to_add.Bake();
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendPerspective(SkMScalar depth) {
@@ -258,7 +270,7 @@ void TransformOperations::AppendPerspective(SkMScalar depth) {
to_add.perspective_depth = depth;
to_add.Bake();
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendMatrix(const gfx::Transform& matrix) {
@@ -266,7 +278,7 @@ void TransformOperations::AppendMatrix(const gfx::Transform& matrix) {
to_add.matrix = matrix;
to_add.type = TransformOperation::TRANSFORM_OPERATION_MATRIX;
operations_.push_back(to_add);
- decomposed_transform_dirty_ = true;
+ decomposed_transforms_.clear();
}
void TransformOperations::AppendIdentity() {
@@ -275,6 +287,7 @@ void TransformOperations::AppendIdentity() {
void TransformOperations::Append(const TransformOperation& operation) {
operations_.push_back(operation);
+ decomposed_transforms_.clear();
}
bool TransformOperations::IsIdentity() const {
@@ -304,42 +317,44 @@ bool TransformOperations::BlendInternal(const TransformOperations& from,
if (from_identity && to_identity)
return true;
- if (MatchesTypes(from)) {
- size_t num_operations =
- std::max(from_identity ? 0 : from.operations_.size(),
- to_identity ? 0 : operations_.size());
- for (size_t i = 0; i < num_operations; ++i) {
- TransformOperation blended;
- if (!TransformOperation::BlendTransformOperations(
- from_identity ? nullptr : &from.operations_[i],
- to_identity ? nullptr : &operations_[i], progress, &blended)) {
- return false;
- }
- result->Append(blended);
+ size_t matching_prefix_length = MatchingPrefixLength(from);
+ size_t from_size = from_identity ? 0 : from.operations_.size();
+ size_t to_size = to_identity ? 0 : operations_.size();
+ size_t num_operations = std::max(from_size, to_size);
+
+ for (size_t i = 0; i < matching_prefix_length; ++i) {
+ TransformOperation blended;
+ if (!TransformOperation::BlendTransformOperations(
+ i >= from_size ? nullptr : &from.operations_[i],
+ i >= to_size ? nullptr : &operations_[i], progress, &blended)) {
+ return false;
}
- return true;
+ result->Append(blended);
}
- if (!ComputeDecomposedTransform() || !from.ComputeDecomposedTransform())
- return false;
-
- gfx::DecomposedTransform to_return;
- to_return = gfx::BlendDecomposedTransforms(*decomposed_transform_.get(),
- *from.decomposed_transform_.get(),
- progress);
-
- result->AppendMatrix(ComposeTransform(to_return));
+ if (matching_prefix_length < num_operations) {
+ if (!ComputeDecomposedTransform(matching_prefix_length) ||
+ !from.ComputeDecomposedTransform(matching_prefix_length)) {
+ return false;
+ }
+ gfx::DecomposedTransform matrix_transform = gfx::BlendDecomposedTransforms(
+ *decomposed_transforms_[matching_prefix_length].get(),
+ *from.decomposed_transforms_[matching_prefix_length].get(), progress);
+ result->AppendMatrix(ComposeTransform(matrix_transform));
+ }
return true;
}
-bool TransformOperations::ComputeDecomposedTransform() const {
- if (decomposed_transform_dirty_) {
- if (!decomposed_transform_)
- decomposed_transform_.reset(new gfx::DecomposedTransform());
- gfx::Transform transform = Apply();
- if (!gfx::DecomposeTransform(decomposed_transform_.get(), transform))
+bool TransformOperations::ComputeDecomposedTransform(
+ size_t start_offset) const {
+ auto it = decomposed_transforms_.find(start_offset);
+ if (it == decomposed_transforms_.end()) {
+ std::unique_ptr<gfx::DecomposedTransform> decomposed_transform =
+ std::make_unique<gfx::DecomposedTransform>();
+ gfx::Transform transform = ApplyRemaining(start_offset);
+ if (!gfx::DecomposeTransform(decomposed_transform.get(), transform))
return false;
- decomposed_transform_dirty_ = false;
+ decomposed_transforms_[start_offset] = std::move(decomposed_transform);
}
return true;
}
diff --git a/chromium/cc/animation/transform_operations.h b/chromium/cc/animation/transform_operations.h
index 081da5932c9..4a6706d75d6 100644
--- a/chromium/cc/animation/transform_operations.h
+++ b/chromium/cc/animation/transform_operations.h
@@ -6,8 +6,10 @@
#define CC_ANIMATION_TRANSFORM_OPERATIONS_H_
#include <memory>
+#include <unordered_map>
#include <vector>
+#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "cc/animation/animation_export.h"
@@ -41,6 +43,10 @@ class CC_ANIMATION_EXPORT TransformOperations {
// Returns a transformation matrix representing these transform operations.
gfx::Transform Apply() const;
+ // Returns a transformation matrix representing the set of transform
+ // operations from index |start| to the end of the list.
+ gfx::Transform ApplyRemaining(size_t start) const;
+
// Given another set of transform operations and a progress in the range
// [0, 1], returns a transformation matrix representing the intermediate
// value. If this->MatchesTypes(from), then each of the operations are
@@ -74,6 +80,12 @@ class CC_ANIMATION_EXPORT TransformOperations {
// as other and its descendants.
bool MatchesTypes(const TransformOperations& other) const;
+ // Returns the number of matching transform operations at the start of the
+ // transform lists. If one list is shorter but pairwise compatible, it will be
+ // extended with matching identity operators per spec
+ // (https://drafts.csswg.org/css-transforms/#interpolation-of-transforms).
+ size_t MatchingPrefixLength(const TransformOperations& other) const;
+
// Returns true if these operations can be blended. It will only return
// false if we must resort to matrix interpolation, and matrix interpolation
// fails (this can happen if either matrix cannot be decomposed).
@@ -109,17 +121,19 @@ class CC_ANIMATION_EXPORT TransformOperations {
SkMScalar tolerance) const;
private:
+ FRIEND_TEST_ALL_PREFIXES(TransformOperationsTest, TestDecompositionCache);
+
bool BlendInternal(const TransformOperations& from,
SkMScalar progress,
TransformOperations* result) const;
std::vector<TransformOperation> operations_;
- bool ComputeDecomposedTransform() const;
+ bool ComputeDecomposedTransform(size_t start_offset) const;
- // For efficiency, we cache the decomposed transform.
- mutable std::unique_ptr<gfx::DecomposedTransform> decomposed_transform_;
- mutable bool decomposed_transform_dirty_;
+ // For efficiency, we cache the decomposed transforms.
+ mutable std::unordered_map<size_t, std::unique_ptr<gfx::DecomposedTransform>>
+ decomposed_transforms_;
};
} // namespace cc
diff --git a/chromium/cc/animation/transform_operations_unittest.cc b/chromium/cc/animation/transform_operations_unittest.cc
index ac7e5289d9f..91a6d6c1931 100644
--- a/chromium/cc/animation/transform_operations_unittest.cc
+++ b/chromium/cc/animation/transform_operations_unittest.cc
@@ -9,6 +9,7 @@
#include <limits>
#include <vector>
+#include "base/stl_util.h"
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/animation/tween.h"
@@ -85,7 +86,7 @@ TEST(TransformOperationTest, TransformTypesAreUnique) {
}
}
-TEST(TransformOperationTest, MatchTypesSameLength) {
+TEST(TransformOperationTest, MatchingPrefixSameLength) {
TransformOperations translates;
translates.AppendTranslate(1, 0, 0);
translates.AppendTranslate(1, 0, 0);
@@ -101,14 +102,20 @@ TEST(TransformOperationTest, MatchTypesSameLength) {
translates2.AppendTranslate(0, 2, 0);
translates2.AppendTranslate(0, 2, 0);
+ TransformOperations mixed;
+ mixed.AppendTranslate(0, 2, 0);
+ mixed.AppendScale(2, 1, 1);
+ mixed.AppendSkew(0, 2);
+
TransformOperations translates3 = translates2;
- EXPECT_FALSE(translates.MatchesTypes(skews));
- EXPECT_TRUE(translates.MatchesTypes(translates2));
- EXPECT_TRUE(translates.MatchesTypes(translates3));
+ EXPECT_EQ(0UL, translates.MatchingPrefixLength(skews));
+ EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates2));
+ EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates3));
+ EXPECT_EQ(1UL, translates.MatchingPrefixLength(mixed));
}
-TEST(TransformOperationTest, MatchTypesDifferentLength) {
+TEST(TransformOperationTest, MatchingPrefixDifferentLength) {
TransformOperations translates;
translates.AppendTranslate(1, 0, 0);
translates.AppendTranslate(1, 0, 0);
@@ -122,8 +129,14 @@ TEST(TransformOperationTest, MatchTypesDifferentLength) {
translates2.AppendTranslate(0, 2, 0);
translates2.AppendTranslate(0, 2, 0);
- EXPECT_FALSE(translates.MatchesTypes(skews));
- EXPECT_FALSE(translates.MatchesTypes(translates2));
+ TransformOperations none;
+
+ EXPECT_EQ(0UL, translates.MatchingPrefixLength(skews));
+ // Pad the length of the shorter list provided all previous operation-
+ // pairs match per spec
+ // (https://drafts.csswg.org/css-transforms/#interpolation-of-transforms).
+ EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates2));
+ EXPECT_EQ(3UL, translates.MatchingPrefixLength(none));
}
std::vector<std::unique_ptr<TransformOperations>> GetIdentityOperations() {
@@ -180,7 +193,7 @@ std::vector<std::unique_ptr<TransformOperations>> GetIdentityOperations() {
return operations;
}
-TEST(TransformOperationTest, MatchTypesOrder) {
+TEST(TransformOperationTest, MatchingPrefixLengthOrder) {
TransformOperations mix_order_identity;
mix_order_identity.AppendTranslate(0, 0, 0);
mix_order_identity.AppendScale(1, 1, 1);
@@ -196,9 +209,9 @@ TEST(TransformOperationTest, MatchTypesOrder) {
mix_order_two.AppendTranslate(1, 0, 0);
mix_order_two.AppendScale(2, 1, 3);
- EXPECT_TRUE(mix_order_identity.MatchesTypes(mix_order_one));
- EXPECT_FALSE(mix_order_identity.MatchesTypes(mix_order_two));
- EXPECT_FALSE(mix_order_one.MatchesTypes(mix_order_two));
+ EXPECT_EQ(3UL, mix_order_identity.MatchingPrefixLength(mix_order_one));
+ EXPECT_EQ(1UL, mix_order_identity.MatchingPrefixLength(mix_order_two));
+ EXPECT_EQ(1UL, mix_order_one.MatchingPrefixLength(mix_order_two));
}
TEST(TransformOperationTest, NoneAlwaysMatches) {
@@ -207,7 +220,8 @@ TEST(TransformOperationTest, NoneAlwaysMatches) {
TransformOperations none_operation;
for (size_t i = 0; i < operations.size(); ++i)
- EXPECT_TRUE(operations[i]->MatchesTypes(none_operation));
+ EXPECT_EQ(operations[i]->size(),
+ operations[i]->MatchingPrefixLength(none_operation));
}
TEST(TransformOperationTest, ApplyTranslate) {
@@ -316,6 +330,10 @@ TEST(TransformOperationTest, BlendOrder) {
SkMScalar dy2 = 20;
SkMScalar dz2 = 30;
+ SkMScalar sx3 = 2;
+ SkMScalar sy3 = 1;
+ SkMScalar sz3 = 1;
+
TransformOperations operations_from;
operations_from.AppendScale(sx1, sy1, sz1);
operations_from.AppendTranslate(dx1, dy1, dz1);
@@ -368,16 +386,54 @@ TEST(TransformOperationTest, BlendOrder) {
ExpectTransformOperationEqual(expected_op, blended_op);
}
- // Create a mismatch, forcing matrix interpolation.
- operations_to.AppendMatrix(gfx::Transform());
+ TransformOperations base_operations_expected = operations_expected;
+
+ // Create a mismatch in number of operations. Pairwise interpolation is still
+ // used when the operations match up to the length of the shorter list.
+ operations_to.AppendScale(sx3, sy3, sz3);
+
+ gfx::Transform appended_scale;
+ appended_scale.Scale3d(sx3, sy3, sz3);
+
+ gfx::Transform blended_append_scale = appended_scale;
+ blended_append_scale.Blend(gfx::Transform(), progress);
+ expected.PreconcatTransform(blended_append_scale);
+
+ operations_expected.AppendScale(
+ gfx::Tween::FloatValueBetween(progress, 1, sx3),
+ gfx::Tween::FloatValueBetween(progress, 1, sy3),
+ gfx::Tween::FloatValueBetween(progress, 1, sz3));
+
+ blended = operations_to.Blend(operations_from, progress);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected, blended.Apply());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(operations_expected.Apply(), blended.Apply());
+ EXPECT_EQ(operations_expected.size(), blended.size());
+ for (size_t i = 0; i < operations_expected.size(); ++i) {
+ TransformOperation expected_op = operations_expected.at(i);
+ TransformOperation blended_op = blended.at(i);
+ SCOPED_TRACE(i);
+ ExpectTransformOperationEqual(expected_op, blended_op);
+ }
+
+ // Create a mismatch, forcing matrix interpolation for the last operator pair.
+ operations_from.AppendRotate(0, 0, 1, 90);
blended = operations_to.Blend(operations_from, progress);
- expected = operations_to.Apply();
- expected.Blend(operations_from.Apply(), progress);
+ gfx::Transform transform_from;
+ transform_from.RotateAboutZAxis(90);
+ gfx::Transform transform_to;
+ transform_to.Scale3d(sx3, sy3, sz3);
+ gfx::Transform blended_matrix = transform_to;
+ blended_matrix.Blend(transform_from, progress);
+
+ expected = blended_scale;
+ expected.PreconcatTransform(blended_translate);
+ expected.PreconcatTransform(blended_matrix);
- operations_expected = TransformOperations();
- operations_expected.AppendMatrix(expected);
+ operations_expected = base_operations_expected;
+ operations_expected.AppendMatrix(blended_matrix);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, blended.Apply());
EXPECT_TRANSFORMATION_MATRIX_EQ(operations_expected.Apply(), blended.Apply());
@@ -1028,7 +1084,7 @@ TEST(TransformOperationTest, BlendedBoundsForRotationTrivial) {
// Since we're rotating 360 degrees, any box with dimensions between 0 and
// 2 * sqrt(2) should give the same result.
float sizes[] = { 0.f, 0.1f, sqrt_2, 2.f * sqrt_2 };
- for (size_t i = 0; i < arraysize(sizes); ++i) {
+ for (size_t i = 0; i < base::size(sizes); ++i) {
box.set_size(sizes[i], sizes[i], 0.f);
SkMScalar min_progress = 0.f;
SkMScalar max_progress = 1.f;
@@ -1123,7 +1179,7 @@ TEST(TransformOperationTest, BlendedBoundsForRotationProblematicAxes) {
{0.f, 1.f, 1.f, gfx::BoxF(-1.f, dim1, dim1, 2.f, dim2, dim2)},
{1.f, 0.f, 1.f, gfx::BoxF(dim1, -1.f, dim1, dim2, 2.f, dim2)}};
- for (size_t i = 0; i < arraysize(tests); ++i) {
+ for (size_t i = 0; i < base::size(tests); ++i) {
float x = tests[i].x;
float y = tests[i].y;
float z = tests[i].z;
@@ -1262,9 +1318,9 @@ TEST(TransformOperationTest, BlendedBoundsForRotationEmpiricalTests) {
{0.f, 1.f}, {-.25f, 1.25f},
};
- for (size_t i = 0; i < arraysize(axes); ++i) {
- for (size_t j = 0; j < arraysize(angles); ++j) {
- for (size_t k = 0; k < arraysize(progress); ++k) {
+ for (size_t i = 0; i < base::size(axes); ++i) {
+ for (size_t j = 0; j < base::size(angles); ++j) {
+ for (size_t k = 0; k < base::size(progress); ++k) {
float x = axes[i].x;
float y = axes[i].y;
float z = axes[i].z;
@@ -1325,8 +1381,8 @@ TEST(TransformOperationTest, BlendedBoundsForPerspective) {
{0.f, 1.f}, {-0.1f, 1.1f},
};
- for (size_t i = 0; i < arraysize(perspective_depths); ++i) {
- for (size_t j = 0; j < arraysize(progress); ++j) {
+ for (size_t i = 0; i < base::size(perspective_depths); ++i) {
+ for (size_t j = 0; j < base::size(progress); ++j) {
TransformOperations operations_from;
operations_from.AppendPerspective(perspective_depths[i].from_depth);
TransformOperations operations_to;
@@ -1356,8 +1412,8 @@ TEST(TransformOperationTest, BlendedBoundsForSkew) {
{0.f, 1.f}, {-0.1f, 1.1f},
};
- for (size_t i = 0; i < arraysize(skews); ++i) {
- for (size_t j = 0; j < arraysize(progress); ++j) {
+ for (size_t i = 0; i < base::size(skews); ++i) {
+ for (size_t j = 0; j < base::size(progress); ++j) {
TransformOperations operations_from;
operations_from.AppendSkew(skews[i].from_x, skews[i].from_y);
TransformOperations operations_to;
@@ -1681,4 +1737,60 @@ TEST(TransformOperationsTest, ApproximateEquality) {
}
} // namespace
+
+// This test is intentionally outside the anonymous namespace for visibility as
+// it needs to be friend of TransformOperations.
+TEST(TransformOperationsTest, TestDecompositionCache) {
+ TransformOperations transforms;
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a scale transform.
+ transforms.AppendScale(2.f, 2.f, 2.f);
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(1));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(1));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(2UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a rotation transform.
+ transforms.AppendRotate(1, 0, 0, 45);
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a translation transform.
+ transforms.AppendTranslate(1, 1, 1);
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a skew transform.
+ transforms.AppendSkew(1, 0);
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a perspective transform.
+ transforms.AppendPerspective(800);
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a matrix transform.
+ transforms.AppendMatrix(gfx::Transform());
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+
+ // Reset cache when appending a generic transform operation.
+ transforms.Append(TransformOperation());
+ EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
+ EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
+ EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
+}
+
} // namespace cc
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index c8d009f4adf..68600f49314 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -118,12 +118,12 @@ TEST_F(WorkletAnimationTest, CurrentTimeCorrectlyUsesScrollTimeline) {
worklet_animation->UpdateInputState(state.get(), base::TimeTicks::Now(),
scroll_tree, true);
std::unique_ptr<AnimationWorkletInput> input =
- state->TakeWorkletState(worklet_animation_id_.scope_id);
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(1234, input->added_and_updated_animations[0].current_time);
}
TEST_F(WorkletAnimationTest,
- CurrentTimeFromDocumentTimelineIsOffsetByStartTime) {
+ CurrentTimeFromRegularTimelineIsOffsetByStartTime) {
scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
worklet_animation_id_, "test_name", nullptr, nullptr);
@@ -141,18 +141,18 @@ TEST_F(WorkletAnimationTest,
true);
// First state request sets the start time and thus current time should be 0.
std::unique_ptr<AnimationWorkletInput> input =
- state->TakeWorkletState(worklet_animation_id_.scope_id);
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(0, input->added_and_updated_animations[0].current_time);
state.reset(new MutatorInputState);
worklet_animation->UpdateInputState(state.get(), second_ticks, scroll_tree,
true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(123.4, input->updated_animations[0].current_time);
// Should always offset from start time.
state.reset(new MutatorInputState());
worklet_animation->UpdateInputState(state.get(), third_ticks, scroll_tree,
true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(246.8, input->updated_animations[0].current_time);
}
@@ -178,7 +178,7 @@ TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
base::TimeTicks time;
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
std::unique_ptr<AnimationWorkletInput> input =
- state->TakeWorkletState(worklet_animation_id_.scope_id);
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->added_and_updated_animations.size(), 1u);
EXPECT_EQ("test_name", input->added_and_updated_animations[0].name);
EXPECT_EQ(input->updated_animations.size(), 0u);
@@ -189,7 +189,7 @@ TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
state.reset(new MutatorInputState());
time += base::TimeDelta::FromSecondsD(0.1);
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
EXPECT_EQ(input->updated_animations.size(), 1u);
EXPECT_EQ(input->removed_animations.size(), 0u);
@@ -200,7 +200,7 @@ TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
state.reset(new MutatorInputState());
time += base::TimeDelta::FromSecondsD(0.1);
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
EXPECT_EQ(input->updated_animations.size(), 1u);
EXPECT_EQ(input->removed_animations.size(), 0u);
@@ -211,7 +211,7 @@ TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
worklet_animation_->UpdateState(true, nullptr);
state.reset(new MutatorInputState());
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
EXPECT_EQ(input->updated_animations.size(), 0u);
EXPECT_EQ(input->removed_animations.size(), 1u);
@@ -236,21 +236,21 @@ TEST_F(WorkletAnimationTest, SkipUnchangedAnimations) {
base::TimeTicks time;
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
std::unique_ptr<AnimationWorkletInput> input =
- state->TakeWorkletState(worklet_animation_id_.scope_id);
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->added_and_updated_animations.size(), 1u);
EXPECT_EQ(input->updated_animations.size(), 0u);
state.reset(new MutatorInputState());
// No update on the input state if input time stays the same.
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_FALSE(input);
state.reset(new MutatorInputState());
// Different input time causes the input state to be updated.
time += base::TimeDelta::FromSecondsD(0.1);
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->updated_animations.size(), 1u);
state.reset(new MutatorInputState());
@@ -258,7 +258,7 @@ TEST_F(WorkletAnimationTest, SkipUnchangedAnimations) {
// the input time doesn't change.
worklet_animation_->RemoveKeyframeModel(keyframe_model_id);
worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
- input = state->TakeWorkletState(worklet_animation_id_.scope_id);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
EXPECT_EQ(input->updated_animations.size(), 0u);
EXPECT_EQ(input->removed_animations.size(), 1u);
}
diff --git a/chromium/cc/base/delayed_unique_notifier.cc b/chromium/cc/base/delayed_unique_notifier.cc
index fa8da7ab467..741bc83c71f 100644
--- a/chromium/cc/base/delayed_unique_notifier.cc
+++ b/chromium/cc/base/delayed_unique_notifier.cc
@@ -13,14 +13,13 @@ namespace cc {
DelayedUniqueNotifier::DelayedUniqueNotifier(
base::SequencedTaskRunner* task_runner,
- const base::Closure& closure,
+ base::RepeatingClosure closure,
const base::TimeDelta& delay)
: task_runner_(task_runner),
- closure_(closure),
+ closure_(std::move(closure)),
delay_(delay),
notification_pending_(false),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
DelayedUniqueNotifier::~DelayedUniqueNotifier() = default;
diff --git a/chromium/cc/base/delayed_unique_notifier.h b/chromium/cc/base/delayed_unique_notifier.h
index 86d2e37e1b8..4a7486e099a 100644
--- a/chromium/cc/base/delayed_unique_notifier.h
+++ b/chromium/cc/base/delayed_unique_notifier.h
@@ -21,7 +21,7 @@ class CC_BASE_EXPORT DelayedUniqueNotifier {
// Configure this notifier to issue the |closure| notification in |delay| time
// from Schedule() call.
DelayedUniqueNotifier(base::SequencedTaskRunner* task_runner,
- const base::Closure& closure,
+ base::RepeatingClosure closure,
const base::TimeDelta& delay);
// Destroying the notifier will ensure that no further notifications will
@@ -56,7 +56,7 @@ class CC_BASE_EXPORT DelayedUniqueNotifier {
void NotifyIfTime();
base::SequencedTaskRunner* const task_runner_;
- const base::Closure closure_;
+ const base::RepeatingClosure closure_;
const base::TimeDelta delay_;
// Lock should be held before modifying |next_notification_time_| or
diff --git a/chromium/cc/base/delayed_unique_notifier_unittest.cc b/chromium/cc/base/delayed_unique_notifier_unittest.cc
index 8731cb0ba73..16ee60687a8 100644
--- a/chromium/cc/base/delayed_unique_notifier_unittest.cc
+++ b/chromium/cc/base/delayed_unique_notifier_unittest.cc
@@ -16,9 +16,9 @@ namespace {
class TestNotifier : public DelayedUniqueNotifier {
public:
TestNotifier(base::SequencedTaskRunner* task_runner,
- const base::Closure& closure,
+ base::RepeatingClosure closure,
const base::TimeDelta& delay)
- : DelayedUniqueNotifier(task_runner, closure, delay) {}
+ : DelayedUniqueNotifier(task_runner, std::move(closure), delay) {}
~TestNotifier() override = default;
// Overridden from DelayedUniqueNotifier:
@@ -54,10 +54,10 @@ class DelayedUniqueNotifierTest : public testing::Test {
TEST_F(DelayedUniqueNotifierTest, ZeroDelay) {
base::TimeDelta delay; // Zero delay.
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
EXPECT_EQ(0, NotificationCount());
@@ -89,10 +89,10 @@ TEST_F(DelayedUniqueNotifierTest, ZeroDelay) {
TEST_F(DelayedUniqueNotifierTest, SmallDelay) {
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
EXPECT_EQ(0, NotificationCount());
@@ -149,10 +149,10 @@ TEST_F(DelayedUniqueNotifierTest, SmallDelay) {
TEST_F(DelayedUniqueNotifierTest, RescheduleDelay) {
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
base::TimeTicks schedule_time;
// Move time 19 units forward and reschedule, expecting that we still need to
@@ -191,10 +191,10 @@ TEST_F(DelayedUniqueNotifierTest, RescheduleDelay) {
TEST_F(DelayedUniqueNotifierTest, CancelAndHasPendingNotification) {
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
EXPECT_EQ(0, NotificationCount());
@@ -261,10 +261,10 @@ TEST_F(DelayedUniqueNotifierTest, CancelAndHasPendingNotification) {
TEST_F(DelayedUniqueNotifierTest, ShutdownWithScheduledTask) {
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
EXPECT_EQ(0, NotificationCount());
@@ -302,10 +302,10 @@ TEST_F(DelayedUniqueNotifierTest, ShutdownWithScheduledTask) {
TEST_F(DelayedUniqueNotifierTest, ShutdownPreventsSchedule) {
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
- TestNotifier notifier(
- task_runner_.get(),
- base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
- delay);
+ TestNotifier notifier(task_runner_.get(),
+ base::BindRepeating(&DelayedUniqueNotifierTest::Notify,
+ base::Unretained(this)),
+ delay);
EXPECT_EQ(0, NotificationCount());
diff --git a/chromium/cc/base/index_rect_unittest.cc b/chromium/cc/base/index_rect_unittest.cc
index aff41ee9759..1580a3947e7 100644
--- a/chromium/cc/base/index_rect_unittest.cc
+++ b/chromium/cc/base/index_rect_unittest.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/macros.h"
#include "cc/base/index_rect.h"
+#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -22,7 +22,7 @@ TEST(IndexRectTest, NumIndices) {
{0, 0, 0, 0, 1, 1},
{10, 10, 10, 10, 1, 1}};
- for (size_t i = 0; i < arraysize(num_indices_cases); ++i) {
+ for (size_t i = 0; i < base::size(num_indices_cases); ++i) {
const NumIndicesCase& value = num_indices_cases[i];
IndexRect rect(value.left, value.right, value.top, value.bottom);
EXPECT_EQ(value.num_indices_x, rect.num_indices_x());
@@ -49,7 +49,7 @@ TEST(IndexRectTest, ClampTo) {
{{-10, 5, -10, 5}, {0, 10, 0, 10}, {0, 5, 0, 5}, true},
{{0, 5, 0, 5}, {10, 20, 10, 20}, {0, 0, 0, 0}, false}};
- for (size_t i = 0; i < arraysize(clamp_to_cases); ++i) {
+ for (size_t i = 0; i < base::size(clamp_to_cases); ++i) {
const ClampToCase& value = clamp_to_cases[i];
IndexRect first(value.first.left, value.first.right, value.first.top,
value.first.bottom);
@@ -82,7 +82,7 @@ TEST(IndexRectTest, Contains) {
{-10, 10, -10, 10, 20, 20, false}, {-10, 10, -10, 10, 20, 5, false},
{-10, 10, -10, 10, 5, 20, false}};
- for (size_t i = 0; i < arraysize(contains_cases); ++i) {
+ for (size_t i = 0; i < base::size(contains_cases); ++i) {
const ContainsCase& value = contains_cases[i];
IndexRect rect(value.left, value.right, value.top, value.bottom);
EXPECT_EQ(value.contained, rect.Contains(value.index_x, value.index_y));
diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc
index d363fe84b1d..22db5dd0254 100644
--- a/chromium/cc/base/switches.cc
+++ b/chromium/cc/base/switches.cc
@@ -48,10 +48,6 @@ const char kCheckDamageEarly[] = "check-damage-early";
// Enables the GPU benchmarking extension
const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking";
-// Always asks the display compositor to send back presentation times.
-const char kAlwaysRequestPresentationTime[] =
- "always-request-presentation-time";
-
// Renders a border around compositor layers to help debug and study
// layer compositing.
const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h
index fe8de281021..cde4700a15d 100644
--- a/chromium/cc/base/switches.h
+++ b/chromium/cc/base/switches.h
@@ -29,7 +29,6 @@ CC_BASE_EXPORT extern const char kCheckDamageEarly[];
// Switches for both the renderer and ui compositors.
CC_BASE_EXPORT extern const char kEnableGpuBenchmarking[];
-CC_BASE_EXPORT extern const char kAlwaysRequestPresentationTime[];
// Debug visualizations.
CC_BASE_EXPORT extern const char kShowCompositedLayerBorders[];
diff --git a/chromium/cc/base/unique_notifier.cc b/chromium/cc/base/unique_notifier.cc
index 2ad6a291c73..52e7a498de3 100644
--- a/chromium/cc/base/unique_notifier.cc
+++ b/chromium/cc/base/unique_notifier.cc
@@ -12,12 +12,11 @@
namespace cc {
UniqueNotifier::UniqueNotifier(base::SequencedTaskRunner* task_runner,
- const base::Closure& closure)
+ base::RepeatingClosure closure)
: task_runner_(task_runner),
- closure_(closure),
+ closure_(std::move(closure)),
notification_pending_(false),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
UniqueNotifier::~UniqueNotifier() = default;
diff --git a/chromium/cc/base/unique_notifier.h b/chromium/cc/base/unique_notifier.h
index d753e1f352a..ff129c8b525 100644
--- a/chromium/cc/base/unique_notifier.h
+++ b/chromium/cc/base/unique_notifier.h
@@ -22,7 +22,7 @@ class CC_BASE_EXPORT UniqueNotifier {
public:
// Configure this notifier to issue the |closure| notification when scheduled.
UniqueNotifier(base::SequencedTaskRunner* task_runner,
- const base::Closure& closure);
+ base::RepeatingClosure closure);
// Destroying the notifier will ensure that no further notifications will
// happen from this class.
@@ -40,7 +40,7 @@ class CC_BASE_EXPORT UniqueNotifier {
// TODO(dcheng): How come this doesn't need to hold a ref to the task runner?
base::SequencedTaskRunner* const task_runner_;
- const base::Closure closure_;
+ const base::RepeatingClosure closure_;
// Lock should be held before modifying |notification_pending_|.
base::Lock lock_;
diff --git a/chromium/cc/base/unique_notifier_unittest.cc b/chromium/cc/base/unique_notifier_unittest.cc
index cfac61efaef..a7995e29d10 100644
--- a/chromium/cc/base/unique_notifier_unittest.cc
+++ b/chromium/cc/base/unique_notifier_unittest.cc
@@ -49,9 +49,9 @@ class UniqueNotifierTest : public testing::Test {
// 50000 can be any number bigger than 1. The bigger the easier to more runs.
TEST_F(UniqueNotifierTest, Schedule) {
{
- UniqueNotifier notifier(
- base::ThreadTaskRunnerHandle::Get().get(),
- base::Bind(&UniqueNotifierTest::Notify, base::Unretained(this)));
+ UniqueNotifier notifier(base::ThreadTaskRunnerHandle::Get().get(),
+ base::BindRepeating(&UniqueNotifierTest::Notify,
+ base::Unretained(this)));
EXPECT_EQ(0, NotificationCount());
diff --git a/chromium/cc/benchmarks/micro_benchmark_controller_unittest.cc b/chromium/cc/benchmarks/micro_benchmark_controller_unittest.cc
index 355447a6d00..171351e1c9b 100644
--- a/chromium/cc/benchmarks/micro_benchmark_controller_unittest.cc
+++ b/chromium/cc/benchmarks/micro_benchmark_controller_unittest.cc
@@ -76,7 +76,7 @@ TEST_F(MicroBenchmarkControllerTest, BenchmarkRan) {
int run_count = 0;
int id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
layer_tree_host_->UpdateLayers();
@@ -88,11 +88,11 @@ TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
int run_count = 0;
int id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
layer_tree_host_->UpdateLayers();
@@ -101,11 +101,11 @@ TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
layer_tree_host_->UpdateLayers();
@@ -123,7 +123,7 @@ TEST_F(MicroBenchmarkControllerTest, BenchmarkImplRan) {
// Schedule a main thread benchmark.
int id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", std::move(settings),
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
// Schedule impl benchmarks. In production code, this is run in commit.
@@ -151,7 +151,7 @@ TEST_F(MicroBenchmarkControllerTest, SendMessage) {
int run_count = 0;
int id = layer_tree_host_->ScheduleMicroBenchmark(
"unittest_only_benchmark", nullptr,
- base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
// Send valid message to valid benchmark
diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc
index 5d1afd1357b..a8c606ac470 100644
--- a/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc
+++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc
@@ -131,8 +131,8 @@ RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) {
return base::WrapUnique(new RasterizeAndRecordBenchmarkImpl(
origin_task_runner, settings_.get(),
- base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults,
- weak_ptr_factory_.GetWeakPtr())));
+ base::BindOnce(&RasterizeAndRecordBenchmark::RecordRasterResults,
+ weak_ptr_factory_.GetWeakPtr())));
}
void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
diff --git a/chromium/cc/benchmarks/unittest_only_benchmark.cc b/chromium/cc/benchmarks/unittest_only_benchmark.cc
index 10724d47f98..4e32942140a 100644
--- a/chromium/cc/benchmarks/unittest_only_benchmark.cc
+++ b/chromium/cc/benchmarks/unittest_only_benchmark.cc
@@ -61,8 +61,8 @@ std::unique_ptr<MicroBenchmarkImpl> UnittestOnlyBenchmark::CreateBenchmarkImpl(
return base::WrapUnique(new UnittestOnlyBenchmarkImpl(
origin_task_runner, nullptr,
- base::Bind(&UnittestOnlyBenchmark::RecordImplResults,
- weak_ptr_factory_.GetWeakPtr())));
+ base::BindOnce(&UnittestOnlyBenchmark::RecordImplResults,
+ weak_ptr_factory_.GetWeakPtr())));
}
} // namespace cc
diff --git a/chromium/cc/input/layer_selection_bound.cc b/chromium/cc/input/layer_selection_bound.cc
index 521cd653f59..55f2e3a5fb4 100644
--- a/chromium/cc/input/layer_selection_bound.cc
+++ b/chromium/cc/input/layer_selection_bound.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "cc/input/layer_selection_bound.h"
namespace cc {
@@ -22,4 +23,10 @@ bool LayerSelectionBound::operator!=(const LayerSelectionBound& other) const {
return !(*this == other);
}
+std::string LayerSelectionBound::ToString() const {
+ return base::StringPrintf("LayerSelectionBound(%s, %s, %d)",
+ edge_top.ToString().c_str(),
+ edge_bottom.ToString().c_str(), hidden);
+}
+
} // namespace cc
diff --git a/chromium/cc/input/layer_selection_bound.h b/chromium/cc/input/layer_selection_bound.h
index 5174341909b..a2a2583c143 100644
--- a/chromium/cc/input/layer_selection_bound.h
+++ b/chromium/cc/input/layer_selection_bound.h
@@ -26,6 +26,8 @@ struct CC_EXPORT LayerSelectionBound {
// content of the layer (as opposed to being outside of the layer's bounds).
bool hidden;
+ std::string ToString() const;
+
bool operator==(const LayerSelectionBound& other) const;
bool operator!=(const LayerSelectionBound& other) const;
};
diff --git a/chromium/cc/input/main_thread_scrolling_reason.cc b/chromium/cc/input/main_thread_scrolling_reason.cc
index 728708ce776..5d1a6b9c5a9 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason.cc
@@ -35,8 +35,8 @@ void MainThreadScrollingReason::AddToTracedValue(
traced_value.AppendString("Threaded scrolling is disabled");
if (reasons & kScrollbarScrolling)
traced_value.AppendString("Scrollbar scrolling");
- if (reasons & kPageOverlay)
- traced_value.AppendString("Page overlay");
+ if (reasons & kFrameOverlay)
+ traced_value.AppendString("Frame overlay");
if (reasons & kHandlingScrollFromMainThread)
traced_value.AppendString("Handling scroll from main thread");
if (reasons & kCustomScrollbarScrolling)
diff --git a/chromium/cc/input/main_thread_scrolling_reason.h b/chromium/cc/input/main_thread_scrolling_reason.h
index 732c3fa904b..6878928bfe7 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.h
+++ b/chromium/cc/input/main_thread_scrolling_reason.h
@@ -28,7 +28,7 @@ struct CC_EXPORT MainThreadScrollingReason {
kHasNonLayerViewportConstrainedObjects = 1 << 1,
kThreadedScrollingDisabled = 1 << 2,
kScrollbarScrolling = 1 << 3,
- kPageOverlay = 1 << 4,
+ kFrameOverlay = 1 << 4,
// This bit is set when any of the other main thread scrolling reasons cause
// an input event to be handled on the main thread, and the main thread
@@ -80,7 +80,7 @@ struct CC_EXPORT MainThreadScrollingReason {
uint32_t reasons_set_by_main_thread =
kNotScrollingOnMain | kHasBackgroundAttachmentFixedObjects |
kHasNonLayerViewportConstrainedObjects | kThreadedScrollingDisabled |
- kScrollbarScrolling | kPageOverlay | kHandlingScrollFromMainThread |
+ kScrollbarScrolling | kFrameOverlay | kHandlingScrollFromMainThread |
kCustomScrollbarScrolling;
return (reasons & reasons_set_by_main_thread) == reasons;
}
diff --git a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
index 7560dda71d9..c6ab9e4a61f 100644
--- a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
@@ -17,7 +17,7 @@ TEST_F(MainThreadScrollingReasonTest, AsText) {
"Has non-layer viewport-constrained objects,"
"Threaded scrolling is disabled,"
"Scrollbar scrolling,"
- "Page overlay,"
+ "Frame overlay,"
"Handling scroll from main thread,"
"Custom scrollbar scrolling,"
"Has opacity and LCD text,"
diff --git a/chromium/cc/input/scroll_snap_data.cc b/chromium/cc/input/scroll_snap_data.cc
index 3fc17474fc7..3d4ad87e1ba 100644
--- a/chromium/cc/input/scroll_snap_data.cc
+++ b/chromium/cc/input/scroll_snap_data.cc
@@ -153,24 +153,42 @@ base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea(
SearchAxis axis,
const SnapSelectionStrategy& strategy,
const SnapSearchResult& cros_axis_snap_result) const {
+ base::Optional<SnapSearchResult> result =
+ FindClosestValidAreaInternal(axis, strategy, cros_axis_snap_result);
+ // Our current direction based strategies are too strict ignoring the other
+ // directions even when we have no candidate in the given direction. This is
+ // particularly problematic with mandatory snap points and for fling
+ // gestures. To counteract this, if the direction based strategy finds no
+ // candidates, we do a second search ignoring the direction (this is
+ // implemented by using an equivalent EndPosition strategy).
+ if (result.has_value() ||
+ scroll_snap_type_.strictness == SnapStrictness::kProximity ||
+ !strategy.HasIntendedDirection())
+ return result;
+
+ std::unique_ptr<SnapSelectionStrategy> relaxed_strategy =
+ SnapSelectionStrategy::CreateForEndPosition(strategy.current_position(),
+ strategy.ShouldSnapOnX(),
+ strategy.ShouldSnapOnY());
+ return FindClosestValidAreaInternal(axis, *relaxed_strategy,
+ cros_axis_snap_result);
+}
+
+base::Optional<SnapSearchResult>
+SnapContainerData::FindClosestValidAreaInternal(
+ SearchAxis axis,
+ const SnapSelectionStrategy& strategy,
+ const SnapSearchResult& cros_axis_snap_result) const {
// The search result from the snap area that's closest to the search origin.
base::Optional<SnapSearchResult> closest;
// The search result with the intended position if it makes a snap area cover
// the snapport.
base::Optional<SnapSearchResult> covering;
- // The search result with the current position as a backup in case no other
- // valid snap position exists.
- base::Optional<SnapSearchResult> current;
// The valid snap positions immediately before and after the current position.
float prev = std::numeric_limits<float>::lowest();
float next = std::numeric_limits<float>::max();
- // The current position before the scroll or snap happens. If no other snap
- // position exists, this would become a backup option.
- float current_position = axis == SearchAxis::kX
- ? strategy.current_position().x()
- : strategy.current_position().y();
// The intended position of the scroll operation if there's no snap. This
// scroll position becomes the covering candidate if there is a snap area that
// fully covers the snapport if this position is scrolled to.
@@ -203,24 +221,22 @@ base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea(
}
if (!IsMutualVisible(candidate, cros_axis_snap_result))
continue;
- if (!strategy.IsValidSnapPosition(axis, candidate.snap_offset())) {
- if (candidate.snap_offset() == current_position &&
- scroll_snap_type_.strictness == SnapStrictness::kMandatory) {
- SetOrUpdateResult(candidate, &current);
- }
- continue;
- }
+
float distance = std::abs(candidate.snap_offset() - base_position);
- if (distance < smallest_distance) {
- smallest_distance = distance;
- closest = candidate;
+ if (strategy.IsValidSnapPosition(axis, candidate.snap_offset())) {
+ if (distance < smallest_distance) {
+ smallest_distance = distance;
+ closest = candidate;
+ }
}
if (candidate.snap_offset() < intended_position &&
- candidate.snap_offset() > prev)
+ candidate.snap_offset() > prev) {
prev = candidate.snap_offset();
+ }
if (candidate.snap_offset() > intended_position &&
- candidate.snap_offset() < next)
+ candidate.snap_offset() < next) {
next = candidate.snap_offset();
+ }
}
// According to the spec [1], if the snap area is covering the snapport, the
// scroll position is a valid snap position only if the distance between the
@@ -235,7 +251,7 @@ base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea(
const base::Optional<SnapSearchResult>& picked =
strategy.PickBestResult(closest, covering);
- return picked.has_value() ? picked : current;
+ return picked;
}
SnapSearchResult SnapContainerData::GetSnapSearchResult(
diff --git a/chromium/cc/input/scroll_snap_data.h b/chromium/cc/input/scroll_snap_data.h
index 3057acf339e..3a8da213404 100644
--- a/chromium/cc/input/scroll_snap_data.h
+++ b/chromium/cc/input/scroll_snap_data.h
@@ -218,6 +218,15 @@ class CC_EXPORT SnapContainerData {
// or the original scroll offset if this is the first iteration of search.
// Returns the candidate as SnapSearchResult that includes the area's
// |snap_offset| and its visible range on the cross axis.
+ base::Optional<SnapSearchResult> FindClosestValidAreaInternal(
+ SearchAxis axis,
+ const SnapSelectionStrategy& strategy,
+ const SnapSearchResult& cross_axis_snap_result) const;
+
+ // A wrapper of FindClosestValidAreaInternal(). If
+ // FindClosestValidAreaInternal() doesn't return a valid result when the snap
+ // type is mandatory and the strategy has an intended direction, we relax the
+ // strategy to ignore the direction and find again.
base::Optional<SnapSearchResult> FindClosestValidArea(
SearchAxis axis,
const SnapSelectionStrategy& strategy,
diff --git a/chromium/cc/input/scroll_snap_data_unittest.cc b/chromium/cc/input/scroll_snap_data_unittest.cc
index 6f994d543a0..3d95014f51f 100644
--- a/chromium/cc/input/scroll_snap_data_unittest.cc
+++ b/chromium/cc/input/scroll_snap_data_unittest.cc
@@ -229,4 +229,82 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapToPositionsOutsideProximityRange) {
EXPECT_EQ(100, snap_position.y());
}
+TEST_F(ScrollSnapDataTest, MandatoryReturnsToCurrentIfNoValidAreaForward) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
+ SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(600, 0, 100, 100), false);
+ container.AddSnapAreaData(area);
+ gfx::ScrollOffset snap_position;
+
+ std::unique_ptr<SnapSelectionStrategy> direction_strategy =
+ SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset(600, 0),
+ gfx::ScrollOffset(5, 0));
+ EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ // The snap direction is right. However, there is no valid snap position on
+ // that direction. So we have to stay at the current snap position of 600 as
+ // the snap type is mandatory.
+ EXPECT_EQ(600, snap_position.x());
+ EXPECT_EQ(0, snap_position.y());
+
+ std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
+ SnapSelectionStrategy::CreateForEndAndDirection(
+ gfx::ScrollOffset(600, 0), gfx::ScrollOffset(15, 15));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ // The snap direction is down and right. However, there is no valid snap
+ // position on that direction. So we have to stay at the current snap position
+ // of (600, 0) as the snap type is mandatory.
+ EXPECT_EQ(600, snap_position.x());
+ EXPECT_EQ(0, snap_position.y());
+
+ // If the scroll-snap-type is proximity, we wouldn't consider the current
+ // snap area valid even if there is no snap area forward.
+ container.set_scroll_snap_type(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kProximity));
+ EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ EXPECT_FALSE(
+ container.FindSnapPosition(*end_direction_strategy, &snap_position));
+}
+
+TEST_F(ScrollSnapDataTest, MandatorySnapsBackwardIfNoValidAreaForward) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
+ SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(600, 0, 100, 100), false);
+ container.AddSnapAreaData(area);
+ gfx::ScrollOffset snap_position;
+
+ std::unique_ptr<SnapSelectionStrategy> direction_strategy =
+ SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset(650, 0),
+ gfx::ScrollOffset(5, 0));
+ EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ // The snap direction is right. However, there is no valid snap position on
+ // that direction. So we have to scroll back to the snap position of 600 as
+ // the snap type is mandatory.
+ EXPECT_EQ(600, snap_position.x());
+ EXPECT_EQ(0, snap_position.y());
+
+ std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
+ SnapSelectionStrategy::CreateForEndAndDirection(
+ gfx::ScrollOffset(650, 10), gfx::ScrollOffset(15, 15));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ // The snap direction is down and right. However, there is no valid snap
+ // position on that direction. So we have to scroll back to the snap position
+ // of (600, 0) as the snap type is mandatory.
+ EXPECT_EQ(600, snap_position.x());
+ EXPECT_EQ(0, snap_position.y());
+
+ // If the scroll-snap-type is proximity, we wouldn't consider the backward
+ // snap area valid even if there is no snap area forward.
+ container.set_scroll_snap_type(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kProximity));
+ EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ EXPECT_FALSE(
+ container.FindSnapPosition(*end_direction_strategy, &snap_position));
+}
+
} // namespace cc
diff --git a/chromium/cc/input/scrollbar_animation_controller.cc b/chromium/cc/input/scrollbar_animation_controller.cc
index 55f97f09d1f..0e57be6414b 100644
--- a/chromium/cc/input/scrollbar_animation_controller.cc
+++ b/chromium/cc/input/scrollbar_animation_controller.cc
@@ -124,8 +124,8 @@ void ScrollbarAnimationController::PostDelayedAnimation(
animation_change_ = animation_change;
delayed_scrollbar_animation_.Cancel();
delayed_scrollbar_animation_.Reset(
- base::Bind(&ScrollbarAnimationController::StartAnimation,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&ScrollbarAnimationController::StartAnimation,
+ weak_factory_.GetWeakPtr()));
client_->PostDelayedScrollbarAnimationTask(
delayed_scrollbar_animation_.callback(), fade_delay_);
}
diff --git a/chromium/cc/input/scrollbar_animation_controller.h b/chromium/cc/input/scrollbar_animation_controller.h
index 9473b416bf8..f7a26c523f4 100644
--- a/chromium/cc/input/scrollbar_animation_controller.h
+++ b/chromium/cc/input/scrollbar_animation_controller.h
@@ -18,7 +18,7 @@ namespace cc {
class CC_EXPORT ScrollbarAnimationControllerClient {
public:
- virtual void PostDelayedScrollbarAnimationTask(const base::Closure& task,
+ virtual void PostDelayedScrollbarAnimationTask(base::OnceClosure task,
base::TimeDelta delay) = 0;
virtual void SetNeedsRedrawForScrollbarAnimation() = 0;
virtual void SetNeedsAnimateForScrollbarAnimation() = 0;
@@ -153,7 +153,7 @@ class CC_EXPORT ScrollbarAnimationController {
bool currently_scrolling_;
bool show_in_fast_scroll_;
- base::CancelableClosure delayed_scrollbar_animation_;
+ base::CancelableOnceClosure delayed_scrollbar_animation_;
float opacity_;
diff --git a/chromium/cc/input/scrollbar_animation_controller_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
index e9f336ff695..0836aeb1afa 100644
--- a/chromium/cc/input/scrollbar_animation_controller_unittest.cc
+++ b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
@@ -37,9 +37,9 @@ class MockScrollbarAnimationControllerClient
: host_impl_(host_impl) {}
~MockScrollbarAnimationControllerClient() override = default;
- void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
+ void PostDelayedScrollbarAnimationTask(base::OnceClosure start_fade,
base::TimeDelta delay) override {
- start_fade_ = start_fade;
+ start_fade_ = std::move(start_fade);
delay_ = delay;
}
void SetNeedsRedrawForScrollbarAnimation() override {}
@@ -49,11 +49,11 @@ class MockScrollbarAnimationControllerClient
}
MOCK_METHOD0(DidChangeScrollbarVisibility, void());
- base::Closure& start_fade() { return start_fade_; }
+ base::OnceClosure& start_fade() { return start_fade_; }
base::TimeDelta& delay() { return delay_; }
private:
- base::Closure start_fade_;
+ base::OnceClosure start_fade_;
base::TimeDelta delay_;
LayerTreeHostImpl* host_impl_;
};
@@ -108,12 +108,12 @@ class ScrollbarAnimationControllerAuraOverlayTest : public testing::Test {
host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip));
v_scrollbar_layer_->SetBounds(gfx::Size(kThumbThickness, kTrackLength));
- v_scrollbar_layer_->SetPosition(gfx::PointF(90, 0));
+ v_scrollbar_layer_->test_properties()->position = gfx::PointF(90, 0);
v_scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id());
v_scrollbar_layer_->test_properties()->opacity_can_animate = true;
h_scrollbar_layer_->SetBounds(gfx::Size(kTrackLength, kThumbThickness));
- h_scrollbar_layer_->SetPosition(gfx::PointF(0, 90));
+ h_scrollbar_layer_->test_properties()->position = gfx::PointF(0, 90);
h_scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id());
h_scrollbar_layer_->test_properties()->opacity_can_animate = true;
@@ -261,7 +261,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, BasicAppearAndFadeOut) {
// An fade out animation should have been enqueued.
EXPECT_EQ(kFadeDelay, client_.delay());
EXPECT_FALSE(client_.start_fade().is_null());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
// Scrollbar should fade out over kFadeDuration.
scrollbar_controller_->Animate(time);
@@ -290,7 +290,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest,
// An fade out animation should have been enqueued.
EXPECT_EQ(kFadeDelay, client_.delay());
EXPECT_FALSE(client_.start_fade().is_null());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
// Scrollbar should fade out over kFadeDuration.
scrollbar_controller_->Animate(time);
@@ -651,7 +651,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest,
// A fade out animation should have been enqueued. Start it.
EXPECT_EQ(kFadeDelay, client_.delay());
EXPECT_FALSE(client_.start_fade().is_null());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
ExpectScrollbarsOpacity(1);
@@ -691,7 +691,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, TestCantCaptureWhenFaded) {
EXPECT_EQ(kFadeDelay, client_.delay());
EXPECT_FALSE(client_.start_fade().is_null());
EXPECT_FALSE(client_.start_fade().IsCancelled());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
ExpectScrollbarsOpacity(1);
@@ -736,8 +736,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, TestCantCaptureWhenFaded) {
EXPECT_EQ(kFadeDelay, client_.delay());
// Play the delay animation.
- client_.start_fade().Run();
- EXPECT_TRUE(client_.start_fade().IsCancelled());
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
time += kFadeDuration;
@@ -831,7 +830,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, FadeAnimated) {
// An fade out animation should have been enqueued.
EXPECT_EQ(kFadeDelay, client_.delay());
EXPECT_FALSE(client_.start_fade().is_null());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
// Test that at half the fade duration time, the opacity is at half.
scrollbar_controller_->Animate(time);
@@ -865,7 +864,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, NotifyChangedVisibility) {
// to) notify during the animation that the scrollbars are still visible.
EXPECT_CALL(client_, DidChangeScrollbarVisibility()).Times(0);
ASSERT_FALSE(client_.start_fade().is_null());
- client_.start_fade().Run();
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
time += kFadeDuration / 4;
EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden());
@@ -1123,8 +1122,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, BasicMouseHoverFadeIn) {
EXPECT_EQ(kFadeDelay, client_.delay());
// Play the delay animation.
- client_.start_fade().Run();
- EXPECT_TRUE(client_.start_fade().IsCancelled());
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
time += kFadeDuration / 2;
@@ -1156,13 +1154,13 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest,
EXPECT_FALSE(client_.start_fade().IsCancelled());
EXPECT_EQ(kFadeDelay, client_.delay());
- base::Closure& fade = client_.start_fade();
+ client_.start_fade().Reset();
// Move mouse still hover the fade in region of scrollbar should not
// post a new fade in.
scrollbar_controller_->DidMouseMove(
NearVerticalScrollbarBegin(-kMouseMoveDistanceToTriggerFadeIn + 2, 0));
- EXPECT_TRUE(fade.Equals(client_.start_fade()));
+ EXPECT_TRUE(client_.start_fade().is_null());
}
// Scrollbars should cancel delay fade in when mouse hover hidden scrollbar then
@@ -1220,8 +1218,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest,
EXPECT_EQ(kFadeDelay, client_.delay());
// Play the delay animation.
- client_.start_fade().Run();
- EXPECT_TRUE(client_.start_fade().IsCancelled());
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
time += kFadeDuration;
@@ -1269,8 +1266,7 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest,
EXPECT_EQ(kFadeDelay, client_.delay());
// Play the delay animation.
- client_.start_fade().Run();
- EXPECT_TRUE(client_.start_fade().IsCancelled());
+ std::move(client_.start_fade()).Run();
scrollbar_controller_->Animate(time);
time += kFadeDuration;
@@ -1375,9 +1371,9 @@ class ScrollbarAnimationControllerAndroidTest
did_request_redraw_(false),
did_request_animate_(false) {}
- void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
+ void PostDelayedScrollbarAnimationTask(base::OnceClosure start_fade,
base::TimeDelta delay) override {
- start_fade_ = start_fade;
+ start_fade_ = std::move(start_fade);
delay_ = delay;
}
void SetNeedsRedrawForScrollbarAnimation() override {
@@ -1438,7 +1434,7 @@ class ScrollbarAnimationControllerAndroidTest
std::unique_ptr<ScrollbarAnimationController> scrollbar_controller_;
SolidColorScrollbarLayerImpl* scrollbar_layer_;
- base::Closure start_fade_;
+ base::OnceClosure start_fade_;
base::TimeDelta delay_;
bool did_request_redraw_;
bool did_request_animate_;
@@ -1467,7 +1463,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest,
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity());
scrollbar_controller_->DidScrollEnd();
- EXPECT_TRUE(start_fade_.Equals(base::Closure()));
+ EXPECT_TRUE(start_fade_.is_null());
time += base::TimeDelta::FromSeconds(100);
scrollbar_controller_->Animate(time);
@@ -1490,7 +1486,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest,
EXPECT_TRUE(scrollbar_controller_->ScrollbarsHidden());
// No fade out animation should have been enqueued.
- EXPECT_TRUE(start_fade_.Equals(base::Closure()));
+ EXPECT_TRUE(start_fade_.is_null());
}
TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnResize) {
@@ -1626,7 +1622,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByScrollingGesture) {
EXPECT_FALSE(did_request_animate_);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity());
- EXPECT_TRUE(start_fade_.Equals(base::Closure()));
+ EXPECT_TRUE(start_fade_.is_null());
time += base::TimeDelta::FromSeconds(100);
@@ -1635,7 +1631,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByScrollingGesture) {
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity());
scrollbar_controller_->DidScrollEnd();
EXPECT_FALSE(did_request_animate_);
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
@@ -1663,7 +1659,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByScrollingGesture) {
scrollbar_controller_->DidScrollUpdate();
scrollbar_controller_->DidScrollEnd();
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
@@ -1697,7 +1693,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByProgrammaticScroll) {
scrollbar_controller_->DidScrollUpdate();
EXPECT_FALSE(did_request_animate_);
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
scrollbar_controller_->Animate(time);
@@ -1713,7 +1709,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByProgrammaticScroll) {
scrollbar_controller_->DidScrollUpdate();
EXPECT_FALSE(did_request_animate_);
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
time += base::TimeDelta::FromSeconds(2);
@@ -1736,7 +1732,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, AwakenByProgrammaticScroll) {
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate();
- start_fade_.Run();
+ std::move(start_fade_).Run();
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_TRUE(did_request_animate_);
@@ -1766,7 +1762,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest,
base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate();
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
scrollbar_controller_->Animate(time);
@@ -1806,7 +1802,7 @@ TEST_F(ScrollbarAnimationControllerAndroidTest,
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate();
EXPECT_FALSE(did_request_animate_);
- start_fade_.Run();
+ std::move(start_fade_).Run();
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
scrollbar_controller_->Animate(time);
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 08ba96d79b5..a08e6aa8838 100644
--- a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
+++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
@@ -42,12 +42,10 @@ class MockSingleScrollbarAnimationControllerClient
}
MOCK_METHOD2(PostDelayedScrollbarAnimationTask,
- void(const base::Closure& start_fade, base::TimeDelta delay));
+ void(base::OnceClosure start_fade, base::TimeDelta delay));
MOCK_METHOD0(SetNeedsRedrawForScrollbarAnimation, void());
MOCK_METHOD0(SetNeedsAnimateForScrollbarAnimation, void());
MOCK_METHOD0(DidChangeScrollbarVisibility, void());
- MOCK_METHOD0(start_fade, base::Closure());
- MOCK_METHOD0(delay, base::TimeDelta());
private:
LayerTreeHostImpl* host_impl_;
@@ -90,7 +88,7 @@ class SingleScrollbarAnimationControllerThinningTest : public testing::Test {
host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip));
scrollbar_layer_->SetBounds(gfx::Size(kThumbThickness, kTrackLength));
- scrollbar_layer_->SetPosition(gfx::PointF(90, 0));
+ scrollbar_layer_->test_properties()->position = gfx::PointF(90, 0);
scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id());
scrollbar_layer_->test_properties()->opacity_can_animate = true;
clip_layer_->SetBounds(gfx::Size(100, 100));
diff --git a/chromium/cc/input/snap_selection_strategy.cc b/chromium/cc/input/snap_selection_strategy.cc
index ce0f2655ecf..8803cce22f1 100644
--- a/chromium/cc/input/snap_selection_strategy.cc
+++ b/chromium/cc/input/snap_selection_strategy.cc
@@ -29,6 +29,10 @@ SnapSelectionStrategy::CreateForEndAndDirection(
displacement);
}
+bool SnapSelectionStrategy::HasIntendedDirection() const {
+ return true;
+}
+
bool EndPositionStrategy::ShouldSnapOnX() const {
return scrolled_x_;
}
@@ -52,6 +56,10 @@ bool EndPositionStrategy::IsValidSnapPosition(SearchAxis axis,
(scrolled_y_ && axis == SearchAxis::kY);
}
+bool EndPositionStrategy::HasIntendedDirection() const {
+ return false;
+}
+
const base::Optional<SnapSearchResult>& EndPositionStrategy::PickBestResult(
const base::Optional<SnapSearchResult>& closest,
const base::Optional<SnapSearchResult>& covering) const {
diff --git a/chromium/cc/input/snap_selection_strategy.h b/chromium/cc/input/snap_selection_strategy.h
index cebc63e96b5..ef6b00baa7a 100644
--- a/chromium/cc/input/snap_selection_strategy.h
+++ b/chromium/cc/input/snap_selection_strategy.h
@@ -48,6 +48,8 @@ class CC_EXPORT SnapSelectionStrategy {
// valid for the current axis.
virtual bool IsValidSnapPosition(SearchAxis axis, float position) const = 0;
+ virtual bool HasIntendedDirection() const;
+
// Returns the best result according to snap selection strategy. This method
// is called at the end of selection process to make the final decision.
//
@@ -91,6 +93,7 @@ class EndPositionStrategy : public SnapSelectionStrategy {
gfx::ScrollOffset base_position() const override;
bool IsValidSnapPosition(SearchAxis axis, float position) const override;
+ bool HasIntendedDirection() const override;
const base::Optional<SnapSearchResult>& PickBestResult(
const base::Optional<SnapSearchResult>& closest,
diff --git a/chromium/cc/layers/append_quads_data.h b/chromium/cc/layers/append_quads_data.h
index d207cf28626..a681a97b489 100644
--- a/chromium/cc/layers/append_quads_data.h
+++ b/chromium/cc/layers/append_quads_data.h
@@ -25,12 +25,6 @@ class CC_EXPORT AppendQuadsData {
int64_t visible_layer_area = 0;
int64_t approximated_visible_content_area = 0;
- // TODO(enne): These are temporary to evaluate mask layer optimizations.
- int num_mask_layers = 0;
- int num_rounded_corner_mask_layers = 0;
- int64_t visible_mask_layer_area = 0;
- int64_t visible_rounded_corner_mask_layer_area = 0;
-
// This is total of the following two areas.
int64_t checkerboarded_visible_content_area = 0;
// This is the area outside interest rect.
diff --git a/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc b/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc
index 7f79eb9b574..26bd15d973f 100644
--- a/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc
+++ b/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc
@@ -32,7 +32,6 @@ class TestLayerImpl : public LayerImpl {
explicit TestLayerImpl(LayerTreeImpl* tree, int id)
: LayerImpl(tree, id), count_(-1) {
SetBounds(gfx::Size(100, 100));
- SetPosition(gfx::PointF());
SetDrawsContent(true);
}
};
diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc
index 1837ed16487..6d7044e2703 100644
--- a/chromium/cc/layers/heads_up_display_layer.cc
+++ b/chromium/cc/layers/heads_up_display_layer.cc
@@ -46,8 +46,10 @@ void HeadsUpDisplayLayer::UpdateLocationAndSize(
// FPS meter), use a fixed size.
constexpr int kDefaultHUDSize = 256;
bounds.SetSize(kDefaultHUDSize, kDefaultHUDSize);
- matrix.Translate(device_viewport_in_layout_pixels.width() - kDefaultHUDSize,
- 0.0);
+ // Put the HUD on the top-left side instead of the top-right side because
+ // the HUD sometimes can be drawn on out of the screen when it works on
+ // embedded devices.
+ matrix.Translate(0.0, 0.0);
}
SetBounds(bounds);
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index cb7ee65c26e..5c1e31565d9 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -32,7 +32,6 @@
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/gpu/texture_allocation.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
@@ -358,11 +357,9 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
constexpr GLuint background_color = SkColorSetARGB(0, 0, 0, 0);
constexpr GLuint msaa_sample_count = -1;
constexpr bool can_use_lcd_text = true;
- const auto pixel_config = viz::ResourceFormatToClosestSkColorType(
- true /* gpu_compositing */, pool_resource.format());
ri->BeginRasterCHROMIUM(background_color, msaa_sample_count,
- can_use_lcd_text, pixel_config,
- raster_color_space_, backing->mailbox.name);
+ can_use_lcd_text, raster_color_space_,
+ backing->mailbox.name);
gfx::Vector2dF post_translate(0.f, 0.f);
DummyImageProvider image_provider;
ri->RasterCHROMIUM(display_item_list.get(), &image_provider, size,
@@ -582,33 +579,32 @@ void HeadsUpDisplayLayerImpl::DrawHudContents(PaintCanvas* canvas) {
}
void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
- PaintFlags* flags,
+ const PaintFlags& flags,
const std::string& text,
TextAlign align,
int size,
int x,
int y) const {
DCHECK(typeface_.get());
- flags->setAntiAlias(true);
- flags->setTextSize(size);
- flags->setTypeface(typeface_);
+ SkFont font(typeface_, size);
+ font.setEdging(SkFont::Edging::kAntiAlias);
+
if (align == TextAlign::kCenter) {
- auto width = flags->ToSkPaint().measureText(text.c_str(), text.length());
+ auto width =
+ font.measureText(text.c_str(), text.length(), kUTF8_SkTextEncoding);
x -= width * 0.5f;
} else if (align == TextAlign::kRight) {
- auto width = flags->ToSkPaint().measureText(text.c_str(), text.length());
+ auto width =
+ font.measureText(text.c_str(), text.length(), kUTF8_SkTextEncoding);
x -= width;
}
- auto sk_paint = flags->ToSkPaint();
- auto text_blob = SkTextBlob::MakeFromText(
- text.c_str(), text.length(),
- SkFont(sk_paint.refTypeface(), sk_paint.getTextSize()));
- canvas->drawTextBlob(std::move(text_blob), x, y, *flags);
+ canvas->drawTextBlob(
+ SkTextBlob::MakeFromText(text.c_str(), text.length(), font), x, y, flags);
}
void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
- PaintFlags* flags,
+ const PaintFlags& flags,
const std::string& text,
TextAlign align,
int size,
@@ -665,7 +661,7 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
int width = kGraphWidth + kHistogramWidth + 4 * kPadding;
int height = kTitleFontHeight + kFontHeight + kGraphHeight + 6 * kPadding + 2;
- int left = bounds().width() - width - right;
+ int left = 0;
SkRect area = SkRect::MakeXYWH(left, top, width, height);
PaintFlags flags;
@@ -693,13 +689,13 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
VLOG(1) << value_text;
flags.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &flags, title, TextAlign::kLeft, kTitleFontHeight,
+ DrawText(canvas, flags, title, TextAlign::kLeft, kTitleFontHeight,
title_bounds.left(), title_bounds.bottom());
flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
- DrawText(canvas, &flags, value_text, TextAlign::kLeft, kFontHeight,
+ DrawText(canvas, flags, value_text, TextAlign::kLeft, kFontHeight,
text_bounds.left(), text_bounds.bottom());
- DrawText(canvas, &flags, min_max_text, TextAlign::kRight, kFontHeight,
+ DrawText(canvas, flags, min_max_text, TextAlign::kRight, kFontHeight,
text_bounds.right(), text_bounds.bottom());
DrawGraphLines(canvas, &flags, graph_bounds, fps_graph_);
@@ -786,7 +782,7 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(PaintCanvas* canvas,
const int kFontHeight = 12;
const int height = kTitleFontHeight + 2 * kFontHeight + 5 * kPadding;
- const int left = bounds().width() - width - right;
+ const int left = 0;
const SkRect area = SkRect::MakeXYWH(left, top, width, height);
const double kMegabyte = 1024.0 * 1024.0;
@@ -802,20 +798,20 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(PaintCanvas* canvas,
top + 2 * kPadding + 3 * kFontHeight);
flags.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &flags, "GPU Memory", TextAlign::kLeft, kTitleFontHeight,
+ DrawText(canvas, flags, "GPU Memory", TextAlign::kLeft, kTitleFontHeight,
title_pos);
flags.setColor(DebugColors::MemoryDisplayTextColor());
std::string text = base::StringPrintf(
"%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte);
- DrawText(canvas, &flags, text, TextAlign::kRight, kFontHeight, stat1_pos);
+ DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat1_pos);
if (!memory_entry_.had_enough_memory)
flags.setColor(SK_ColorRED);
text = base::StringPrintf("%6.1f MB max ",
memory_entry_.total_budget_in_bytes / kMegabyte);
- DrawText(canvas, &flags, text, TextAlign::kRight, kFontHeight, stat2_pos);
+ DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat2_pos);
// Draw memory graph.
int length = 2 * kFontHeight + kPadding + 12;
@@ -895,7 +891,7 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
const int kFontHeight = 12;
const int height = kTitleFontHeight + kFontHeight + 3 * kPadding;
- const int left = bounds().width() - width - right;
+ const int left = 0;
const SkRect area = SkRect::MakeXYWH(left, top, width, height);
PaintFlags flags;
@@ -904,10 +900,10 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
SkPoint gpu_status_pos = SkPoint::Make(left + width - kPadding,
top + 2 * kFontHeight + 2 * kPadding);
flags.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &flags, "GPU Raster", TextAlign::kLeft, kTitleFontHeight,
+ DrawText(canvas, flags, "GPU Raster", TextAlign::kLeft, kTitleFontHeight,
left + kPadding, top + kFontHeight + kPadding);
flags.setColor(color);
- DrawText(canvas, &flags, status, TextAlign::kRight, kFontHeight,
+ DrawText(canvas, flags, status, TextAlign::kRight, kFontHeight,
gpu_status_pos);
return area;
@@ -950,19 +946,17 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect(
canvas->translate(sk_clip_rect.x(), sk_clip_rect.y());
PaintFlags label_flags;
- label_flags.setTextSize(kFontHeight);
- label_flags.setTypeface(typeface_);
label_flags.setColor(stroke_color);
+ SkFont label_font(typeface_, kFontHeight);
- const SkScalar label_text_width = label_flags.ToSkPaint().measureText(
- label_text.c_str(), label_text.length());
+ const SkScalar label_text_width = label_font.measureText(
+ label_text.c_str(), label_text.length(), kUTF8_SkTextEncoding);
canvas->drawRect(SkRect::MakeWH(label_text_width + 2 * kPadding,
kFontHeight + 2 * kPadding),
label_flags);
- label_flags.setAntiAlias(true);
label_flags.setColor(SkColorSetARGB(255, 50, 50, 50));
- DrawText(canvas, &label_flags, label_text, TextAlign::kLeft, kFontHeight,
+ DrawText(canvas, label_flags, label_text, TextAlign::kLeft, kFontHeight,
kPadding, kFontHeight * 0.8f + kPadding);
canvas->restore();
}
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h
index 9a97daea2d4..352b71bdaf2 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.h
+++ b/chromium/cc/layers/heads_up_display_layer_impl.h
@@ -98,14 +98,14 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
void UpdateHudContents();
void DrawHudContents(PaintCanvas* canvas);
void DrawText(PaintCanvas* canvas,
- PaintFlags* flags,
+ const PaintFlags& flags,
const std::string& text,
TextAlign align,
int size,
int x,
int y) const;
void DrawText(PaintCanvas* canvas,
- PaintFlags* flags,
+ const PaintFlags& flags,
const std::string& text,
TextAlign align,
int size,
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index f976fa6e1aa..18dc2f32a64 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -77,6 +77,7 @@ scoped_refptr<Layer> Layer::Create() {
Layer::Layer()
: ignore_set_needs_commit_(false),
+ paint_count_(0),
parent_(nullptr),
layer_tree_host_(nullptr),
// Layer IDs start from 1.
@@ -96,9 +97,10 @@ Layer::Layer()
may_contain_video_(false),
needs_show_scrollbars_(false),
has_transform_node_(false),
- is_rounded_corner_mask_(false),
subtree_has_copy_request_(false),
- safe_opaque_background_color_(0) {}
+ safe_opaque_background_color_(0),
+ compositing_reasons_(0),
+ owner_node_id_(0) {}
Layer::~Layer() {
// Our parent should be holding a reference to us so there should be no
@@ -124,9 +126,12 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
bool property_tree_indices_invalid = false;
if (layer_tree_host_) {
+ bool should_register_element =
+ inputs_.element_id &&
+ (!layer_tree_host_->IsUsingLayerLists() || inputs_.scrollable);
layer_tree_host_->property_trees()->needs_rebuild = true;
layer_tree_host_->UnregisterLayer(this);
- if (inputs_.element_id) {
+ if (should_register_element) {
layer_tree_host_->UnregisterElement(inputs_.element_id,
ElementListType::ACTIVE);
}
@@ -134,9 +139,12 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
property_tree_indices_invalid = true;
}
if (host) {
+ bool should_register_element =
+ inputs_.element_id &&
+ (!host->IsUsingLayerLists() || inputs_.scrollable);
host->property_trees()->needs_rebuild = true;
host->RegisterLayer(this);
- if (inputs_.element_id)
+ if (should_register_element)
host->RegisterElement(inputs_.element_id, ElementListType::ACTIVE, this);
if (!host->IsUsingLayerLists())
property_tree_indices_invalid = true;
@@ -555,6 +563,10 @@ void Layer::SetBackdropFilters(const FilterOperations& filters) {
SetNeedsCommit();
}
+void Layer::SetBackdropFilterBounds(const gfx::RectF& backdrop_filter_bounds) {
+ inputs_.backdrop_filter_bounds = backdrop_filter_bounds;
+}
+
void Layer::SetBackdropFilterQuality(const float quality) {
inputs_.backdrop_filter_quality = quality;
}
@@ -912,6 +924,12 @@ void Layer::SetScrollable(const gfx::Size& bounds) {
if (!layer_tree_host_)
return;
+ if (layer_tree_host_->IsUsingLayerLists() && !was_scrollable &&
+ inputs_.element_id) {
+ layer_tree_host_->RegisterElement(inputs_.element_id,
+ ElementListType::ACTIVE, this);
+ }
+
if (!layer_tree_host_->IsUsingLayerLists()) {
auto& scroll_tree = layer_tree_host_->property_trees()->scroll_tree;
auto* scroll_node = scroll_tree.Node(scroll_tree_index_);
@@ -955,10 +973,50 @@ void Layer::SetUserScrollable(bool horizontal, bool vertical) {
SetNeedsCommit();
}
+bool Layer::GetUserScrollableHorizontal() const {
+ // When using layer lists, horizontal scrollability is stored in scroll nodes.
+ if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) {
+ auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
+ if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_))
+ return scroll_node->user_scrollable_horizontal;
+ return false;
+ }
+ return inputs_.user_scrollable_horizontal;
+}
+
+bool Layer::GetUserScrollableVertical() const {
+ // When using layer lists, vertical scrollability is stored in scroll nodes.
+ if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) {
+ auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
+ if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_))
+ return scroll_node->user_scrollable_vertical;
+ return false;
+ }
+ return inputs_.user_scrollable_vertical;
+}
+
+uint32_t Layer::GetMainThreadScrollingReasons() const {
+ // When using layer lists, main thread scrolling reasons are stored in scroll
+ // nodes.
+ if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) {
+ auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
+ if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_))
+ return scroll_node->main_thread_scrolling_reasons;
+ return MainThreadScrollingReason::kNotScrollingOnMain;
+ }
+ return inputs_.main_thread_scrolling_reasons;
+}
+
void Layer::AddMainThreadScrollingReasons(
uint32_t main_thread_scrolling_reasons) {
DCHECK(IsPropertyChangeAllowed());
DCHECK(main_thread_scrolling_reasons);
+
+ // When layer lists are used, the main thread scrolling reasons should be set
+ // on property tree nodes directly.
+ // TODO(pdr): Uncomment this check when https://crbug.com/919969 is fixed.
+ // DCHECK(!layer_tree_host() || !layer_tree_host()->IsUsingLayerLists());
+
// Layer should only see non-transient scrolling reasons. Transient scrolling
// reasons are computed per hit test.
DCHECK(MainThreadScrollingReason::MainThreadCanSetScrollReasons(
@@ -1141,6 +1199,24 @@ void Layer::SetShouldFlattenTransform(bool should_flatten) {
SetSubtreePropertyChanged();
}
+std::string Layer::ToString() const {
+ return base::StringPrintf(
+ "layer_id: %d\n"
+ " Bounds: %s\n"
+ " ElementId: %s\n"
+ " OffsetToTransformParent: %s\n"
+ " Position: %s\n"
+ " scrollable: %d\n"
+ " clip_tree_index: %d\n"
+ " effect_tree_index: %d\n"
+ " scroll_tree_index: %d\n"
+ " transform_tree_index: %d\n",
+ id(), bounds().ToString().c_str(), element_id().ToString().c_str(),
+ offset_to_transform_parent().ToString().c_str(),
+ position().ToString().c_str(), scrollable(), clip_tree_index(),
+ effect_tree_index(), scroll_tree_index(), transform_tree_index());
+}
+
void Layer::SetUseParentBackfaceVisibility(bool use) {
DCHECK(IsPropertyChangeAllowed());
if (inputs_.use_parent_backface_visibility == use)
@@ -1262,7 +1338,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
// deprecated. http://crbug.com/709137
layer->SetElementId(inputs_.element_id);
layer->SetHasTransformNode(has_transform_node_);
- layer->set_is_rounded_corner_mask(is_rounded_corner_mask_);
layer->SetBackgroundColor(inputs_.background_color);
layer->SetSafeOpaqueBackgroundColor(safe_opaque_background_color_);
layer->SetBounds(inputs_.bounds);
@@ -1281,8 +1356,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->NoteLayerPropertyChanged();
layer->set_may_contain_video(may_contain_video_);
layer->SetMasksToBounds(inputs_.masks_to_bounds);
- layer->set_main_thread_scrolling_reasons(
- inputs_.main_thread_scrolling_reasons);
layer->SetNonFastScrollableRegion(inputs_.non_fast_scrollable_region);
layer->SetTouchActionRegion(inputs_.touch_action_region);
// TODO(sunxd): Pass the correct region for wheel event handlers, see
@@ -1297,7 +1370,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->SetWheelEventHandlerRegion(Region());
}
layer->SetContentsOpaque(inputs_.contents_opaque);
- layer->SetPosition(inputs_.position);
layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree(
should_flatten_screen_space_transform_from_property_tree_);
layer->SetUseParentBackfaceVisibility(inputs_.use_parent_backface_visibility);
@@ -1509,14 +1581,17 @@ void Layer::SetElementId(ElementId id) {
return;
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "Layer::SetElementId",
"element", id.AsValue().release());
- if (inputs_.element_id && layer_tree_host()) {
+ bool should_register_element =
+ layer_tree_host() &&
+ (!layer_tree_host()->IsUsingLayerLists() || inputs_.scrollable);
+ if (should_register_element && inputs_.element_id) {
layer_tree_host_->UnregisterElement(inputs_.element_id,
ElementListType::ACTIVE);
}
inputs_.element_id = id;
- if (inputs_.element_id && layer_tree_host()) {
+ if (should_register_element && inputs_.element_id) {
layer_tree_host_->RegisterElement(inputs_.element_id,
ElementListType::ACTIVE, this);
}
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index b90f4559bc0..286a72eec82 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -163,7 +163,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// specified in layer space, which excludes device scale and page scale
// factors, and ignoring transforms for this layer or ancestor layers. The
// root layer's position is not used as it always appears at the origin of
- // the viewport.
+ // the viewport. When property trees are built by cc (when IsUsingLayerLists
+ // is false), position is used to update |offset_to_transform_parent|.
void SetPosition(const gfx::PointF& position);
const gfx::PointF& position() const { return inputs_.position; }
@@ -276,13 +277,18 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
gfx::PointF filters_origin() const { return inputs_.filters_origin; }
// Set or get the list of filters that should be applied to the content this
- // layer and its subtree will be drawn into. The effect is clipped to only
- // apply directly behind this layer and its subtree.
+ // layer and its subtree will be drawn into. The effect is clipped by
+ // backdrop_filter_bounds.
void SetBackdropFilters(const FilterOperations& filters);
const FilterOperations& backdrop_filters() const {
return inputs_.backdrop_filters;
}
+ void SetBackdropFilterBounds(const gfx::RectF& backdrop_filter_bounds);
+ const gfx::RectF& backdrop_filter_bounds() const {
+ return inputs_.backdrop_filter_bounds;
+ }
+
void SetBackdropFilterQuality(const float quality);
float backdrop_filter_quality() const {
return inputs_.backdrop_filter_quality;
@@ -404,7 +410,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
bool is_scrollbar() const { return inputs_.is_scrollbar; }
// Set or get if this layer is able to be scrolled along each axis. These are
- // independant of the scrollable state, or size of the scrollable area
+ // independent of the scrollable state, or size of the scrollable area
// specified in SetScrollable(), as these may be enabled or disabled
// dynamically, while SetScrollable() defines what would be possible if these
// are enabled.
@@ -413,12 +419,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// the scrollbars will be shown when the scroll offset changes if these are
// set to true.
void SetUserScrollable(bool horizontal, bool vertical);
- bool user_scrollable_horizontal() const {
- return inputs_.user_scrollable_horizontal;
- }
- bool user_scrollable_vertical() const {
- return inputs_.user_scrollable_vertical;
- }
+ bool GetUserScrollableHorizontal() const;
+ bool GetUserScrollableVertical() const;
// Set or get if this layer is able to be scrolled on the compositor thread.
// This only applies for layers that are marked as scrollable, not for layers
@@ -431,9 +433,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
void AddMainThreadScrollingReasons(uint32_t main_thread_scrolling_reasons);
void ClearMainThreadScrollingReasons(
uint32_t main_thread_scrolling_reasons_to_clear);
- uint32_t main_thread_scrolling_reasons() const {
- return inputs_.main_thread_scrolling_reasons;
- }
+ uint32_t GetMainThreadScrollingReasons() const;
// Set or get an area of this layer within which initiating a scroll can not
// be done from the compositor thread. Within this area, if the user attempts
@@ -709,10 +709,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
void SetEffectTreeIndex(int index);
void SetScrollTreeIndex(int index);
- // Internal to property tree construction. Set or get the position of this
- // layer relative to the origin after transforming according to this layer's
- // index into the transform tree. This translation is appended to the
- // transform that comes from the transform tree for this layer.
+ // The position of this layer after transforming by the layer's transform
+ // node. When property trees are built by cc (when IsUsingLayerLists is false)
+ // this is set by property_tree_builder.cc.
void SetOffsetToTransformParent(gfx::Vector2dF offset);
gfx::Vector2dF offset_to_transform_parent() const {
return offset_to_transform_parent_;
@@ -764,9 +763,33 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
return should_flatten_screen_space_transform_from_property_tree_;
}
- void set_is_rounded_corner_mask(bool rounded) {
- is_rounded_corner_mask_ = rounded;
+ std::string ToString() const;
+
+ // Called when a property has been modified in a way that the layer knows
+ // immediately that a commit is required. This implies SetNeedsPushProperties
+ // to push that property.
+ // This is public, so that it can be called directly when needed, for example
+ // in PropertyTreeManager when handling scroll offsets.
+ void SetNeedsCommit();
+
+ // The following data are for profiling and debugging. They will be displayed
+ // e.g. in the Layers panel of DevTools.
+
+ // The compositing reasons of the layer. The values are defined in
+ // third_party/blink/renderer/platform/graphics/compositing_reasons.h.
+ void set_compositing_reasons(uint64_t compositing_reasons) {
+ compositing_reasons_ = compositing_reasons;
}
+ uint64_t compositing_reasons() const { return compositing_reasons_; }
+
+ // The id of the DOM node that owns this layer.
+ void set_owner_node_id(int node_id) { owner_node_id_ = node_id; }
+ int owner_node_id() const { return owner_node_id_; }
+
+ // How many times this layer has been repainted.
+ int paint_count() const { return paint_count_; }
+
+ // End of data for profiling and debugging.
protected:
friend class LayerImpl;
@@ -776,11 +799,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
virtual ~Layer();
// These SetNeeds functions are in order of severity of update:
- //
- // Called when a property has been modified in a way that the layer knows
- // immediately that a commit is required. This implies SetNeedsPushProperties
- // to push that property.
- void SetNeedsCommit();
+
+ // See SetNeedsCommit() above - it belongs here in the order of severity.
// Called when there's been a change in layer structure. Implies
// SetNeedsCommit and property tree rebuld, but not SetNeedsPushProperties
@@ -813,6 +833,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// will be handled implicitly after the update completes.
bool ignore_set_needs_commit_;
+ int paint_count_;
+
private:
friend class base::RefCounted<Layer>;
friend class LayerTreeHostCommon;
@@ -851,9 +873,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
void UpdateScrollOffset(const gfx::ScrollOffset&);
// Encapsulates all data, callbacks or interfaces received from the embedder.
- // TODO(khushalsagar): This is only valid when PropertyTrees are built
- // internally in cc. Update this for the SPv2 path where blink generates
- // PropertyTrees.
struct Inputs {
explicit Inputs(int layer_id);
~Inputs();
@@ -901,6 +920,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
FilterOperations filters;
FilterOperations backdrop_filters;
+ gfx::RectF backdrop_filter_bounds;
gfx::PointF filters_origin;
float backdrop_filter_quality;
@@ -988,10 +1008,11 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
bool may_contain_video_ : 1;
bool needs_show_scrollbars_ : 1;
bool has_transform_node_ : 1;
- bool is_rounded_corner_mask_ : 1;
// This value is valid only when LayerTreeHost::has_copy_request() is true
bool subtree_has_copy_request_ : 1;
SkColor safe_opaque_background_color_;
+ uint64_t compositing_reasons_;
+ int owner_node_id_;
std::unique_ptr<std::set<Layer*>> clip_children_;
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 3a1f4e9aadf..7d07aa39ad5 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -11,6 +11,7 @@
#include <utility>
#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
@@ -20,7 +21,6 @@
#include "cc/benchmarks/micro_benchmark_impl.h"
#include "cc/debug/debug_colors.h"
#include "cc/debug/layer_tree_debug_state.h"
-#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/input/scroll_state.h"
#include "cc/layers/layer.h"
#include "cc/trees/clip_node.h"
@@ -52,8 +52,6 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
layer_tree_impl_(tree_impl),
will_always_push_properties_(will_always_push_properties),
test_properties_(nullptr),
- main_thread_scrolling_reasons_(
- MainThreadScrollingReason::kNotScrollingOnMain),
scrollable_(false),
should_flatten_screen_space_transform_from_property_tree_(false),
layer_property_changed_not_from_property_trees_(false),
@@ -82,8 +80,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
scrollbars_hidden_(false),
needs_show_scrollbars_(false),
raster_even_if_not_drawn_(false),
- has_transform_node_(false),
- is_rounded_corner_mask_(false) {
+ has_transform_node_(false) {
DCHECK_GT(layer_id_, 0);
DCHECK(layer_tree_impl_);
@@ -308,9 +305,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->SetElementId(element_id_);
layer->has_transform_node_ = has_transform_node_;
- layer->is_rounded_corner_mask_ = is_rounded_corner_mask_;
layer->offset_to_transform_parent_ = offset_to_transform_parent_;
- layer->main_thread_scrolling_reasons_ = main_thread_scrolling_reasons_;
layer->should_flatten_screen_space_transform_from_property_tree_ =
should_flatten_screen_space_transform_from_property_tree_;
layer->masks_to_bounds_ = masks_to_bounds_;
@@ -326,7 +321,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->wheel_event_handler_region_ = wheel_event_handler_region_;
layer->background_color_ = background_color_;
layer->safe_opaque_background_color_ = safe_opaque_background_color_;
- layer->position_ = position_;
layer->transform_tree_index_ = transform_tree_index_;
layer->effect_tree_index_ = effect_tree_index_;
layer->clip_tree_index_ = clip_tree_index_;
@@ -382,9 +376,11 @@ void LayerImpl::SetIsResizedByBrowserControls(bool resized) {
is_resized_by_browser_controls_ = resized;
}
-std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() {
+std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() const {
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue);
result->SetInteger("LayerId", id());
+ if (element_id())
+ result->SetString("ElementId", element_id().ToString());
result->SetString("LayerType", LayerTypeAsString());
auto list = std::make_unique<base::ListValue>();
@@ -393,11 +389,12 @@ std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() {
result->Set("Bounds", std::move(list));
list = std::make_unique<base::ListValue>();
- list->AppendDouble(position_.x());
- list->AppendDouble(position_.y());
- result->Set("Position", std::move(list));
+ list->AppendInteger(offset_to_transform_parent().x());
+ list->AppendInteger(offset_to_transform_parent().y());
+ result->Set("OffsetToTransformParent", std::move(list));
- const gfx::Transform& gfx_transform = test_properties()->transform;
+ const gfx::Transform& gfx_transform =
+ const_cast<LayerImpl*>(this)->test_properties()->transform;
double transform[16];
gfx_transform.matrix().asColMajord(transform);
list = std::make_unique<base::ListValue>();
@@ -409,11 +406,13 @@ std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() {
result->SetBoolean("HitTestableWithoutDrawsContent",
hit_testable_without_draws_content_);
result->SetBoolean("Is3dSorted", Is3dSorted());
- result->SetDouble("OPACITY", Opacity());
+ result->SetDouble("Opacity", Opacity());
result->SetBoolean("ContentsOpaque", contents_opaque_);
- result->SetString(
- "mainThreadScrollingReasons",
- MainThreadScrollingReason::AsText(main_thread_scrolling_reasons_));
+
+ result->SetInteger("transform_tree_index", transform_tree_index());
+ result->SetInteger("clip_tree_index", clip_tree_index());
+ result->SetInteger("effect_tree_index", effect_tree_index());
+ result->SetInteger("scroll_tree_index", scroll_tree_index());
if (scrollable())
result->SetBoolean("Scrollable", true);
@@ -606,6 +605,15 @@ void LayerImpl::SetHitTestableWithoutDrawsContent(bool should_hit_test) {
NoteLayerPropertyChanged();
}
+bool LayerImpl::ShouldHitTest() const {
+ bool should_hit_test = draws_content_;
+ if (GetEffectTree().Node(effect_tree_index()))
+ should_hit_test &=
+ !GetEffectTree().Node(effect_tree_index())->subtree_hidden;
+ should_hit_test |= hit_testable_without_draws_content_;
+ return should_hit_test;
+}
+
void LayerImpl::SetBackgroundColor(SkColor background_color) {
if (background_color_ == background_color)
return;
@@ -654,10 +662,6 @@ void LayerImpl::SetElementId(ElementId element_id) {
layer_tree_impl_->AddToElementLayerList(element_id_, this);
}
-void LayerImpl::SetPosition(const gfx::PointF& position) {
- position_ = position;
-}
-
void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
update_rect_ = update_rect;
}
@@ -738,7 +742,8 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetDouble("opacity", Opacity());
- MathUtil::AddToTracedValue("position", position_, state);
+ // For backward-compatibility of DevTools front-end.
+ MathUtil::AddToTracedValue("position", gfx::PointF(), state);
state->SetInteger("transform_tree_index", transform_tree_index());
state->SetInteger("clip_tree_index", clip_tree_index());
@@ -785,13 +790,20 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetBoolean("has_will_change_transform_hint",
has_will_change_transform_hint());
- MainThreadScrollingReason::AddToTracedValue(main_thread_scrolling_reasons_,
- *state);
-
if (debug_info_)
state->SetValue("debug_info", debug_info_);
}
+std::string LayerImpl::ToString() const {
+ std::string str;
+ base::JSONWriter::WriteWithOptions(
+ *LayerAsJson(),
+ base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &str);
+ return str;
+}
+
size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h
index bdfd63a5e70..837b7e0ac47 100644
--- a/chromium/cc/layers/layer_impl.h
+++ b/chromium/cc/layers/layer_impl.h
@@ -167,9 +167,7 @@ class CC_EXPORT LayerImpl {
// True if either the layer draws content or has been marked as hit testable
// without draws_content.
- bool should_hit_test() const {
- return draws_content_ || hit_testable_without_draws_content_;
- }
+ bool ShouldHitTest() const;
LayerImplTestProperties* test_properties() {
if (!test_properties_)
@@ -196,9 +194,6 @@ class CC_EXPORT LayerImpl {
void SetElementId(ElementId element_id);
ElementId element_id() const { return element_id_; }
- void SetPosition(const gfx::PointF& position);
- gfx::PointF position() const { return position_; }
-
bool IsAffectedByPageScale() const;
bool Is3dSorted() const { return GetSortingContextId() != 0; }
@@ -309,14 +304,6 @@ class CC_EXPORT LayerImpl {
gfx::Size scroll_container_bounds() const { return scroll_container_bounds_; }
bool scrollable() const { return scrollable_; }
- void set_main_thread_scrolling_reasons(
- uint32_t main_thread_scrolling_reasons) {
- main_thread_scrolling_reasons_ = main_thread_scrolling_reasons;
- }
- uint32_t main_thread_scrolling_reasons() const {
- return main_thread_scrolling_reasons_;
- }
-
void SetNonFastScrollableRegion(const Region& region) {
non_fast_scrollable_region_ = region;
}
@@ -348,7 +335,7 @@ class CC_EXPORT LayerImpl {
void AddDamageRect(const gfx::Rect& damage_rect);
const gfx::Rect& damage_rect() const { return damage_rect_; }
- virtual std::unique_ptr<base::DictionaryValue> LayerAsJson();
+ virtual std::unique_ptr<base::DictionaryValue> LayerAsJson() const;
// TODO(pdr): This should be removed because there is no longer a tree
// of layers, only a list.
std::unique_ptr<base::DictionaryValue> LayerTreeAsJson();
@@ -398,6 +385,7 @@ class CC_EXPORT LayerImpl {
virtual void GetAllPrioritizedTilesForTracing(
std::vector<PrioritizedTile>* prioritized_tiles) const;
virtual void AsValueInto(base::trace_event::TracedValue* dict) const;
+ std::string ToString() const;
virtual size_t GPUMemoryUsageInBytes() const;
@@ -466,11 +454,6 @@ class CC_EXPORT LayerImpl {
// TODO(sunxd): Remove this function and replace it with visitor pattern.
virtual bool is_surface_layer() const;
- void set_is_rounded_corner_mask(bool rounded) {
- is_rounded_corner_mask_ = rounded;
- }
- bool is_rounded_corner_mask() const { return is_rounded_corner_mask_; }
-
protected:
// When |will_always_push_properties| is true, the layer will not itself set
// its SetNeedsPushProperties() state, as it expects to be always pushed to
@@ -510,7 +493,6 @@ class CC_EXPORT LayerImpl {
gfx::Size bounds_;
gfx::Vector2dF offset_to_transform_parent_;
- uint32_t main_thread_scrolling_reasons_;
// Size of the scroll container that this layer scrolls in.
gfx::Size scroll_container_bounds_;
@@ -558,8 +540,6 @@ class CC_EXPORT LayerImpl {
SkColor background_color_;
SkColor safe_opaque_background_color_;
- gfx::PointF position_;
-
int transform_tree_index_;
int effect_tree_index_;
int clip_tree_index_;
@@ -612,7 +592,6 @@ class CC_EXPORT LayerImpl {
bool raster_even_if_not_drawn_ : 1;
bool has_transform_node_ : 1;
- bool is_rounded_corner_mask_ : 1;
DISALLOW_COPY_AND_ASSIGN(LayerImpl);
};
diff --git a/chromium/cc/layers/layer_impl_test_properties.h b/chromium/cc/layers/layer_impl_test_properties.h
index c931d45d95f..9f0d688a8ee 100644
--- a/chromium/cc/layers/layer_impl_test_properties.h
+++ b/chromium/cc/layers/layer_impl_test_properties.h
@@ -48,6 +48,7 @@ struct CC_EXPORT LayerImplTestProperties {
float opacity;
FilterOperations filters;
FilterOperations backdrop_filters;
+ gfx::RectF backdrop_filter_bounds;
float backdrop_filter_quality;
gfx::PointF filters_origin;
SkBlendMode blend_mode;
@@ -55,6 +56,7 @@ struct CC_EXPORT LayerImplTestProperties {
LayerStickyPositionConstraint sticky_position_constraint;
gfx::Point3F transform_origin;
gfx::Transform transform;
+ gfx::PointF position;
LayerImpl* scroll_parent;
LayerImpl* clip_parent;
std::unique_ptr<std::set<LayerImpl*>> clip_children;
@@ -62,6 +64,7 @@ struct CC_EXPORT LayerImplTestProperties {
LayerImplList children;
LayerImpl* mask_layer;
LayerImpl* parent;
+ uint32_t main_thread_scrolling_reasons = 0;
bool user_scrollable_horizontal = true;
bool user_scrollable_vertical = true;
OverscrollBehavior overscroll_behavior;
diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc
index cca256cf143..9200f7a7be1 100644
--- a/chromium/cc/layers/layer_impl_unittest.cc
+++ b/chromium/cc/layers/layer_impl_unittest.cc
@@ -115,7 +115,6 @@ TEST(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) {
EXPECT_FALSE(child->LayerPropertyChanged());
EXPECT_FALSE(grand_child->LayerPropertyChanged());
- gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
float arbitrary_number = 0.352f;
gfx::Size arbitrary_size = gfx::Size(111, 222);
gfx::Point arbitrary_point = gfx::Point(333, 444);
@@ -159,8 +158,6 @@ TEST(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) {
// After setting all these properties already, setting to the exact same
// values again should not cause any change.
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true));
- EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
- root->SetPosition(arbitrary_point_f));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetContentsOpaque(true));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(root->bounds()));
@@ -266,7 +263,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting();
DCHECK(host_impl.CanDraw());
- gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
float arbitrary_number = 0.352f;
gfx::Size arbitrary_size = gfx::Size(111, 222);
gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
@@ -325,8 +321,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
layer->NoteLayerPropertyChanged());
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true);
layer->NoteLayerPropertyChanged());
- VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer2->SetPosition(arbitrary_point_f);
- layer->NoteLayerPropertyChanged());
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetBackgroundColor(arbitrary_color));
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
@@ -346,8 +340,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
arbitrary_filters));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
- VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
- layer2->SetPosition(arbitrary_point_f));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetBackgroundColor(arbitrary_color));
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index 1f207f8e3bc..044c5b7dec7 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -877,22 +877,22 @@ TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
EXPECT_SET_NEEDS_COMMIT(1,
test_layer->AddMainThreadScrollingReasons(
MainThreadScrollingReason::kScrollbarScrolling));
- EXPECT_EQ(reasons, test_layer->main_thread_scrolling_reasons());
+ EXPECT_EQ(reasons, test_layer->GetMainThreadScrollingReasons());
// Check that the reasons can be selectively cleared.
EXPECT_SET_NEEDS_COMMIT(
1, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
EXPECT_EQ(reasons_after_clearing,
- test_layer->main_thread_scrolling_reasons());
+ test_layer->GetMainThreadScrollingReasons());
// Check that clearing non-set reasons doesn't set needs commit.
reasons_to_clear = 0;
reasons_to_clear |= MainThreadScrollingReason::kCustomScrollbarScrolling;
- reasons_to_clear |= MainThreadScrollingReason::kPageOverlay;
+ reasons_to_clear |= MainThreadScrollingReason::kFrameOverlay;
EXPECT_SET_NEEDS_COMMIT(
0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
EXPECT_EQ(reasons_after_clearing,
- test_layer->main_thread_scrolling_reasons());
+ test_layer->GetMainThreadScrollingReasons());
// Check that adding an existing condition doesn't set needs commit.
EXPECT_SET_NEEDS_COMMIT(
@@ -1346,7 +1346,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
root_layer->PushPropertiesTo(impl_layer.get());
EXPECT_TRUE(impl_layer->DrawsContent());
EXPECT_FALSE(impl_layer->hit_testable_without_draws_content());
- EXPECT_TRUE(impl_layer->should_hit_test());
+ EXPECT_TRUE(impl_layer->ShouldHitTest());
// A layer that does not draw content and does not hit test without drawing
// content should not be hit testable.
@@ -1354,7 +1354,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
root_layer->PushPropertiesTo(impl_layer.get());
EXPECT_FALSE(impl_layer->DrawsContent());
EXPECT_FALSE(impl_layer->hit_testable_without_draws_content());
- EXPECT_FALSE(impl_layer->should_hit_test());
+ EXPECT_FALSE(impl_layer->ShouldHitTest());
// |SetHitTestableWithoutDrawsContent| should cause a layer to become hit
// testable even though it does not draw content.
@@ -1362,7 +1362,7 @@ TEST_F(LayerTest, PushUpdatesShouldHitTest) {
root_layer->PushPropertiesTo(impl_layer.get());
EXPECT_FALSE(impl_layer->DrawsContent());
EXPECT_TRUE(impl_layer->hit_testable_without_draws_content());
- EXPECT_TRUE(impl_layer->should_hit_test());
+ EXPECT_TRUE(impl_layer->ShouldHitTest());
}
void ReceiveCopyOutputResult(int* result_count,
@@ -1548,20 +1548,51 @@ class LayerTestWithLayerLists : public LayerTest {
}
};
-TEST_F(LayerTestWithLayerLists, LayerTreeHostRegistersElementId) {
+TEST_F(LayerTestWithLayerLists, LayerTreeHostRegistersScrollingElementId) {
+ scoped_refptr<Layer> normal_layer = Layer::Create();
+ scoped_refptr<Layer> scrolling_layer = Layer::Create();
+ scrolling_layer->SetScrollable(gfx::Size(1000, 1000));
+ ElementId normal_element_id = ElementId(2);
+ ElementId scrolling_element_id = ElementId(3);
+ normal_layer->SetElementId(normal_element_id);
+ scrolling_layer->SetElementId(scrolling_element_id);
+
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
+ normal_layer->SetLayerTreeHost(layer_tree_host_.get());
+ scrolling_layer->SetLayerTreeHost(layer_tree_host_.get());
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
+ EXPECT_EQ(scrolling_layer,
+ layer_tree_host_->LayerByElementId(scrolling_element_id));
+
+ normal_layer->SetLayerTreeHost(nullptr);
+ scrolling_layer->SetLayerTreeHost(nullptr);
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
+}
+
+TEST_F(LayerTestWithLayerLists, ChangingScrollableElementIdRegistersElement) {
scoped_refptr<Layer> test_layer = Layer::Create();
+ test_layer->SetScrollable(gfx::Size(1000, 1000));
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ test_layer->SetLayerTreeHost(layer_tree_host_.get());
+
ElementId element_id = ElementId(2);
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
+
+ // Setting the element id should register the layer.
test_layer->SetElementId(element_id);
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));
+ // Unsetting the element id should unregister the layer.
+ test_layer->SetElementId(ElementId());
EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
- test_layer->SetLayerTreeHost(layer_tree_host_.get());
- EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));
test_layer->SetLayerTreeHost(nullptr);
EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}
-TEST_F(LayerTestWithLayerLists, ChangingElementIdRegistersElement) {
+TEST_F(LayerTestWithLayerLists, ChangingScrollableRegistersElement) {
scoped_refptr<Layer> test_layer = Layer::Create();
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
test_layer->SetLayerTreeHost(layer_tree_host_.get());
@@ -1569,9 +1600,15 @@ TEST_F(LayerTestWithLayerLists, ChangingElementIdRegistersElement) {
ElementId element_id = ElementId(2);
EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
- // Setting the element id should register the layer.
+ // Setting the element id commits the element id but should not register
+ // the layer.
test_layer->SetElementId(element_id);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
+
+ // Making the layer scrollable should register it.
+ test_layer->SetScrollable(gfx::Size(1000, 1000));
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));
// Unsetting the element id should unregister the layer.
diff --git a/chromium/cc/layers/nine_patch_layer_impl.cc b/chromium/cc/layers/nine_patch_layer_impl.cc
index 9e6c80055f0..28a92410367 100644
--- a/chromium/cc/layers/nine_patch_layer_impl.cc
+++ b/chromium/cc/layers/nine_patch_layer_impl.cc
@@ -85,7 +85,7 @@ const char* NinePatchLayerImpl::LayerTypeAsString() const {
return "cc::NinePatchLayerImpl";
}
-std::unique_ptr<base::DictionaryValue> NinePatchLayerImpl::LayerAsJson() {
+std::unique_ptr<base::DictionaryValue> NinePatchLayerImpl::LayerAsJson() const {
std::unique_ptr<base::DictionaryValue> result = LayerImpl::LayerAsJson();
quad_generator_.AsJson(result.get());
return result;
diff --git a/chromium/cc/layers/nine_patch_layer_impl.h b/chromium/cc/layers/nine_patch_layer_impl.h
index 4841059fcaf..5e01501d4ee 100644
--- a/chromium/cc/layers/nine_patch_layer_impl.h
+++ b/chromium/cc/layers/nine_patch_layer_impl.h
@@ -44,7 +44,7 @@ class CC_EXPORT NinePatchLayerImpl : public UIResourceLayerImpl {
void AppendQuads(viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
- std::unique_ptr<base::DictionaryValue> LayerAsJson() override;
+ std::unique_ptr<base::DictionaryValue> LayerAsJson() const override;
protected:
NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id);
diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc
index 541c024eba5..214a33ba52c 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer.cc
@@ -4,24 +4,12 @@
#include "cc/layers/painted_scrollbar_layer.h"
-#include <algorithm>
-
#include "base/auto_reset.h"
-#include "cc/base/math_util.h"
-#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/painted_scrollbar_layer_impl.h"
-#include "cc/paint/paint_flags.h"
#include "cc/paint/skia_paint_canvas.h"
-#include "cc/resources/ui_resource_bitmap.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/layer_tree_impl.h"
-#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkSize.h"
-#include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/skia_util.h"
namespace {
static constexpr int kMaxScrollbarDimension = 8192;
@@ -54,10 +42,6 @@ PaintedScrollbarLayer::PaintedScrollbarLayer(
is_overlay_(scrollbar_->IsOverlay()),
has_thumb_(scrollbar_->HasThumb()),
thumb_opacity_(scrollbar_->ThumbOpacity()) {
- if (!scrollbar_->IsOverlay()) {
- AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kScrollbarScrolling);
- }
SetIsScrollbar(true);
}
diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc
index 50a0b87b9d4..fa1d6ae4c54 100644
--- a/chromium/cc/layers/picture_layer.cc
+++ b/chromium/cc/layers/picture_layer.cc
@@ -133,6 +133,7 @@ bool PictureLayer::Update() {
layer_tree_host()->recording_scale_factor());
SetNeedsPushProperties();
+ paint_count_++;
} else {
// If this invalidation did not affect the recording source, then it can be
// cleared as an optimization.
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index 5c4c58fc5da..c3bed20247f 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -256,12 +256,6 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
- if (mask_type_ != Layer::LayerMaskType::NOT_MASK) {
- append_quads_data->num_mask_layers++;
- if (is_rounded_corner_mask())
- append_quads_data->num_rounded_corner_mask_layers++;
- }
-
if (raster_source_->IsSolidColor()) {
// TODO(sunxd): Solid color non-mask layers are forced to have contents
// scale = 1. This is a workaround to temperarily fix
@@ -461,13 +455,6 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
visible_geometry_rect.height();
append_quads_data->visible_layer_area += visible_geometry_area;
- if (mask_type_ != Layer::LayerMaskType::NOT_MASK) {
- append_quads_data->visible_mask_layer_area += visible_geometry_area;
- if (is_rounded_corner_mask())
- append_quads_data->visible_rounded_corner_mask_layer_area +=
- visible_geometry_area;
- }
-
bool has_draw_quad = false;
if (*iter && iter->draw_info().IsReadyToDraw()) {
const TileDrawInfo& draw_info = iter->draw_info();
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index 147364120ac..00cbffe0d5a 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/macros.h"
+#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
#include "cc/base/math_util.h"
@@ -3242,7 +3243,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) {
while (std::abs(tile->contents_scale_key() - expected_scales[scale_index]) >
std::numeric_limits<float>::epsilon()) {
++scale_index;
- ASSERT_LT(scale_index, arraysize(expected_scales));
+ ASSERT_LT(scale_index, base::size(expected_scales));
}
EXPECT_FLOAT_EQ(tile->contents_scale_key(), expected_scales[scale_index]);
@@ -3290,7 +3291,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) {
while (std::abs(tile->contents_scale_key() - expected_scales[scale_index]) >
std::numeric_limits<float>::epsilon()) {
++scale_index;
- ASSERT_LT(scale_index, arraysize(expected_scales));
+ ASSERT_LT(scale_index, base::size(expected_scales));
}
EXPECT_FLOAT_EQ(tile->contents_scale_key(), expected_scales[scale_index]);
@@ -4051,7 +4052,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
layer1->SetBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
- layer1->SetPosition(occluding_layer_position);
+ layer1->test_properties()->position = occluding_layer_position;
RebuildPropertyTreesOnPendingTree();
host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
@@ -4075,7 +4076,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
EXPECT_EQ(20, unoccluded_tile_count);
// Full occlusion.
- layer1->SetPosition(gfx::PointF());
+ layer1->test_properties()->position = gfx::PointF();
layer1->NoteLayerPropertyChanged();
RebuildPropertyTreesOnPendingTree();
@@ -4146,7 +4147,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
layer1->SetBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
- layer1->SetPosition(occluding_layer_position);
+ layer1->test_properties()->position = occluding_layer_position;
RebuildPropertyTreesOnPendingTree();
host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
@@ -4183,7 +4184,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
}
// Full occlusion.
- layer1->SetPosition(gfx::PointF());
+ layer1->test_properties()->position = gfx::PointF();
layer1->NoteLayerPropertyChanged();
RebuildPropertyTreesOnPendingTree();
@@ -4243,7 +4244,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
layer1->SetBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
- layer1->SetPosition(occluding_layer_position);
+ layer1->test_properties()->position = occluding_layer_position;
pending_layer()->tilings()->RemoveAllTilings();
float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
@@ -4328,7 +4329,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
layer1->SetBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
- layer1->SetPosition(occluding_layer_position);
+ layer1->test_properties()->position = occluding_layer_position;
ActivateTree();
@@ -4424,7 +4425,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
active_occluding_layer->SetBounds(layer_bounds);
active_occluding_layer->SetDrawsContent(true);
active_occluding_layer->SetContentsOpaque(true);
- active_occluding_layer->SetPosition(active_occluding_layer_position);
+ active_occluding_layer->test_properties()->position =
+ active_occluding_layer_position;
ActivateTree();
// Partially invalidate the pending layer. Tiles inside the invalidation rect
@@ -4440,7 +4442,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
pending_occluding_layer->SetBounds(layer_bounds);
pending_occluding_layer->SetDrawsContent(true);
pending_occluding_layer->SetContentsOpaque(true);
- pending_occluding_layer->SetPosition(pending_occluding_layer_position);
+ pending_occluding_layer->test_properties()->position =
+ pending_occluding_layer_position;
EXPECT_EQ(1u, pending_layer()->num_tilings());
EXPECT_EQ(2u, active_layer()->num_tilings());
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index d4a0e72f590..168de7b984e 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -153,6 +153,10 @@ const FilterOperations& RenderSurfaceImpl::BackdropFilters() const {
return OwningEffectNode()->backdrop_filters;
}
+const gfx::RectF& RenderSurfaceImpl::BackdropFilterBounds() const {
+ return OwningEffectNode()->backdrop_filter_bounds;
+}
+
bool RenderSurfaceImpl::TrilinearFiltering() const {
return OwningEffectNode()->trilinear_filtering;
}
@@ -375,6 +379,7 @@ std::unique_ptr<viz::RenderPass> RenderSurfaceImpl::CreateRenderPass() {
draw_properties_.screen_space_transform);
pass->filters = Filters();
pass->backdrop_filters = BackdropFilters();
+ pass->backdrop_filter_bounds = BackdropFilterBounds();
pass->generate_mipmap = TrilinearFiltering();
pass->cache_render_pass = ShouldCacheRenderSurface();
pass->has_damage_from_contributing_content =
@@ -430,17 +435,6 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
"mask_layer_gpu_memory_usage",
mask_layer->GPUMemoryUsageInBytes());
- int64_t visible_geometry_area =
- static_cast<int64_t>(unoccluded_content_rect.width()) *
- unoccluded_content_rect.height();
- append_quads_data->num_mask_layers++;
- append_quads_data->visible_mask_layer_area += visible_geometry_area;
- if (mask_layer->is_rounded_corner_mask()) {
- append_quads_data->num_rounded_corner_mask_layers++;
- append_quads_data->visible_rounded_corner_mask_layer_area +=
- visible_geometry_area;
- }
-
if (mask_layer->mask_type() == Layer::LayerMaskType::MULTI_TEXTURE_MASK) {
TileMaskLayer(render_pass, shared_quad_state, unoccluded_content_rect);
return;
diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h
index 6e648a4d8ff..e3011ee3111 100644
--- a/chromium/cc/layers/render_surface_impl.h
+++ b/chromium/cc/layers/render_surface_impl.h
@@ -150,6 +150,7 @@ class CC_EXPORT RenderSurfaceImpl {
const FilterOperations& Filters() const;
const FilterOperations& BackdropFilters() const;
+ const gfx::RectF& BackdropFilterBounds() const;
gfx::PointF FiltersOrigin() const;
gfx::Transform SurfaceScale() const;
diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc
index 4425f722798..c46e3eef674 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -252,49 +252,6 @@ TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) {
}
}
-TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) {
- // Create and attach a non-overlay scrollbar.
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar);
- LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), std::move(scrollbar), false, false, 0, 0);
- PaintedScrollbarLayerImpl* scrollbar_layer_impl =
- static_cast<PaintedScrollbarLayerImpl*>(
- layer_impl_tree_root->layer_tree_impl()->LayerById(
- scrollbar_layer_id_));
- ScrollTree& scroll_tree =
- layer_impl_tree_root->layer_tree_impl()->property_trees()->scroll_tree;
- ScrollNode* scroll_node =
- scroll_tree.Node(scrollbar_layer_impl->scroll_tree_index());
-
- // When the scrollbar is not an overlay scrollbar, the scroll should be
- // responded to on the main thread as the compositor does not yet implement
- // scrollbar scrolling.
- InputHandler::ScrollStatus status = layer_tree_host_->host_impl()->TryScroll(
- gfx::PointF(), InputHandler::TOUCHSCREEN, scroll_tree, scroll_node);
- EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
- EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
- status.main_thread_scrolling_reasons);
-
- // Create and attach an overlay scrollbar.
- scrollbar.reset(new FakeScrollbar(false, false, true));
-
- layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), std::move(scrollbar), false, false, 0, 0);
- scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
- layer_impl_tree_root->layer_tree_impl()->LayerById(scrollbar_layer_id_));
- scroll_tree =
- layer_impl_tree_root->layer_tree_impl()->property_trees()->scroll_tree;
- scroll_node = scroll_tree.Node(scrollbar_layer_impl->scroll_tree_index());
-
- // The user shouldn't be able to drag an overlay scrollbar and the scroll
- // may be handled in the compositor.
- status = layer_tree_host_->host_impl()->TryScroll(
- gfx::PointF(), InputHandler::TOUCHSCREEN, scroll_tree, scroll_node);
- EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
- EXPECT_EQ(MainThreadScrollingReason::kNotScrollable,
- status.main_thread_scrolling_reasons);
-}
-
class FakeNinePatchScrollbar : public FakeScrollbar {
public:
bool UsesNinePatchThumbResource() const override { return true; }
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index 23810a45400..3b411aa7c69 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include "base/stl_util.h"
#include "base/trace_event/traced_value.h"
#include "cc/debug/debug_colors.h"
#include "cc/layers/append_quads_data.h"
@@ -212,7 +213,7 @@ void SurfaceLayerImpl::AppendRainbowDebugBorder(viz::RenderPass* render_pass) {
0x800000ff, // Blue.
0x80ee82ee, // Violet.
};
- const int kNumColors = arraysize(colors);
+ const int kNumColors = base::size(colors);
const int kStripeWidth = 300;
const int kStripeHeight = 300;
diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc
index 0b2784bf04d..e97162e7b1e 100644
--- a/chromium/cc/layers/texture_layer.cc
+++ b/chromium/cc/layers/texture_layer.cc
@@ -339,8 +339,8 @@ TextureLayer::TransferableResourceHolder::GetCallbackForImplThread(
DCHECK_GT(internal_references_, 0);
InternalAddRef();
return viz::SingleReleaseCallback::Create(
- base::Bind(&TransferableResourceHolder::ReturnAndReleaseOnImplThread,
- this, std::move(main_thread_task_runner)));
+ base::BindOnce(&TransferableResourceHolder::ReturnAndReleaseOnImplThread,
+ this, std::move(main_thread_task_runner)));
}
void TextureLayer::TransferableResourceHolder::InternalAddRef() {
@@ -375,7 +375,7 @@ void TextureLayer::TransferableResourceHolder::ReturnAndReleaseOnImplThread(
#endif
main_thread_task_runner->PostTask(
FROM_HERE,
- base::Bind(&TransferableResourceHolder::InternalRelease, this));
+ base::BindOnce(&TransferableResourceHolder::InternalRelease, this));
}
} // namespace cc
diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc
index 7022e5757f1..93a61894e5b 100644
--- a/chromium/cc/layers/texture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/texture_layer_impl_unittest.cc
@@ -63,7 +63,7 @@ TEST(TextureLayerImplTest, Occlusion) {
texture_layer_impl->SetDrawsContent(true);
texture_layer_impl->SetTransferableResource(
resource,
- viz::SingleReleaseCallback::Create(base::Bind(&IgnoreCallback)));
+ viz::SingleReleaseCallback::Create(base::BindOnce(&IgnoreCallback)));
impl.CalcDrawProps(viewport_size);
@@ -122,7 +122,7 @@ TEST(TextureLayerImplTest, ResourceNotFreedOnGpuRasterToggle) {
texture_layer_impl->SetBounds(layer_size);
texture_layer_impl->SetDrawsContent(true);
texture_layer_impl->SetTransferableResource(
- resource, viz::SingleReleaseCallback::Create(base::Bind(
+ resource, viz::SingleReleaseCallback::Create(base::BindOnce(
[](bool* released, const gpu::SyncToken& sync_token,
bool lost) { *released = true; },
base::Unretained(&released))));
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index de62de061e6..c85b89e9247 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -123,11 +123,11 @@ struct CommonResourceObjects {
gpu::CommandBufferId::FromUnsafeValue(0x234),
2) {
release_callback1_ =
- base::Bind(&MockReleaseCallback::Release,
- base::Unretained(&mock_callback_), mailbox_name1_);
+ base::BindRepeating(&MockReleaseCallback::Release,
+ base::Unretained(&mock_callback_), mailbox_name1_);
release_callback2_ =
- base::Bind(&MockReleaseCallback::Release,
- base::Unretained(&mock_callback_), mailbox_name2_);
+ base::BindRepeating(&MockReleaseCallback::Release,
+ base::Unretained(&mock_callback_), mailbox_name2_);
const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
resource1_ = viz::TransferableResource::MakeGL(
@@ -136,9 +136,9 @@ struct CommonResourceObjects {
mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
gfx::Size size(128, 128);
shared_bitmap_id_ = viz::SharedBitmap::GenerateId();
- sw_release_callback_ =
- base::Bind(&MockReleaseCallback::Release2,
- base::Unretained(&mock_callback_), shared_bitmap_id_);
+ sw_release_callback_ = base::BindRepeating(
+ &MockReleaseCallback::Release2, base::Unretained(&mock_callback_),
+ shared_bitmap_id_);
sw_resource_ = viz::TransferableResource::MakeSoftware(
shared_bitmap_id_, size, viz::RGBA_8888);
}
@@ -683,7 +683,7 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
void SetMailbox(char mailbox_char) {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
+ viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
base::Unretained(this), mailbox_char));
@@ -761,7 +761,7 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
const gpu::SyncToken sync_token =
SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char));
std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
+ viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
base::Unretained(this), sync_token));
auto resource = viz::TransferableResource::MakeGL(
@@ -1027,9 +1027,9 @@ class TextureLayerNoExtraCommitForMailboxTest
*resource = viz::TransferableResource::MakeGL(MailboxFromChar('1'),
GL_LINEAR, GL_TEXTURE_2D,
SyncTokenFromUInt(0x123));
- *release_callback = viz::SingleReleaseCallback::Create(
- base::Bind(&TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
- base::Unretained(this)));
+ *release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
+ &TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
+ base::Unretained(this)));
return true;
}
@@ -1101,9 +1101,9 @@ class TextureLayerChangeInvisibleMailboxTest
if (!resource_changed_)
return false;
*resource = resource_;
- *release_callback = viz::SingleReleaseCallback::Create(
- base::Bind(&TextureLayerChangeInvisibleMailboxTest::ResourceReleased,
- base::Unretained(this)));
+ *release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
+ &TextureLayerChangeInvisibleMailboxTest::ResourceReleased,
+ base::Unretained(this)));
return true;
}
@@ -1220,8 +1220,8 @@ class TextureLayerReleaseResourcesBase
*resource = viz::TransferableResource::MakeGL(
MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1));
*release_callback = viz::SingleReleaseCallback::Create(
- base::Bind(&TextureLayerReleaseResourcesBase::ResourceReleased,
- base::Unretained(this)));
+ base::BindOnce(&TextureLayerReleaseResourcesBase::ResourceReleased,
+ base::Unretained(this)));
return true;
}
@@ -1291,7 +1291,7 @@ class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
void SetMailbox(char mailbox_char) {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
+ viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
base::Unretained(this)));
auto resource = viz::TransferableResource::MakeGL(
@@ -1361,7 +1361,7 @@ class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
void SetMailbox(char mailbox_char) {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
+ viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
base::Unretained(this)));
auto resource = viz::TransferableResource::MakeGL(
diff --git a/chromium/cc/layers/ui_resource_layer_impl.cc b/chromium/cc/layers/ui_resource_layer_impl.cc
index c3a94fc6fbc..7eae103e9aa 100644
--- a/chromium/cc/layers/ui_resource_layer_impl.cc
+++ b/chromium/cc/layers/ui_resource_layer_impl.cc
@@ -138,7 +138,8 @@ const char* UIResourceLayerImpl::LayerTypeAsString() const {
return "cc::UIResourceLayerImpl";
}
-std::unique_ptr<base::DictionaryValue> UIResourceLayerImpl::LayerAsJson() {
+std::unique_ptr<base::DictionaryValue> UIResourceLayerImpl::LayerAsJson()
+ const {
std::unique_ptr<base::DictionaryValue> result = LayerImpl::LayerAsJson();
result->Set("ImageBounds", MathUtil::AsValue(image_bounds_));
diff --git a/chromium/cc/layers/ui_resource_layer_impl.h b/chromium/cc/layers/ui_resource_layer_impl.h
index bd94720a0e2..1283a23a9c3 100644
--- a/chromium/cc/layers/ui_resource_layer_impl.h
+++ b/chromium/cc/layers/ui_resource_layer_impl.h
@@ -52,7 +52,7 @@ class CC_EXPORT UIResourceLayerImpl : public LayerImpl {
void AppendQuads(viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
- std::unique_ptr<base::DictionaryValue> LayerAsJson() override;
+ std::unique_ptr<base::DictionaryValue> LayerAsJson() const override;
protected:
UIResourceLayerImpl(LayerTreeImpl* tree_impl, int id);
diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc
index f70e8e22646..f7b2f20bcd6 100644
--- a/chromium/cc/layers/video_layer_impl_unittest.cc
+++ b/chromium/cc/layers/video_layer_impl_unittest.cc
@@ -299,8 +299,6 @@ TEST(VideoLayerImplTest, Rotated270) {
EXPECT_EQ(gfx::Point3F(0, 0, 0), p2);
}
-void EmptyCallback(const gpu::SyncToken& sync_token) {}
-
TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) {
gfx::Size layer_size(1000, 1000);
@@ -388,7 +386,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::WrapNativeTextures(
- media::PIXEL_FORMAT_I420, mailbox_holders, base::Bind(EmptyCallback),
+ media::PIXEL_FORMAT_I420, mailbox_holders, base::DoNothing(),
gfx::Size(10, 10), gfx::Rect(10, 10), gfx::Size(10, 10),
base::TimeDelta());
ASSERT_TRUE(video_frame);
@@ -432,7 +430,7 @@ TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) {
gfx::Size resource_size = gfx::Size(10, 10);
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::WrapNativeTextures(
- media::PIXEL_FORMAT_ARGB, mailbox_holders, base::Bind(EmptyCallback),
+ media::PIXEL_FORMAT_ARGB, mailbox_holders, base::DoNothing(),
resource_size, gfx::Rect(10, 10), resource_size, base::TimeDelta());
ASSERT_TRUE(video_frame);
video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY,
diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
index 3dfd15b8666..286c3288c93 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -167,14 +167,15 @@ void AsyncLayerTreeFrameSink::SetLocalSurfaceId(
void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
viz::CompositorFrame frame,
+ bool hit_test_data_changed,
bool show_hit_test_borders) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(compositor_frame_sink_ptr_);
DCHECK(frame.metadata.begin_frame_ack.has_damage);
DCHECK_LE(viz::BeginFrameArgs::kStartingFrameNumber,
frame.metadata.begin_frame_ack.sequence_number);
- TRACE_EVENT0("cc,benchmark",
- "AsyncLayerTreeFrameSink::SubmitCompositorFrame");
+ TRACE_EVENT1("cc,benchmark", "AsyncLayerTreeFrameSink::SubmitCompositorFrame",
+ "source_frame_number_", source_frame_number_);
// It's possible to request an immediate composite from cc which will bypass
// BeginFrame. In that case, we cannot collect full graphics pipeline data.
@@ -217,6 +218,28 @@ void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
if (show_hit_test_borders && hit_test_region_list)
hit_test_region_list->flags |= viz::HitTestRegionFlags::kHitTestDebug;
+ // If |hit_test_data_changed| was set or local_surface_id has been updated,
+ // we always send hit-test data; otherwise we check for equality with the
+ // last submitted hit-test data for possible optimization.
+ if (!hit_test_region_list) {
+ last_hit_test_data_ = viz::HitTestRegionList();
+ } else if (!hit_test_data_changed &&
+ local_surface_id_ == last_submitted_local_surface_id_) {
+ if (viz::HitTestRegionList::IsEqual(*hit_test_region_list,
+ last_hit_test_data_)) {
+ DCHECK(!viz::HitTestRegionList::IsEqual(*hit_test_region_list,
+ viz::HitTestRegionList()));
+ hit_test_region_list = base::nullopt;
+ } else {
+ last_hit_test_data_ = *hit_test_region_list;
+ }
+
+ UMA_HISTOGRAM_BOOLEAN("Event.VizHitTest.HitTestDataIsEqualAccuracy",
+ !hit_test_region_list);
+ } else {
+ last_hit_test_data_ = *hit_test_region_list;
+ }
+
if (last_submitted_local_surface_id_ != local_surface_id_) {
last_submitted_local_surface_id_ = local_surface_id_;
last_submitted_device_scale_factor_ = frame.device_scale_factor();
@@ -314,7 +337,8 @@ void AsyncLayerTreeFrameSink::OnBeginFrame(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"step", "ReceiveBeginFrameDiscard");
// We had a race with SetNeedsBeginFrame(false) and still need to let the
- // sink know that we didn't use this BeginFrame.
+ // sink know that we didn't use this BeginFrame. OnBeginFrame() can also be
+ // called to deliver presentation feedback.
DidNotProduceFrame(viz::BeginFrameAck(args, false));
return;
}
diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
index f3f3be12461..0750bcf231c 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
@@ -118,6 +118,7 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
void DetachFromClient() override;
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool hit_test_data_changed,
bool show_hit_test_borders) override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
@@ -125,6 +126,10 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
void ForceAllocateNewId() override;
+ const viz::HitTestRegionList& get_last_hit_test_data_for_testing() const {
+ return last_hit_test_data_;
+ }
+
private:
// mojom::CompositorFrameSinkClient implementation:
void DidReceiveCompositorFrameAck(
@@ -166,6 +171,8 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
const bool enable_surface_synchronization_;
const bool wants_animate_only_begin_frames_;
+ viz::HitTestRegionList last_hit_test_data_;
+
viz::LocalSurfaceId last_submitted_local_surface_id_;
float last_submitted_device_scale_factor_ = 1.f;
gfx::Size last_submitted_size_in_pixels_;
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 b00ca4cb0ec..cc49361e62f 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
@@ -10,9 +10,16 @@
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
+#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/quads/render_pass_draw_quad.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
+#include "components/viz/common/quads/surface_draw_quad.h"
+#include "components/viz/common/surfaces/surface_range.h"
+#include "components/viz/test/compositor_frame_helpers.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gpu_memory_buffer_manager.h"
#include "mojo/public/cpp/bindings/interface_request.h"
@@ -70,8 +77,6 @@ TEST(AsyncLayerTreeFrameSinkTest,
init_params.gpu_memory_buffer_manager = &test_gpu_memory_buffer_manager;
init_params.pipes.compositor_frame_sink_info = std::move(sink_info);
init_params.pipes.client_request = std::move(client_request);
- init_params.local_surface_id_provider =
- std::make_unique<viz::DefaultLocalSurfaceIdProvider>();
init_params.enable_surface_synchronization = true;
auto layer_tree_frame_sink = std::make_unique<AsyncLayerTreeFrameSink>(
std::move(provider), nullptr, &init_params);
@@ -115,5 +120,312 @@ TEST(AsyncLayerTreeFrameSinkTest,
}
} // namespace
+
+// Boilerplate code for simple AsyncLayerTreeFrameSink. Friend of
+// AsyncLayerTreeFrameSink.
+class AsyncLayerTreeFrameSinkSimpleTest : public testing::Test {
+ public:
+ AsyncLayerTreeFrameSinkSimpleTest()
+ : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::TestMockTimeTaskRunner::Type::kStandalone)),
+ display_rect_(1, 1) {
+ auto context_provider = viz::TestContextProvider::Create();
+
+ viz::mojom::CompositorFrameSinkPtrInfo sink_info;
+ viz::mojom::CompositorFrameSinkRequest sink_request =
+ mojo::MakeRequest(&sink_info);
+ viz::mojom::CompositorFrameSinkClientPtr client;
+ viz::mojom::CompositorFrameSinkClientRequest client_request =
+ mojo::MakeRequest(&client);
+
+ init_params_.compositor_task_runner = task_runner_;
+ init_params_.gpu_memory_buffer_manager = &test_gpu_memory_buffer_manager_;
+ init_params_.pipes.compositor_frame_sink_info = std::move(sink_info);
+ init_params_.pipes.client_request = std::move(client_request);
+ init_params_.enable_surface_synchronization = true;
+ init_params_.hit_test_data_provider =
+ std::make_unique<viz::HitTestDataProviderDrawQuad>(
+ /*should_ask_for_child_region=*/true, /*root_accepts_events=*/true);
+
+ layer_tree_frame_sink_ = std::make_unique<AsyncLayerTreeFrameSink>(
+ std::move(context_provider), nullptr, &init_params_);
+
+ viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
+ layer_tree_frame_sink_->SetLocalSurfaceId(local_surface_id);
+ layer_tree_frame_sink_->BindToClient(&layer_tree_frame_sink_client_);
+ }
+
+ void SendRenderPassList(viz::RenderPassList* pass_list,
+ bool hit_test_data_changed) {
+ auto frame = viz::CompositorFrameBuilder()
+ .SetRenderPassList(std::move(*pass_list))
+ .Build();
+ pass_list->clear();
+ layer_tree_frame_sink_->SubmitCompositorFrame(
+ std::move(frame), hit_test_data_changed,
+ /*show_hit_test_borders=*/false);
+ }
+
+ const viz::HitTestRegionList& GetHitTestData() const {
+ return layer_tree_frame_sink_->get_last_hit_test_data_for_testing();
+ }
+
+ AsyncLayerTreeFrameSink::InitParams init_params_;
+
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
+ viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_;
+ gfx::Rect display_rect_;
+ std::unique_ptr<AsyncLayerTreeFrameSink> layer_tree_frame_sink_;
+ FakeLayerTreeFrameSinkClient layer_tree_frame_sink_client_;
+};
+
+TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
+ viz::RenderPassList pass_list;
+
+ // Initial submission.
+ auto pass1 = viz::RenderPass::Create();
+ pass1->id = 1;
+ pass1->output_rect = display_rect_;
+ auto* shared_quad_state1 = pass1->CreateAndAppendSharedQuadState();
+ gfx::Rect rect1(display_rect_);
+ shared_quad_state1->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect1,
+ /*visible_quad_layer_rect=*/rect1, /*clip_rect=*/rect1,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad1 =
+ pass1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad1->SetNew(shared_quad_state1, /*rect=*/rect1,
+ /*visible_rect=*/rect1, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(move(pass1));
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+ const viz::HitTestRegionList hit_test_region_list = GetHitTestData();
+
+ // Identical submission.
+ auto pass2 = viz::RenderPass::Create();
+ pass2->id = 2;
+ pass2->output_rect = display_rect_;
+ auto* shared_quad_state2 = pass2->CreateAndAppendSharedQuadState();
+ gfx::Rect rect2(display_rect_);
+ shared_quad_state2->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect2,
+ /*visible_quad_layer_rect=*/rect2, /*clip_rect=*/rect2,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad2 =
+ pass2->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad2->SetNew(shared_quad_state2, /*rect=*/rect2,
+ /*visible_rect=*/rect2, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(move(pass2));
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+
+ EXPECT_TRUE(
+ viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
+
+ // Different submission.
+ const viz::SurfaceId child_surface_id(
+ viz::FrameSinkId(1, 1),
+ viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
+ auto pass3_0 = viz::RenderPass::Create();
+ pass3_0->output_rect = display_rect_;
+ pass3_0->id = 3;
+ auto* shared_quad_state3_0 = pass3_0->CreateAndAppendSharedQuadState();
+ gfx::Rect rect3_0(display_rect_);
+ gfx::Transform transform3_0;
+ transform3_0.Translate(-200, -100);
+ shared_quad_state3_0->SetAll(
+ transform3_0, /*quad_layer_rect=*/rect3_0,
+ /*visible_quad_layer_rect=*/rect3_0, /*clip_rect=*/rect3_0,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad3_0 =
+ pass3_0->quad_list.AllocateAndConstruct<viz::SurfaceDrawQuad>();
+ quad3_0->SetNew(shared_quad_state3_0, /*rect=*/rect3_0,
+ /*visible_rect=*/rect3_0,
+ viz::SurfaceRange(base::nullopt, child_surface_id),
+ SK_ColorBLACK,
+ /*stretch_content_to_fill_bounds=*/false,
+ /*ignores_input_event=*/false);
+ pass_list.push_back(std::move(pass3_0));
+
+ auto pass3_1 = viz::RenderPass::Create();
+ pass3_1->output_rect = display_rect_;
+ pass3_1->id = 4;
+ auto* shared_quad_state3_1 = pass3_1->CreateAndAppendSharedQuadState();
+ gfx::Rect rect3_1(display_rect_);
+ shared_quad_state3_1->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect3_1,
+ /*visible_quad_layer_rect=*/rect3_1, /*clip_rect=*/rect3_1,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad3_1 =
+ pass3_1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad3_1->SetNew(shared_quad_state3_1, /*rect=*/rect3_1,
+ /*visible_rect=*/rect3_1, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(std::move(pass3_1));
+
+ auto pass3_root = viz::RenderPass::Create();
+ pass3_root->output_rect = display_rect_;
+ pass3_root->id = 5;
+ auto* shared_quad_state3_root = pass3_root->CreateAndAppendSharedQuadState();
+ gfx::Rect rect3_root(display_rect_);
+ shared_quad_state3_root->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect3_root,
+ /*visible_quad_layer_rect=*/rect3_root, /*clip_rect=*/rect3_root,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad3_root_1 =
+ pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
+ quad3_root_1->SetNew(shared_quad_state3_root, /*rect=*/rect3_root,
+ /*visible_rect=*/rect3_root, /*render_pass_id=*/3,
+ /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
+ gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
+ 1.0f);
+ auto* quad3_root_2 =
+ pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
+ quad3_root_2->SetNew(shared_quad_state3_root, /*rect=*/rect3_root,
+ /*visible_rect=*/rect3_root, /*render_pass_id=*/4,
+ /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
+ gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
+ 1.0f);
+ pass_list.push_back(std::move(pass3_root));
+
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+ EXPECT_FALSE(
+ viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
+}
+
+TEST_F(AsyncLayerTreeFrameSinkSimpleTest,
+ HitTestRegionListDuplicateChangedFlip) {
+ viz::RenderPassList pass_list;
+
+ // Initial submission.
+ auto pass1 = viz::RenderPass::Create();
+ pass1->id = 1;
+ pass1->output_rect = display_rect_;
+ auto* shared_quad_state1 = pass1->CreateAndAppendSharedQuadState();
+ gfx::Rect rect1(display_rect_);
+ shared_quad_state1->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect1,
+ /*visible_quad_layer_rect=*/rect1, /*clip_rect=*/rect1,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad1 =
+ pass1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad1->SetNew(shared_quad_state1, /*rect=*/rect1,
+ /*visible_rect=*/rect1, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(move(pass1));
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+ viz::HitTestRegionList hit_test_region_list = GetHitTestData();
+
+ // Different submission with |hit_test_data_changed| set to true.
+ const viz::SurfaceId child_surface_id(
+ viz::FrameSinkId(1, 1),
+ viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
+ auto pass2_0 = viz::RenderPass::Create();
+ pass2_0->output_rect = display_rect_;
+ pass2_0->id = 2;
+ auto* shared_quad_state2_0 = pass2_0->CreateAndAppendSharedQuadState();
+ gfx::Rect rect2_0(display_rect_);
+ gfx::Transform transform2_0;
+ transform2_0.Translate(-200, -100);
+ shared_quad_state2_0->SetAll(
+ transform2_0, /*quad_layer_rect=*/rect2_0,
+ /*visible_quad_layer_rect=*/rect2_0, /*clip_rect=*/rect2_0,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad2_0 =
+ pass2_0->quad_list.AllocateAndConstruct<viz::SurfaceDrawQuad>();
+ quad2_0->SetNew(shared_quad_state2_0, /*rect=*/rect2_0,
+ /*visible_rect=*/rect2_0,
+ viz::SurfaceRange(base::nullopt, child_surface_id),
+ SK_ColorBLACK,
+ /*stretch_content_to_fill_bounds=*/false,
+ /*ignores_input_event=*/false);
+ pass_list.push_back(std::move(pass2_0));
+
+ auto pass2_1 = viz::RenderPass::Create();
+ pass2_1->output_rect = display_rect_;
+ pass2_1->id = 3;
+ auto* shared_quad_state2_1 = pass2_1->CreateAndAppendSharedQuadState();
+ gfx::Rect rect2_1(display_rect_);
+ shared_quad_state2_1->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect2_1,
+ /*visible_quad_layer_rect=*/rect2_1, /*clip_rect=*/rect2_1,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad2_1 =
+ pass2_1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad2_1->SetNew(shared_quad_state2_1, /*rect=*/rect2_1,
+ /*visible_rect=*/rect2_1, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(std::move(pass2_1));
+
+ auto pass2_root = viz::RenderPass::Create();
+ pass2_root->output_rect = display_rect_;
+ pass2_root->id = 4;
+ auto* shared_quad_state2_root = pass2_root->CreateAndAppendSharedQuadState();
+ gfx::Rect rect2_root(display_rect_);
+ shared_quad_state2_root->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect2_root,
+ /*visible_quad_layer_rect=*/rect2_root, /*clip_rect=*/rect2_root,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad2_root_1 =
+ pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
+ quad2_root_1->SetNew(shared_quad_state2_root, /*rect=*/rect2_root,
+ /*visible_rect=*/rect2_root, /*render_pass_id=*/2,
+ /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
+ gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
+ 1.0f);
+ auto* quad2_root_2 =
+ pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
+ quad2_root_2->SetNew(shared_quad_state2_root, /*rect=*/rect2_root,
+ /*visible_rect=*/rect2_root, /*render_pass_id=*/3,
+ /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
+ gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
+ 1.0f);
+ pass_list.push_back(std::move(pass2_root));
+
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/true);
+ task_runner_->RunUntilIdle();
+
+ EXPECT_FALSE(
+ viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
+ hit_test_region_list = GetHitTestData();
+
+ // Identical submission with |hit_test_data_changed| set back to false. We
+ // expect the hit-data to still have been sent.
+ auto pass3 = viz::RenderPass::Create();
+ pass3->id = 4;
+ pass3->output_rect = display_rect_;
+ auto* shared_quad_state3 = pass3->CreateAndAppendSharedQuadState();
+ gfx::Rect rect3(display_rect_);
+ shared_quad_state3->SetAll(
+ gfx::Transform(), /*quad_layer_rect=*/rect3,
+ /*visible_quad_layer_rect=*/rect3, /*clip_rect=*/rect3,
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* quad3 =
+ pass3->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
+ quad3->SetNew(shared_quad_state3, /*rect=*/rect3,
+ /*visible_rect=*/rect3, SK_ColorBLACK,
+ /*force_anti_aliasing_off=*/false);
+ pass_list.push_back(move(pass3));
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+
+ EXPECT_FALSE(
+ viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
+}
+
} // namespace mojo_embedder
} // namespace cc
diff --git a/chromium/cc/paint/BUILD.gn b/chromium/cc/paint/BUILD.gn
index 21c6b8b7b5d..74d2b6dc4c9 100644
--- a/chromium/cc/paint/BUILD.gn
+++ b/chromium/cc/paint/BUILD.gn
@@ -59,6 +59,8 @@ cc_component("paint") {
"paint_recorder.h",
"paint_shader.cc",
"paint_shader.h",
+ "paint_worklet_input.h",
+ "paint_worklet_layer_painter.h",
"raw_memory_transfer_cache_entry.cc",
"raw_memory_transfer_cache_entry.h",
"record_paint_canvas.cc",
diff --git a/chromium/cc/paint/color_space_transfer_cache_entry.cc b/chromium/cc/paint/color_space_transfer_cache_entry.cc
index adde3371f4e..31f27438a45 100644
--- a/chromium/cc/paint/color_space_transfer_cache_entry.cc
+++ b/chromium/cc/paint/color_space_transfer_cache_entry.cc
@@ -14,6 +14,7 @@ ClientColorSpaceTransferCacheEntry::ClientColorSpaceTransferCacheEntry(
DCHECK(raster_color_space.color_space.IsValid());
IPC::ParamTraits<gfx::ColorSpace>::Write(&pickle_,
raster_color_space.color_space);
+ DCHECK_LE(pickle_.size(), UINT32_MAX);
}
ClientColorSpaceTransferCacheEntry::~ClientColorSpaceTransferCacheEntry() =
@@ -23,8 +24,8 @@ uint32_t ClientColorSpaceTransferCacheEntry::Id() const {
return id_;
}
-size_t ClientColorSpaceTransferCacheEntry::SerializedSize() const {
- return pickle_.size();
+uint32_t ClientColorSpaceTransferCacheEntry::SerializedSize() const {
+ return static_cast<uint32_t>(pickle_.size());
}
bool ClientColorSpaceTransferCacheEntry::Serialize(
diff --git a/chromium/cc/paint/color_space_transfer_cache_entry.h b/chromium/cc/paint/color_space_transfer_cache_entry.h
index baeeb4ce68d..4923c73c7fc 100644
--- a/chromium/cc/paint/color_space_transfer_cache_entry.h
+++ b/chromium/cc/paint/color_space_transfer_cache_entry.h
@@ -29,7 +29,7 @@ class CC_PAINT_EXPORT ClientColorSpaceTransferCacheEntry final
const RasterColorSpace& raster_color_space);
~ClientColorSpaceTransferCacheEntry() override;
uint32_t Id() const override;
- size_t SerializedSize() const override;
+ uint32_t SerializedSize() const override;
bool Serialize(base::span<uint8_t> data) const final;
private:
diff --git a/chromium/cc/paint/discardable_image_map.cc b/chromium/cc/paint/discardable_image_map.cc
index c9462f1595c..eeda8585f89 100644
--- a/chromium/cc/paint/discardable_image_map.cc
+++ b/chromium/cc/paint/discardable_image_map.cc
@@ -195,10 +195,10 @@ class DiscardableImageGenerator {
PaintOpType op_type = static_cast<PaintOpType>(op->type);
if (op_type == PaintOpType::DrawImage) {
auto* image_op = static_cast<DrawImageOp*>(op);
- auto* sk_image = image_op->image.GetSkImage().get();
- AddImage(image_op->image,
- SkRect::MakeIWH(sk_image->width(), sk_image->height()),
- op_rect, ctm, image_op->flags.getFilterQuality());
+ AddImage(
+ image_op->image,
+ SkRect::MakeIWH(image_op->image.width(), image_op->image.height()),
+ op_rect, ctm, image_op->flags.getFilterQuality());
} else if (op_type == PaintOpType::DrawImageRect) {
auto* image_rect_op = static_cast<DrawImageRectOp*>(op);
SkMatrix matrix = ctm;
@@ -355,14 +355,16 @@ class DiscardableImageGenerator {
SkIRect src_irect;
src_rect.roundOut(&src_irect);
- // Make a note if any image was originally specified in a non-sRGB color
- // space.
- SkColorSpace* source_color_space = paint_image.color_space();
- color_stats_total_pixel_count_ += image_rect.size().GetCheckedArea();
- color_stats_total_image_count_++;
- if (!source_color_space || source_color_space->isSRGB()) {
- color_stats_srgb_pixel_count_ += image_rect.size().GetCheckedArea();
- color_stats_srgb_image_count_++;
+ if (!paint_image.IsPaintWorklet()) {
+ // Make a note if any image was originally specified in a non-sRGB color
+ // space.
+ SkColorSpace* source_color_space = paint_image.color_space();
+ color_stats_total_pixel_count_ += image_rect.size().GetCheckedArea();
+ color_stats_total_image_count_++;
+ if (!source_color_space || source_color_space->isSRGB()) {
+ color_stats_srgb_pixel_count_ += image_rect.size().GetCheckedArea();
+ color_stats_srgb_image_count_++;
+ }
}
auto& rects = image_id_to_rects_[paint_image.stable_id()];
diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc
index 32ec754bbe1..ba6211073ed 100644
--- a/chromium/cc/paint/discardable_image_map_unittest.cc
+++ b/chromium/cc/paint/discardable_image_map_unittest.cc
@@ -18,6 +18,7 @@
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_recording_source.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_paint_worklet_input.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkGraphics.h"
@@ -881,6 +882,19 @@ TEST_F(DiscardableImageMapTest, EmbeddedShaderWithAnimatedImages) {
ImageAnalysisState::kAnimatedImages);
}
+TEST_F(DiscardableImageMapTest, BuildPaintWorkletImage) {
+ gfx::SizeF size(100, 50);
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(size);
+ PaintImage paint_image = PaintImageBuilder::WithDefault()
+ .set_id(1)
+ .set_paint_worklet_input(std::move(input))
+ .TakePaintImage();
+ EXPECT_TRUE(paint_image.paint_worklet_input());
+ EXPECT_EQ(paint_image.width(), size.width());
+ EXPECT_EQ(paint_image.height(), size.height());
+}
+
TEST_F(DiscardableImageMapTest, DecodingModeHintsBasic) {
gfx::Rect visible_rect(100, 100);
PaintImage unspecified_image =
diff --git a/chromium/cc/paint/display_item_list.cc b/chromium/cc/paint/display_item_list.cc
index cacbe80e5a5..ea5a9768185 100644
--- a/chromium/cc/paint/display_item_list.cc
+++ b/chromium/cc/paint/display_item_list.cc
@@ -44,8 +44,10 @@ DisplayItemList::DisplayItemList(UsageHint usage_hint)
DisplayItemList::~DisplayItemList() = default;
-void DisplayItemList::Raster(SkCanvas* canvas,
- ImageProvider* image_provider) const {
+void DisplayItemList::Raster(
+ SkCanvas* canvas,
+ ImageProvider* image_provider,
+ PaintWorkletImageProvider* paint_worklet_image_provider) const {
DCHECK(usage_hint_ == kTopLevelDisplayItemList);
gfx::Rect canvas_playback_rect;
if (!GetCanvasClipBounds(canvas, &canvas_playback_rect))
@@ -53,7 +55,9 @@ void DisplayItemList::Raster(SkCanvas* canvas,
std::vector<size_t> offsets;
rtree_.Search(canvas_playback_rect, &offsets);
- paint_op_buffer_.Playback(canvas, PlaybackParams(image_provider), &offsets);
+ paint_op_buffer_.Playback(
+ canvas, PlaybackParams(image_provider, paint_worklet_image_provider),
+ &offsets);
}
void DisplayItemList::Finalize() {
diff --git a/chromium/cc/paint/display_item_list.h b/chromium/cc/paint/display_item_list.h
index feb8e5407b7..deda06057ca 100644
--- a/chromium/cc/paint/display_item_list.h
+++ b/chromium/cc/paint/display_item_list.h
@@ -41,6 +41,7 @@ class TracedValue;
}
namespace cc {
+class PaintWorkletImageProvider;
// DisplayItemList is a container of paint operations. One can populate the list
// using StartPaint, followed by push{,_with_data,_with_array} functions
@@ -59,7 +60,9 @@ class CC_PAINT_EXPORT DisplayItemList
explicit DisplayItemList(UsageHint = kTopLevelDisplayItemList);
- void Raster(SkCanvas* canvas, ImageProvider* image_provider = nullptr) const;
+ void Raster(SkCanvas* canvas,
+ ImageProvider* image_provider = nullptr,
+ PaintWorkletImageProvider* = nullptr) const;
void StartPaint() {
#if DCHECK_IS_ON()
diff --git a/chromium/cc/paint/filter_operation.cc b/chromium/cc/paint/filter_operation.cc
index 3357afb235c..267381b2bef 100644
--- a/chromium/cc/paint/filter_operation.cc
+++ b/chromium/cc/paint/filter_operation.cc
@@ -9,6 +9,7 @@
#include "cc/paint/filter_operation.h"
#include "base/numerics/ranges.h"
+#include "base/stl_util.h"
#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/base/math_util.h"
@@ -300,7 +301,7 @@ void FilterOperation::AsValueInto(base::trace_event::TracedValue* value) const {
break;
case FilterOperation::COLOR_MATRIX: {
value->BeginArray("matrix");
- for (size_t i = 0; i < arraysize(matrix_); ++i)
+ for (size_t i = 0; i < base::size(matrix_); ++i)
value->AppendDouble(matrix_[i]);
value->EndArray();
break;
@@ -349,10 +350,17 @@ gfx::Rect MapRectInternal(const FilterOperation& op,
switch (op.type()) {
case FilterOperation::BLUR: {
SkVector spread = MapStdDeviation(op.amount(), matrix);
- float spread_x = std::abs(spread.x());
- float spread_y = std::abs(spread.y());
+ // Mapping a blur forward requires an outset (negative inset) because a
+ // smaller source rectangle gets blurred to a larger destination
+ // rectangle.
+ // TODO(916583): Fix this function for reverse mapping:
+ // float sign = (direction == SkImageFilter::kForward_MapDirection) ? -1.0
+ // : 1.0;
+ float sign = -1.0;
+ float spread_x = std::abs(spread.x()) * sign;
+ float spread_y = std::abs(spread.y()) * sign;
gfx::RectF result(rect);
- result.Inset(-spread_x, -spread_y, -spread_x, -spread_y);
+ result.Inset(spread_x, spread_y, spread_x, spread_y);
return gfx::ToEnclosingRect(result);
}
case FilterOperation::DROP_SHADOW: {
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index dedc9add23c..3a9b9781385 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -69,7 +69,7 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
: 0u;
// Compute and cache the size of the data.
- base::CheckedNumeric<size_t> safe_size;
+ base::CheckedNumeric<uint32_t> safe_size;
safe_size += PaintOpWriter::HeaderBytes();
safe_size += sizeof(uint32_t); // color type
safe_size += sizeof(uint32_t); // width
@@ -90,7 +90,7 @@ ClientImageTransferCacheEntry::~ClientImageTransferCacheEntry() = default;
// static
base::AtomicSequenceNumber ClientImageTransferCacheEntry::s_next_id_;
-size_t ClientImageTransferCacheEntry::SerializedSize() const {
+uint32_t ClientImageTransferCacheEntry::SerializedSize() const {
return size_;
}
@@ -144,7 +144,9 @@ bool ServiceImageTransferCacheEntry::Deserialize(
// We don't need to populate the DeSerializeOptions here since the reader is
// only used for de-serializing primitives.
- PaintOp::DeserializeOptions options(nullptr, nullptr, nullptr);
+ std::vector<uint8_t> scratch_buffer;
+ PaintOp::DeserializeOptions options(nullptr, nullptr, nullptr,
+ &scratch_buffer);
PaintOpReader reader(data.data(), data.size(), options);
SkColorType color_type;
reader.Read(&color_type);
diff --git a/chromium/cc/paint/image_transfer_cache_entry.h b/chromium/cc/paint/image_transfer_cache_entry.h
index db31ade3796..7b563c44e63 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.h
+++ b/chromium/cc/paint/image_transfer_cache_entry.h
@@ -31,7 +31,7 @@ class CC_PAINT_EXPORT ClientImageTransferCacheEntry
uint32_t Id() const final;
// ClientTransferCacheEntry implementation:
- size_t SerializedSize() const final;
+ uint32_t SerializedSize() const final;
bool Serialize(base::span<uint8_t> data) const final;
private:
@@ -39,7 +39,7 @@ class CC_PAINT_EXPORT ClientImageTransferCacheEntry
const SkPixmap* const pixmap_;
const SkColorSpace* const target_color_space_;
const bool needs_mips_;
- size_t size_ = 0;
+ uint32_t size_ = 0;
static base::AtomicSequenceNumber s_next_id_;
};
diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc
index f86a674a381..11b5f62250d 100644
--- a/chromium/cc/paint/oop_pixeltest.cc
+++ b/chromium/cc/paint/oop_pixeltest.cc
@@ -130,7 +130,6 @@ class OopPixelTest : public testing::Test,
SkColor background_color = SK_ColorBLACK;
int msaa_sample_count = 0;
bool use_lcd_text = false;
- SkColorType color_type = kRGBA_8888_SkColorType;
gfx::Size resource_size;
gfx::Size content_size;
gfx::Rect full_raster_rect;
@@ -184,7 +183,7 @@ class OopPixelTest : public testing::Test,
if (options.preclear) {
raster_implementation->BeginRasterCHROMIUM(
options.preclear_color, options.msaa_sample_count,
- options.use_lcd_text, options.color_type, color_space, mailbox.name);
+ options.use_lcd_text, color_space, mailbox.name);
raster_implementation->EndRasterCHROMIUM();
}
@@ -192,7 +191,7 @@ class OopPixelTest : public testing::Test,
raster_implementation->BeginRasterCHROMIUM(
options.background_color, options.msaa_sample_count,
- options.use_lcd_text, options.color_type, color_space, mailbox.name);
+ options.use_lcd_text, color_space, mailbox.name);
raster_implementation->RasterCHROMIUM(
display_item_list.get(), &image_provider, options.content_size,
options.full_raster_rect, options.playback_rect, options.post_translate,
@@ -1616,8 +1615,8 @@ class OopPathPixelTest : public OopPixelTest,
void RunTest() {
auto* ri = static_cast<gpu::raster::RasterImplementation*>(
raster_context_provider_->RasterInterface());
- size_t max_inlined_entry_size =
- AllowInlining() ? std::numeric_limits<size_t>::max() : 0u;
+ uint32_t max_inlined_entry_size =
+ AllowInlining() ? std::numeric_limits<uint32_t>::max() : 0u;
ri->set_max_inlined_entry_size_for_testing(max_inlined_entry_size);
RasterOptions options;
diff --git a/chromium/cc/paint/paint_cache.cc b/chromium/cc/paint/paint_cache.cc
index b3fad275dba..dc73c6e300e 100644
--- a/chromium/cc/paint/paint_cache.cc
+++ b/chromium/cc/paint/paint_cache.cc
@@ -52,7 +52,7 @@ void ClientPaintCache::FinalizePendingEntries() {
}
void ClientPaintCache::AbortPendingEntries() {
- for (const auto& entry : pending_entries_.container()) {
+ for (const auto& entry : pending_entries_) {
auto it = cache_map_.Peek(entry);
DCHECK(it != cache_map_.end());
EraseFromMap(it);
diff --git a/chromium/cc/paint/paint_canvas.h b/chromium/cc/paint/paint_canvas.h
index 80a6915472d..df30609c606 100644
--- a/chromium/cc/paint/paint_canvas.h
+++ b/chromium/cc/paint/paint_canvas.h
@@ -55,9 +55,7 @@ class CC_PAINT_EXPORT PaintCanvas {
virtual int save() = 0;
virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
- virtual int saveLayerAlpha(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests) = 0;
+ virtual int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) = 0;
virtual void restore() = 0;
virtual int getSaveCount() const = 0;
diff --git a/chromium/cc/paint/paint_flags.cc b/chromium/cc/paint/paint_flags.cc
index c0ff3a6aa47..dcdb3c3a7f8 100644
--- a/chromium/cc/paint/paint_flags.cc
+++ b/chromium/cc/paint/paint_flags.cc
@@ -24,8 +24,6 @@ PaintFlags::PaintFlags() {
bitfields_.cap_type_ = SkPaint::kDefault_Cap;
bitfields_.join_type_ = SkPaint::kDefault_Join;
bitfields_.style_ = SkPaint::kFill_Style;
- bitfields_.text_encoding_ = SkPaint::kUTF8_TextEncoding;
- bitfields_.hinting_ = static_cast<unsigned>(SkFontHinting::kNormal);
bitfields_.filter_quality_ = SkFilterQuality::kNone_SkFilterQuality;
static_assert(sizeof(bitfields_) <= sizeof(bitfields_uint_),
@@ -43,7 +41,6 @@ PaintFlags::~PaintFlags() {
blend_mode_ = static_cast<uint32_t>(SkBlendMode::kLastMode);
// Free refcounted objects one by one.
- typeface_.reset();
path_effect_.reset();
shader_.reset();
mask_filter_.reset();
@@ -127,7 +124,6 @@ bool PaintFlags::SupportsFoldingAlpha() const {
SkPaint PaintFlags::ToSkPaint() const {
SkPaint paint;
- paint.setTypeface(typeface_);
paint.setPathEffect(path_effect_);
if (shader_)
paint.setShader(shader_->GetSkShader());
@@ -136,40 +132,19 @@ SkPaint PaintFlags::ToSkPaint() const {
paint.setDrawLooper(draw_looper_);
if (image_filter_)
paint.setImageFilter(image_filter_->cached_sk_filter_);
- paint.setTextSize(text_size_);
paint.setColor(color_);
paint.setStrokeWidth(width_);
paint.setStrokeMiter(miter_limit_);
paint.setBlendMode(getBlendMode());
- paint.setFlags(bitfields_.flags_);
+ paint.setAntiAlias(bitfields_.antialias_);
+ paint.setDither(bitfields_.dither_);
paint.setStrokeCap(static_cast<SkPaint::Cap>(getStrokeCap()));
paint.setStrokeJoin(static_cast<SkPaint::Join>(getStrokeJoin()));
paint.setStyle(static_cast<SkPaint::Style>(getStyle()));
- paint.setTextEncoding(static_cast<SkPaint::TextEncoding>(getTextEncoding()));
- paint.setHinting(static_cast<SkFontHinting>(getHinting()));
paint.setFilterQuality(getFilterQuality());
return paint;
}
-SkFont PaintFlags::ToSkFont() const {
- SkFont font;
- font.setTypeface(typeface_);
- font.setSize(text_size_);
- font.setHinting(static_cast<SkFontHinting>(getHinting()));
- font.setForceAutoHinting(isAutohinted());
- font.setSubpixel(isSubpixelText());
- if (isAntiAlias()) {
- if (isLCDRenderText()) {
- font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
- } else {
- font.setEdging(SkFont::Edging::kAntiAlias);
- }
- } else {
- font.setEdging(SkFont::Edging::kAlias);
- }
- return font;
-}
-
bool PaintFlags::IsValid() const {
return PaintOp::IsValidPaintFlagsSkBlendMode(getBlendMode());
}
@@ -178,8 +153,6 @@ bool PaintFlags::operator==(const PaintFlags& other) const {
// Can't just ToSkPaint and operator== here as SkPaint does pointer
// comparisons on all the ref'd skia objects on the SkPaint, which
// is not true after serialization.
- if (!PaintOp::AreEqualEvenIfNaN(getTextSize(), other.getTextSize()))
- return false;
if (getColor() != other.getColor())
return false;
if (!PaintOp::AreEqualEvenIfNaN(getStrokeWidth(), other.getStrokeWidth()))
@@ -194,14 +167,9 @@ bool PaintFlags::operator==(const PaintFlags& other) const {
return false;
if (getStyle() != other.getStyle())
return false;
- if (getTextEncoding() != other.getTextEncoding())
- return false;
- if (getHinting() != other.getHinting())
- return false;
if (getFilterQuality() != other.getFilterQuality())
return false;
- // TODO(enne): compare typeface too
if (!PaintOp::AreSkFlattenablesEqual(getPathEffect().get(),
other.getPathEffect().get())) {
return false;
@@ -237,8 +205,8 @@ bool PaintFlags::HasDiscardableImages() const {
}
size_t PaintFlags::GetSerializedSize() const {
- return sizeof(text_size_) + sizeof(color_) + sizeof(width_) +
- sizeof(miter_limit_) + sizeof(blend_mode_) + sizeof(bitfields_uint_) +
+ return sizeof(color_) + sizeof(width_) + sizeof(miter_limit_) +
+ sizeof(blend_mode_) + sizeof(bitfields_uint_) +
PaintOpWriter::GetFlattenableSize(path_effect_.get()) +
PaintOpWriter::Alignment() +
PaintOpWriter::GetFlattenableSize(mask_filter_.get()) +
diff --git a/chromium/cc/paint/paint_flags.h b/chromium/cc/paint/paint_flags.h
index fda9cc5ba8d..64acb7861b4 100644
--- a/chromium/cc/paint/paint_flags.h
+++ b/chromium/cc/paint/paint_flags.h
@@ -11,14 +11,11 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkDrawLooper.h"
-#include "third_party/skia/include/core/SkFont.h"
-#include "third_party/skia/include/core/SkFontTypes.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPathEffect.h"
#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/core/SkTypeface.h"
namespace cc {
class PaintFilter;
@@ -56,63 +53,10 @@ class CC_PAINT_EXPORT PaintFlags {
ALWAYS_INLINE SkBlendMode getBlendMode() const {
return static_cast<SkBlendMode>(blend_mode_);
}
- ALWAYS_INLINE bool isAntiAlias() const {
- return !!(bitfields_.flags_ & SkPaint::kAntiAlias_Flag);
- }
- ALWAYS_INLINE void setAntiAlias(bool aa) {
- SetInternalFlag(aa, SkPaint::kAntiAlias_Flag);
- }
- ALWAYS_INLINE bool isSubpixelText() const {
- return !!(bitfields_.flags_ & SkPaint::kSubpixelText_Flag);
- }
- ALWAYS_INLINE void setSubpixelText(bool subpixel_text) {
- SetInternalFlag(subpixel_text, SkPaint::kSubpixelText_Flag);
- }
- ALWAYS_INLINE bool isLCDRenderText() const {
- return !!(bitfields_.flags_ & SkPaint::kLCDRenderText_Flag);
- }
- ALWAYS_INLINE void setLCDRenderText(bool lcd_text) {
- SetInternalFlag(lcd_text, SkPaint::kLCDRenderText_Flag);
- }
- enum Hinting {
- kNo_Hinting = static_cast<unsigned>(SkFontHinting::kNone),
- kSlight_Hinting = static_cast<unsigned>(SkFontHinting::kSlight),
- kNormal_Hinting =
- static_cast<unsigned>(SkFontHinting::kNormal), //!< this is the default
- kFull_Hinting = static_cast<unsigned>(SkFontHinting::kFull)
- };
- ALWAYS_INLINE Hinting getHinting() const {
- return static_cast<Hinting>(bitfields_.hinting_);
- }
- ALWAYS_INLINE void setHinting(Hinting hinting) {
- bitfields_.hinting_ = hinting;
- }
- ALWAYS_INLINE bool isAutohinted() const {
- return !!(bitfields_.flags_ & SkPaint::kAutoHinting_Flag);
- }
- ALWAYS_INLINE void setAutohinted(bool use_auto_hinter) {
- SetInternalFlag(use_auto_hinter, SkPaint::kAutoHinting_Flag);
- }
- ALWAYS_INLINE bool isDither() const {
- return !!(bitfields_.flags_ & SkPaint::kDither_Flag);
- }
- ALWAYS_INLINE void setDither(bool dither) {
- SetInternalFlag(dither, SkPaint::kDither_Flag);
- }
- enum TextEncoding {
- kUTF8_TextEncoding = SkPaint::kUTF8_TextEncoding,
- kUTF16_TextEncoding = SkPaint::kUTF16_TextEncoding,
- kUTF32_TextEncoding = SkPaint::kUTF32_TextEncoding,
- kGlyphID_TextEncoding = SkPaint::kGlyphID_TextEncoding
- };
- ALWAYS_INLINE TextEncoding getTextEncoding() const {
- return static_cast<TextEncoding>(bitfields_.text_encoding_);
- }
- ALWAYS_INLINE void setTextEncoding(TextEncoding encoding) {
- bitfields_.text_encoding_ = encoding;
- }
- ALWAYS_INLINE SkScalar getTextSize() const { return text_size_; }
- ALWAYS_INLINE void setTextSize(SkScalar text_size) { text_size_ = text_size; }
+ ALWAYS_INLINE bool isAntiAlias() const { return bitfields_.antialias_; }
+ ALWAYS_INLINE void setAntiAlias(bool aa) { bitfields_.antialias_ = aa; }
+ ALWAYS_INLINE bool isDither() const { return bitfields_.dither_; }
+ ALWAYS_INLINE void setDither(bool dither) { bitfields_.dither_ = dither; }
ALWAYS_INLINE void setFilterQuality(SkFilterQuality quality) {
bitfields_.filter_quality_ = quality;
}
@@ -148,12 +92,6 @@ class CC_PAINT_EXPORT PaintFlags {
}
ALWAYS_INLINE void setStrokeJoin(Join join) { bitfields_.join_type_ = join; }
- ALWAYS_INLINE const sk_sp<SkTypeface>& getTypeface() const {
- return typeface_;
- }
- ALWAYS_INLINE void setTypeface(sk_sp<SkTypeface> typeface) {
- typeface_ = std::move(typeface);
- }
ALWAYS_INLINE const sk_sp<SkColorFilter>& getColorFilter() const {
return color_filter_;
}
@@ -209,7 +147,6 @@ class CC_PAINT_EXPORT PaintFlags {
bool SupportsFoldingAlpha() const;
SkPaint ToSkPaint() const;
- SkFont ToSkFont() const;
bool IsValid() const;
bool operator==(const PaintFlags& other) const;
@@ -223,14 +160,6 @@ class CC_PAINT_EXPORT PaintFlags {
friend class PaintOpReader;
friend class PaintOpWriter;
- ALWAYS_INLINE void SetInternalFlag(bool value, uint32_t mask) {
- if (value)
- bitfields_.flags_ |= mask;
- else
- bitfields_.flags_ &= ~mask;
- }
-
- sk_sp<SkTypeface> typeface_;
sk_sp<SkPathEffect> path_effect_;
sk_sp<PaintShader> shader_;
sk_sp<SkMaskFilter> mask_filter_;
@@ -240,19 +169,17 @@ class CC_PAINT_EXPORT PaintFlags {
// Match(ish) SkPaint defaults. SkPaintDefaults is not public, so this
// just uses these values and ignores any SkUserConfig overrides.
- float text_size_ = 12.f;
SkColor color_ = SK_ColorBLACK;
float width_ = 0.f;
float miter_limit_ = 4.f;
uint32_t blend_mode_ = static_cast<uint32_t>(SkBlendMode::kSrcOver);
struct PaintFlagsBitfields {
- uint32_t flags_ : 16;
+ uint32_t antialias_ : 1;
+ uint32_t dither_ : 1;
uint32_t cap_type_ : 2;
uint32_t join_type_ : 2;
uint32_t style_ : 2;
- uint32_t text_encoding_ : 2;
- uint32_t hinting_ : 2;
uint32_t filter_quality_ : 2;
};
diff --git a/chromium/cc/paint/paint_image.h b/chromium/cc/paint/paint_image.h
index 0684c2d80c6..c71fe7217a4 100644
--- a/chromium/cc/paint/paint_image.h
+++ b/chromium/cc/paint/paint_image.h
@@ -9,9 +9,11 @@
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/memory/scoped_refptr.h"
#include "cc/paint/frame_metadata.h"
#include "cc/paint/image_animation_count.h"
#include "cc/paint/paint_export.h"
+#include "cc/paint/paint_worklet_input.h"
#include "third_party/skia/include/core/SkImage.h"
#include "ui/gfx/geometry/rect.h"
@@ -76,7 +78,7 @@ class CC_PAINT_EXPORT PaintImage {
bool operator==(const FrameKey& other) const;
bool operator!=(const FrameKey& other) const;
- uint64_t hash() const { return hash_; }
+ size_t hash() const { return hash_; }
std::string ToString() const;
size_t frame_index() const { return frame_index_; }
ContentId content_id() const { return content_id_; }
@@ -173,13 +175,32 @@ class CC_PAINT_EXPORT PaintImage {
PaintImage::ContentId content_id() const { return content_id_; }
// TODO(vmpstr): Don't get the SkImage here if you don't need to.
- uint32_t unique_id() const { return GetSkImage()->uniqueID(); }
- explicit operator bool() const { return !!GetSkImage(); }
- bool IsLazyGenerated() const { return GetSkImage()->isLazyGenerated(); }
- bool IsTextureBacked() const { return GetSkImage()->isTextureBacked(); }
- int width() const { return GetSkImage()->width(); }
- int height() const { return GetSkImage()->height(); }
- SkColorSpace* color_space() const { return GetSkImage()->colorSpace(); }
+ uint32_t unique_id() const {
+ return paint_worklet_input_ ? 0 : GetSkImage()->uniqueID();
+ }
+ explicit operator bool() const {
+ return paint_worklet_input_ || !!GetSkImage();
+ }
+ bool IsLazyGenerated() const {
+ return paint_worklet_input_ ? false : GetSkImage()->isLazyGenerated();
+ }
+ bool IsPaintWorklet() const { return !!paint_worklet_input_; }
+ bool IsTextureBacked() const {
+ return paint_worklet_input_ ? false : GetSkImage()->isTextureBacked();
+ }
+ int width() const {
+ return paint_worklet_input_
+ ? static_cast<int>(paint_worklet_input_->GetSize().width())
+ : GetSkImage()->width();
+ }
+ int height() const {
+ return paint_worklet_input_
+ ? static_cast<int>(paint_worklet_input_->GetSize().height())
+ : GetSkImage()->height();
+ }
+ SkColorSpace* color_space() const {
+ return paint_worklet_input_ ? nullptr : GetSkImage()->colorSpace();
+ }
// Returns the color type of this image.
SkColorType GetColorType() const;
@@ -198,6 +219,10 @@ class CC_PAINT_EXPORT PaintImage {
sk_sp<SkImage> GetSkImageForFrame(size_t index,
GeneratorClientId client_id) const;
+ PaintWorkletInput* paint_worklet_input() const {
+ return paint_worklet_input_.get();
+ }
+
std::string ToString() const;
private:
@@ -260,6 +285,9 @@ class CC_PAINT_EXPORT PaintImage {
// skia's cache.
// 2) Ensures that accesses to it are thread-safe.
sk_sp<SkImage> cached_sk_image_;
+
+ // The input parameters that are needed to execute the JS paint callback.
+ scoped_refptr<PaintWorkletInput> paint_worklet_input_;
};
} // namespace cc
diff --git a/chromium/cc/paint/paint_image_builder.cc b/chromium/cc/paint/paint_image_builder.cc
index d6741c1cf99..d8b3199f935 100644
--- a/chromium/cc/paint/paint_image_builder.cc
+++ b/chromium/cc/paint/paint_image_builder.cc
@@ -45,6 +45,7 @@ PaintImage PaintImageBuilder::TakePaintImage() {
DCHECK(!paint_image_.paint_record_);
DCHECK(!paint_image_.paint_image_generator_);
DCHECK(!paint_image_.sk_image_->isLazyGenerated());
+ DCHECK(!paint_image_.paint_worklet_input_);
// TODO(khushalsagar): Assert that we don't have an animated image type
// here. The only case where this is possible is DragImage. There are 2 use
// cases going through that path, re-orienting the image and for use by the
@@ -55,11 +56,17 @@ PaintImage PaintImageBuilder::TakePaintImage() {
} else if (paint_image_.paint_record_) {
DCHECK(!paint_image_.sk_image_);
DCHECK(!paint_image_.paint_image_generator_);
+ DCHECK(!paint_image_.paint_worklet_input_);
// TODO(khushalsagar): Assert that we don't have an animated image type
// here.
} else if (paint_image_.paint_image_generator_) {
DCHECK(!paint_image_.sk_image_);
DCHECK(!paint_image_.paint_record_);
+ DCHECK(!paint_image_.paint_worklet_input_);
+ } else if (paint_image_.paint_worklet_input_) {
+ DCHECK(!paint_image_.sk_image_);
+ DCHECK(!paint_image_.paint_record_);
+ DCHECK(!paint_image_.paint_image_generator_);
}
if (paint_image_.ShouldAnimate()) {
diff --git a/chromium/cc/paint/paint_image_builder.h b/chromium/cc/paint/paint_image_builder.h
index d12705003c1..52e7ec8b181 100644
--- a/chromium/cc/paint/paint_image_builder.h
+++ b/chromium/cc/paint/paint_image_builder.h
@@ -98,6 +98,11 @@ class CC_PAINT_EXPORT PaintImageBuilder {
paint_image_.decoding_mode_ = decoding_mode;
return std::move(*this);
}
+ PaintImageBuilder&& set_paint_worklet_input(
+ scoped_refptr<PaintWorkletInput> input) {
+ paint_image_.paint_worklet_input_ = std::move(input);
+ return std::move(*this);
+ }
PaintImage TakePaintImage();
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 7ae8135f509..4516fec0c83 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -302,8 +302,11 @@ size_t SimpleSerialize(const PaintOp* op, void* memory, size_t size) {
return sizeof(T);
}
-PlaybackParams::PlaybackParams(ImageProvider* image_provider)
+PlaybackParams::PlaybackParams(
+ ImageProvider* image_provider,
+ PaintWorkletImageProvider* paint_worklet_image_provider)
: image_provider(image_provider),
+ paint_worklet_image_provider(paint_worklet_image_provider),
original_ctm(SkMatrix::I()),
custom_callback(CustomDataRasterCallback()),
did_draw_op_callback(DidDrawOpCallback()) {}
@@ -355,10 +358,14 @@ PaintOp::SerializeOptions& PaintOp::SerializeOptions::operator=(
PaintOp::DeserializeOptions::DeserializeOptions(
TransferCacheDeserializeHelper* transfer_cache,
ServicePaintCache* paint_cache,
- SkStrikeClient* strike_client)
+ SkStrikeClient* strike_client,
+ std::vector<uint8_t>* scratch_buffer)
: transfer_cache(transfer_cache),
paint_cache(paint_cache),
- strike_client(strike_client) {}
+ strike_client(strike_client),
+ scratch_buffer(scratch_buffer) {
+ DCHECK(scratch_buffer);
+}
size_t AnnotateOp::Serialize(const PaintOp* base_op,
void* memory,
@@ -1393,14 +1400,7 @@ void SaveLayerAlphaOp::Raster(const SaveLayerAlphaOp* op,
const PlaybackParams& params) {
// See PaintOp::kUnsetRect
bool unset = op->bounds.left() == SK_ScalarInfinity;
- if (op->preserve_lcd_text_requests) {
- SkPaint paint;
- paint.setAlpha(op->alpha);
- canvas->saveLayerPreserveLCDTextRequests(unset ? nullptr : &op->bounds,
- &paint);
- } else {
- canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha);
- }
+ canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha);
}
void ScaleOp::Raster(const ScaleOp* op,
@@ -1814,8 +1814,6 @@ bool SaveLayerAlphaOp::AreEqual(const PaintOp* base_left,
return false;
if (left->alpha != right->alpha)
return false;
- if (left->preserve_lcd_text_requests != right->preserve_lcd_text_requests)
- return false;
return true;
}
@@ -2387,6 +2385,8 @@ void PaintOpBuffer::Playback(SkCanvas* canvas,
PlaybackParams new_params(params.image_provider, canvas->getTotalMatrix(),
params.custom_callback,
params.did_draw_op_callback);
+ // TODO(xidachen): retrieve the PaintRecord stored in PaintWorkletImageCache,
+ // from the PaintWorkletImageProvider in the params.
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 a4a3ae89f72..028a476ce87 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -18,7 +18,6 @@
#include "base/memory/aligned_memory.h"
#include "base/optional.h"
#include "cc/base/math_util.h"
-#include "cc/paint/image_provider.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_export.h"
#include "cc/paint/paint_flags.h"
@@ -40,7 +39,9 @@ class SkStrikeServer;
// See: third_party/skia/src/core/SkLiteDL.h.
namespace cc {
class ClientPaintCache;
+class ImageProvider;
class ServicePaintCache;
+class PaintWorkletImageProvider;
class CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix {
public:
@@ -107,7 +108,9 @@ struct CC_PAINT_EXPORT PlaybackParams {
base::RepeatingCallback<void(SkCanvas* canvas, uint32_t id)>;
using DidDrawOpCallback = base::RepeatingCallback<void()>;
- explicit PlaybackParams(ImageProvider* image_provider);
+ explicit PlaybackParams(
+ ImageProvider* image_provider,
+ PaintWorkletImageProvider* paint_worklet_image_provider = nullptr);
PlaybackParams(
ImageProvider* image_provider,
const SkMatrix& original_ctm,
@@ -119,6 +122,7 @@ struct CC_PAINT_EXPORT PlaybackParams {
PlaybackParams& operator=(const PlaybackParams& other);
ImageProvider* image_provider;
+ PaintWorkletImageProvider* paint_worklet_image_provider;
SkMatrix original_ctm;
CustomDataRasterCallback custom_callback;
DidDrawOpCallback did_draw_op_callback;
@@ -181,13 +185,16 @@ class CC_PAINT_EXPORT PaintOp {
struct CC_PAINT_EXPORT DeserializeOptions {
DeserializeOptions(TransferCacheDeserializeHelper* transfer_cache,
ServicePaintCache* paint_cache,
- SkStrikeClient* strike_client);
+ SkStrikeClient* strike_client,
+ std::vector<uint8_t>* scratch_buffer);
TransferCacheDeserializeHelper* transfer_cache = nullptr;
ServicePaintCache* paint_cache = nullptr;
SkStrikeClient* strike_client = nullptr;
uint32_t raster_color_space_id = gfx::ColorSpace::kInvalidId;
// Do a DumpWithoutCrashing when serialization fails.
bool crash_dump_on_failure = false;
+ // Used to memcpy Skia flattenables into to avoid TOCTOU issues.
+ std::vector<uint8_t>* scratch_buffer = nullptr;
};
// Indicates how PaintImages are serialized.
@@ -270,9 +277,7 @@ class CC_PAINT_EXPORT PaintOp {
static_cast<uint32_t>(SkClipOp::kMax_EnumValue);
}
- static bool IsValidPath(const SkPath& path) {
- return path.isValid() && path.pathRefIsValid();
- }
+ static bool IsValidPath(const SkPath& path) { return path.isValid(); }
static bool IsUnsetRect(const SkRect& rect) {
return rect.fLeft == SK_ScalarInfinity;
@@ -827,13 +832,8 @@ class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlags {
class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp {
public:
static constexpr PaintOpType kType = PaintOpType::SaveLayerAlpha;
- SaveLayerAlphaOp(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests)
- : PaintOp(kType),
- bounds(bounds ? *bounds : kUnsetRect),
- alpha(alpha),
- preserve_lcd_text_requests(preserve_lcd_text_requests) {}
+ SaveLayerAlphaOp(const SkRect* bounds, uint8_t alpha)
+ : PaintOp(kType), bounds(bounds ? *bounds : kUnsetRect), alpha(alpha) {}
static void Raster(const SaveLayerAlphaOp* op,
SkCanvas* canvas,
const PlaybackParams& params);
@@ -843,7 +843,6 @@ class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp {
SkRect bounds;
uint8_t alpha;
- bool preserve_lcd_text_requests;
};
class CC_PAINT_EXPORT ScaleOp final : public PaintOp {
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index c91d62fbfa8..d7fcd2edcb7 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -68,8 +68,9 @@ void Raster(scoped_refptr<viz::TestContextProvider> context_provider,
cc::PlaybackParams params(nullptr, canvas->getTotalMatrix());
cc::TransferCacheTestHelper transfer_cache_helper;
+ std::vector<uint8_t> scratch_buffer;
cc::PaintOp::DeserializeOptions deserialize_options(
- &transfer_cache_helper, paint_cache, strike_client);
+ &transfer_cache_helper, paint_cache, strike_client, &scratch_buffer);
// Need 4 bytes to be able to read the type/skip.
while (size >= 4) {
@@ -111,7 +112,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::CommandLine::Init(0, nullptr);
// Partition the data to use some bytes for populating the font cache.
- size_t bytes_for_fonts = data[0];
+ uint32_t bytes_for_fonts = data[0];
if (bytes_for_fonts > size)
bytes_for_fonts = size / 2;
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.cc b/chromium/cc/paint/paint_op_buffer_serializer.cc
index 5802b3c369d..f7f7f4f9d06 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.cc
+++ b/chromium/cc/paint/paint_op_buffer_serializer.cc
@@ -405,8 +405,8 @@ SimpleBufferSerializer::SimpleBufferSerializer(
int max_texture_size,
size_t max_texture_bytes)
: PaintOpBufferSerializer(
- base::Bind(&SimpleBufferSerializer::SerializeToMemory,
- base::Unretained(this)),
+ base::BindRepeating(&SimpleBufferSerializer::SerializeToMemory,
+ base::Unretained(this)),
image_provider,
transfer_cache,
paint_cache,
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.h b/chromium/cc/paint/paint_op_buffer_serializer.h
index 4dfd6c13c97..341767468a7 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.h
+++ b/chromium/cc/paint/paint_op_buffer_serializer.h
@@ -17,7 +17,8 @@ class TransferCacheSerializeHelper;
class CC_PAINT_EXPORT PaintOpBufferSerializer {
public:
using SerializeCallback =
- base::Callback<size_t(const PaintOp*, const PaintOp::SerializeOptions&)>;
+ base::RepeatingCallback<size_t(const PaintOp*,
+ const PaintOp::SerializeOptions&)>;
PaintOpBufferSerializer(SerializeCallback serialize_cb,
ImageProvider* image_provider,
diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc
index 8e007c409db..4df17de7e1c 100644
--- a/chromium/cc/paint/paint_op_buffer_unittest.cc
+++ b/chromium/cc/paint/paint_op_buffer_unittest.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "cc/paint/paint_op_buffer.h"
+
+#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "cc/paint/decoded_draw_image.h"
#include "cc/paint/display_item_list.h"
@@ -213,7 +215,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags draw_flags;
draw_flags.setColor(SK_ColorMAGENTA);
@@ -243,7 +245,7 @@ TEST(PaintOpBufferTest, SaveDrawRestoreFail_BadFlags) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags draw_flags;
draw_flags.setColor(SK_ColorMAGENTA);
@@ -270,7 +272,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_BadFlags255Alpha) {
PaintOpBuffer buffer;
uint8_t alpha = 255;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags draw_flags;
draw_flags.setColor(SK_ColorMAGENTA);
@@ -295,7 +297,7 @@ TEST(PaintOpBufferTest, SaveDrawRestoreFail_TooManyOps) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags draw_flags;
draw_flags.setColor(SK_ColorMAGENTA);
@@ -322,7 +324,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpNotADrawOp) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
buffer.push<NoopOp>();
buffer.push<RestoreOp>();
@@ -350,7 +352,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleOp) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
buffer.push<DrawRecordOp>(std::move(record));
buffer.push<RestoreOp>();
@@ -378,7 +380,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleNonDrawOp) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
buffer.push<DrawRecordOp>(std::move(record));
buffer.push<RestoreOp>();
@@ -394,7 +396,7 @@ TEST(PaintOpBufferTest, SaveLayerRestore_DrawColor) {
uint8_t alpha = 100;
SkColor original = SkColorSetA(50, SK_ColorRED);
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
buffer.push<DrawColorOp>(original, SkBlendMode::kSrcOver);
buffer.push<RestoreOp>();
@@ -731,7 +733,7 @@ TEST_F(PaintOpBufferOffsetsTest, ContiguousIndicesWithSaveLayerAlphaRestore) {
push_op<DrawColorOp>(0u, SkBlendMode::kClear);
push_op<DrawColorOp>(1u, SkBlendMode::kClear);
uint8_t alpha = 100;
- push_op<SaveLayerAlphaOp>(nullptr, alpha, true);
+ push_op<SaveLayerAlphaOp>(nullptr, alpha);
push_op<RestoreOp>();
push_op<DrawColorOp>(2u, SkBlendMode::kClear);
push_op<DrawColorOp>(3u, SkBlendMode::kClear);
@@ -757,7 +759,7 @@ TEST_F(PaintOpBufferOffsetsTest,
push_op<DrawColorOp>(0u, SkBlendMode::kClear);
push_op<DrawColorOp>(1u, SkBlendMode::kClear);
uint8_t alpha = 100;
- push_op<SaveLayerAlphaOp>(nullptr, alpha, true);
+ push_op<SaveLayerAlphaOp>(nullptr, alpha);
push_op<DrawColorOp>(2u, SkBlendMode::kClear);
push_op<DrawColorOp>(3u, SkBlendMode::kClear);
push_op<RestoreOp>();
@@ -807,7 +809,7 @@ TEST_F(PaintOpBufferOffsetsTest,
add_draw_rect(0u);
add_draw_rect(1u);
uint8_t alpha = 100;
- push_op<SaveLayerAlphaOp>(nullptr, alpha, true);
+ push_op<SaveLayerAlphaOp>(nullptr, alpha);
add_draw_rect(2u);
push_op<RestoreOp>();
add_draw_rect(3u);
@@ -840,7 +842,7 @@ TEST_F(PaintOpBufferOffsetsTest,
add_draw_rect(0u);
add_draw_rect(1u);
uint8_t alpha = 100;
- push_op<SaveLayerAlphaOp>(nullptr, alpha, true);
+ push_op<SaveLayerAlphaOp>(nullptr, alpha);
add_draw_rect(2u);
add_draw_rect(3u);
add_draw_rect(4u);
@@ -899,7 +901,7 @@ TEST(PaintOpBufferTest, SaveLayerAlphaDrawRestoreWithBadBlendMode) {
add_draw_rect(&buffer, 0u);
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, true);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
add_draw_rect(&buffer, 1u);
buffer.push<RestoreOp>();
add_draw_rect(&buffer, 2u);
@@ -928,9 +930,9 @@ TEST(PaintOpBufferTest, UnmatchedSaveRestoreNoSideEffects) {
// Push 2 saves.
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, true);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
add_draw_rect(&buffer, 0u);
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, true);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
add_draw_rect(&buffer, 1u);
add_draw_rect(&buffer, 2u);
// But only 1 restore.
@@ -1040,7 +1042,6 @@ std::vector<PaintFlags> test_flags = {
PaintFlags(),
[] {
PaintFlags flags;
- flags.setTextSize(82.7f);
flags.setColor(SK_ColorMAGENTA);
flags.setStrokeWidth(4.2f);
flags.setStrokeMiter(5.91f);
@@ -1048,15 +1049,12 @@ std::vector<PaintFlags> test_flags = {
flags.setStrokeCap(PaintFlags::kSquare_Cap);
flags.setStrokeJoin(PaintFlags::kBevel_Join);
flags.setStyle(PaintFlags::kStrokeAndFill_Style);
- flags.setTextEncoding(PaintFlags::kGlyphID_TextEncoding);
- flags.setHinting(PaintFlags::kNormal_Hinting);
flags.setFilterQuality(SkFilterQuality::kMedium_SkFilterQuality);
flags.setShader(PaintShader::MakeColor(SkColorSetARGB(1, 2, 3, 4)));
return flags;
}(),
[] {
PaintFlags flags;
- flags.setTextSize(0.0f);
flags.setColor(SK_ColorCYAN);
flags.setAlpha(103);
flags.setStrokeWidth(0.32f);
@@ -1065,8 +1063,6 @@ std::vector<PaintFlags> test_flags = {
flags.setStrokeCap(PaintFlags::kRound_Cap);
flags.setStrokeJoin(PaintFlags::kRound_Join);
flags.setStyle(PaintFlags::kFill_Style);
- flags.setTextEncoding(PaintFlags::kUTF32_TextEncoding);
- flags.setHinting(PaintFlags::kSlight_Hinting);
flags.setFilterQuality(SkFilterQuality::kHigh_SkFilterQuality);
SkScalar intervals[] = {1.f, 1.f};
@@ -1167,8 +1163,7 @@ std::vector<sk_sp<SkTextBlob>> test_paint_blobs = {
SkTextBlobBuilder builder;
int glyph_count = 5;
- const auto& run =
- builder.allocRun(font, glyph_count, 1.2f, 2.3f, &test_rects[0]);
+ const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f);
// allocRun() allocates only the glyph buffer.
std::fill(run.glyphs, run.glyphs + glyph_count, 0);
return builder.make();
@@ -1179,13 +1174,12 @@ std::vector<sk_sp<SkTextBlob>> test_paint_blobs = {
SkTextBlobBuilder builder;
int glyph_count = 5;
- const auto& run1 =
- builder.allocRun(font, glyph_count, 1.2f, 2.3f, &test_rects[0]);
+ const auto& run1 = builder.allocRun(font, glyph_count, 1.2f, 2.3f);
// allocRun() allocates only the glyph buffer.
std::fill(run1.glyphs, run1.glyphs + glyph_count, 0);
glyph_count = 16;
- const auto& run2 = builder.allocRunPos(font, glyph_count, &test_rects[1]);
+ const auto& run2 = builder.allocRunPos(font, glyph_count);
// allocRun() allocates the glyph buffer, and 2 scalars per glyph for the
// pos buffer.
std::fill(run2.glyphs, run2.glyphs + glyph_count, 0);
@@ -1193,8 +1187,7 @@ std::vector<sk_sp<SkTextBlob>> test_paint_blobs = {
font.setTypeface(test_typefaces[1][1]);
glyph_count = 8;
- const auto& run3 =
- builder.allocRunPosH(font, glyph_count, 0, &test_rects[2]);
+ const auto& run3 = builder.allocRunPosH(font, glyph_count, 0);
// allocRun() allocates the glyph buffer, and 1 scalar per glyph for the
// pos buffer.
std::fill(run3.glyphs, run3.glyphs + glyph_count, 0);
@@ -1568,10 +1561,10 @@ void PushSaveLayerOps(PaintOpBuffer* buffer) {
void PushSaveLayerAlphaOps(PaintOpBuffer* buffer) {
size_t len = std::min(test_uint8s.size(), test_rects.size());
for (size_t i = 0; i < len; ++i)
- buffer->push<SaveLayerAlphaOp>(&test_rects[i], test_uint8s[i], !!(i % 2));
+ buffer->push<SaveLayerAlphaOp>(&test_rects[i], test_uint8s[i]);
// Test optional args.
- buffer->push<SaveLayerAlphaOp>(nullptr, test_uint8s[0], false);
+ buffer->push<SaveLayerAlphaOp>(nullptr, test_uint8s[0]);
ValidateOps<SaveLayerAlphaOp>(buffer);
}
@@ -2254,7 +2247,7 @@ TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
- buffer.push<SaveLayerAlphaOp>(nullptr, alpha, false);
+ buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags draw_flags;
draw_flags.setColor(SK_ColorMAGENTA);
@@ -2471,11 +2464,11 @@ TEST(PaintOpBufferTest, ValidateSkBlendMode) {
static_cast<SkBlendMode>(static_cast<uint32_t>(~0)),
};
- for (size_t i = 0; i < arraysize(bad_modes_for_draw_color); ++i) {
+ for (size_t i = 0; i < base::size(bad_modes_for_draw_color); ++i) {
buffer.push<DrawColorOp>(SK_ColorMAGENTA, bad_modes_for_draw_color[i]);
}
- for (size_t i = 0; i < arraysize(bad_modes_for_flags); ++i) {
+ for (size_t i = 0; i < base::size(bad_modes_for_flags); ++i) {
PaintFlags flags = test_flags[i % test_flags.size()];
flags.setBlendMode(bad_modes_for_flags[i]);
buffer.push<DrawRectOp>(test_rects[i % test_rects.size()], flags);
@@ -2534,7 +2527,7 @@ TEST(PaintOpBufferTest, ValidateRects) {
buffer.push<DrawRectOp>(bad_rect, test_flags[0]);
buffer.push<SaveLayerOp>(&bad_rect, nullptr);
buffer.push<SaveLayerOp>(&bad_rect, &test_flags[0]);
- buffer.push<SaveLayerAlphaOp>(&bad_rect, test_uint8s[0], true);
+ buffer.push<SaveLayerAlphaOp>(&bad_rect, test_uint8s[0]);
TestOptionsProvider options_provider;
@@ -3289,9 +3282,10 @@ TEST(PaintOpBufferTest, RecordShadersCached) {
// Hold onto records so PaintShader pointer comparisons are valid.
sk_sp<PaintRecord> records[5];
const SkShader* last_shader = nullptr;
+ std::vector<uint8_t> scratch_buffer;
PaintOp::DeserializeOptions deserialize_options(
transfer_cache, options_provider.service_paint_cache(),
- options_provider.strike_client());
+ options_provider.strike_client(), &scratch_buffer);
// Several deserialization test cases:
// (0) deserialize once, verify cached is the same as deserialized version
@@ -3391,9 +3385,10 @@ TEST(PaintOpBufferTest, RecordShadersCachedSize) {
options_provider.context_supports_distance_field_text();
serializer.Serialize(buffer.get());
+ std::vector<uint8_t> scratch_buffer;
PaintOp::DeserializeOptions deserialize_options(
transfer_cache, options_provider.service_paint_cache(),
- options_provider.strike_client());
+ options_provider.strike_client(), &scratch_buffer);
auto record = PaintOpBuffer::MakeFromMemory(
memory.get(), serializer.written(), deserialize_options);
auto* shader_entry =
diff --git a/chromium/cc/paint/paint_op_helper_unittest.cc b/chromium/cc/paint/paint_op_helper_unittest.cc
index eac6e4ddc62..c2682d039b4 100644
--- a/chromium/cc/paint/paint_op_helper_unittest.cc
+++ b/chromium/cc/paint/paint_op_helper_unittest.cc
@@ -65,12 +65,10 @@ TEST(PaintOpHelper, DrawDRRectToString) {
str,
"DrawDRRectOp(outer=[bounded by 1.000,2.000 3.000x4.000], inner=[bounded "
"by 5.000,6.000 7.000x8.000], flags=[color=rgba(0, 0, 0, 255), "
- "blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, hinting=kNormal_Hinting, "
- "isAutohinted=false, isDither=false, textEncoding=kUTF8_TextEncoding, "
- "textSize=12.000, filterQuality=kNone_SkFilterQuality, "
+ "blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
+ "filterQuality=kNone_SkFilterQuality, "
"strokeWidth=0.000, strokeMiter=4.000, strokeCap=kButt_Cap, "
- "strokeJoin=kMiter_Join, typeface=(nil), colorFilter=(nil), "
+ "strokeJoin=kMiter_Join, colorFilter=(nil), "
"maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
"pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
"isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
@@ -84,12 +82,9 @@ TEST(PaintOpHelper, DrawImageToString) {
str,
"DrawImageOp(image=<paint image>, left=10.500, top=20.300, "
"flags=[color=rgba(0, 0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
- "filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
+ "isDither=false, filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -105,12 +100,9 @@ TEST(PaintOpHelper, DrawImageRectToString) {
"DrawImageRectOp(image=<paint image>, src=[1.000,2.000 3.000x4.000], "
"dst=[5.000,6.000 7.000x8.000], constraint=kStrict_SrcRectConstraint, "
"flags=[color=rgba(0, 0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
- "filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
+ "isDither=false, filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -121,13 +113,10 @@ TEST(PaintOpHelper, DrawIRectToString) {
std::string str = PaintOpHelper::ToString(&op);
EXPECT_EQ(str,
"DrawIRectOp(rect=[1,2 3x4], flags=[color=rgba(0, 0, 0, 255), "
- "blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
+ "blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), "
"shader=(nil), hasShader=false, shaderIsOpaque=false, "
"pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
"isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
@@ -140,13 +129,10 @@ TEST(PaintOpHelper, DrawLineToString) {
EXPECT_EQ(
str,
"DrawLineOp(x0=1.100, y0=2.200, x1=3.300, y1=4.400, flags=[color=rgba(0, "
- "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
+ "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -158,13 +144,10 @@ TEST(PaintOpHelper, DrawOvalToString) {
EXPECT_EQ(
str,
"DrawOvalOp(oval=[100.000,200.000 300.000x400.000], flags=[color=rgba(0, "
- "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
+ "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -176,13 +159,10 @@ TEST(PaintOpHelper, DrawPathToString) {
std::string str = PaintOpHelper::ToString(&op);
EXPECT_EQ(str,
"DrawPathOp(path=<SkPath>, flags=[color=rgba(0, 0, 0, 255), "
- "blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
+ "blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), "
"shader=(nil), hasShader=false, shaderIsOpaque=false, "
"pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
"isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
@@ -202,11 +182,9 @@ TEST(PaintOpHelper, DrawRectToString) {
str,
"DrawRectOp(rect=[-1.000,-2.000 -3.000x-4.000], flags=[color=rgba(0, 0, "
"0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, hinting=kNormal_Hinting, "
- "isAutohinted=false, isDither=false, textEncoding=kUTF8_TextEncoding, "
- "textSize=12.000, filterQuality=kNone_SkFilterQuality, "
+ "isDither=false, filterQuality=kNone_SkFilterQuality, "
"strokeWidth=0.000, strokeMiter=4.000, strokeCap=kButt_Cap, "
- "strokeJoin=kMiter_Join, typeface=(nil), colorFilter=(nil), "
+ "strokeJoin=kMiter_Join, colorFilter=(nil), "
"maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
"pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
"isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
@@ -221,12 +199,9 @@ TEST(PaintOpHelper, DrawRRectToString) {
str,
"DrawRRectOp(rrect=[bounded by -1.000,-2.000 3.000x4.000], "
"flags=[color=rgba(0, 0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
- "filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
+ "isDither=false, filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -238,13 +213,10 @@ TEST(PaintOpHelper, DrawTextBlobToString) {
EXPECT_EQ(
str,
"DrawTextBlobOp(blob=(nil), x=100.000, y=-222.000, flags=[color=rgba(0, "
- "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, "
- "hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
- "textEncoding=kUTF8_TextEncoding, textSize=12.000, "
+ "0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
"strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
- "typeface=(nil), colorFilter=(nil), maskFilter=(nil), shader=(nil), "
+ "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
"hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
"imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
"supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
@@ -281,12 +253,10 @@ TEST(PaintOpHelper, SaveLayerToString) {
EXPECT_EQ(
str,
"SaveLayerOp(bounds=[1.000,2.000 3.000x4.000], flags=[color=rgba(0, 0, "
- "0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isSubpixelText=false, isLCDRenderText=false, hinting=kNormal_Hinting, "
- "isAutohinted=false, isDither=false, textEncoding=kUTF8_TextEncoding, "
- "textSize=12.000, filterQuality=kNone_SkFilterQuality, "
+ "0, 255), blendMode=kSrcOver, isAntiAlias=false, isDither=false, "
+ "filterQuality=kNone_SkFilterQuality, "
"strokeWidth=0.000, strokeMiter=4.000, strokeCap=kButt_Cap, "
- "strokeJoin=kMiter_Join, typeface=(nil), colorFilter=(nil), "
+ "strokeJoin=kMiter_Join, colorFilter=(nil), "
"maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
"pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
"isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
@@ -295,11 +265,10 @@ TEST(PaintOpHelper, SaveLayerToString) {
TEST(PaintOpHelper, SaveLayerAlphaToString) {
SkRect bounds = SkRect::MakeXYWH(1, 2, 3, 4);
- SaveLayerAlphaOp op(&bounds, 255, false);
+ SaveLayerAlphaOp op(&bounds, 255);
std::string str = PaintOpHelper::ToString(&op);
EXPECT_EQ(str,
- "SaveLayerAlphaOp(bounds=[1.000,2.000 3.000x4.000], alpha=255, "
- "preserve_lcd_text_requests=false)");
+ "SaveLayerAlphaOp(bounds=[1.000,2.000 3.000x4.000], alpha=255)");
}
TEST(PaintOpHelper, ScaleToString) {
diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc
index 9805e9c8149..a8b777f7c22 100644
--- a/chromium/cc/paint/paint_op_reader.cc
+++ b/chromium/cc/paint/paint_op_reader.cc
@@ -9,6 +9,7 @@
#include "base/bits.h"
#include "base/debug/dump_without_crashing.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/paint/paint_cache.h"
@@ -27,12 +28,6 @@
namespace cc {
namespace {
-// If we have more than this many colors, abort deserialization.
-const size_t kMaxShaderColorsSupported = 10000;
-const size_t kMaxMergeFilterCount = 10000;
-const size_t kMaxKernelSize = 1000;
-const size_t kMaxRegionByteSize = 10 * 1024;
-
bool IsValidPaintShaderType(PaintShader::Type type) {
return static_cast<uint8_t>(type) <
static_cast<uint8_t>(PaintShader::Type::kShaderCount);
@@ -122,6 +117,16 @@ void PaintOpReader::ReadSimple(T* val) {
remaining_bytes_ -= size;
}
+uint8_t* PaintOpReader::CopyScratchSpace(size_t bytes) {
+ DCHECK(SkIsAlign4(reinterpret_cast<uintptr_t>(memory_)));
+
+ if (options_.scratch_buffer->size() < bytes)
+ options_.scratch_buffer->resize(bytes);
+ memcpy(options_.scratch_buffer->data(), const_cast<const char*>(memory_),
+ bytes);
+ return options_.scratch_buffer->data();
+}
+
template <typename T>
void PaintOpReader::ReadFlattenable(sk_sp<T>* val) {
size_t bytes = 0;
@@ -133,13 +138,9 @@ void PaintOpReader::ReadFlattenable(sk_sp<T>* val) {
if (bytes == 0)
return;
- // This is assumed safe from TOCTOU violations as the flattenable
- // deserializing function uses an SkReadBuffer which reads each piece of
- // memory once much like PaintOpReader does.
- DCHECK(SkIsAlign4(reinterpret_cast<uintptr_t>(memory_)));
+ auto* scratch = CopyScratchSpace(bytes);
val->reset(static_cast<T*>(
- SkFlattenable::Deserialize(T::GetFlattenableType(),
- const_cast<const char*>(memory_), bytes)
+ SkFlattenable::Deserialize(T::GetFlattenableType(), scratch, bytes)
.release()));
if (!val)
SetInvalid();
@@ -214,8 +215,8 @@ void PaintOpReader::Read(SkPath* path) {
return;
if (path_bytes != 0u) {
- size_t bytes_read =
- path->readFromMemory(const_cast<const char*>(memory_), path_bytes);
+ auto* scratch = CopyScratchSpace(path_bytes);
+ size_t bytes_read = path->readFromMemory(scratch, path_bytes);
if (bytes_read == 0u) {
SetInvalid();
return;
@@ -236,7 +237,6 @@ void PaintOpReader::Read(SkPath* path) {
}
void PaintOpReader::Read(PaintFlags* flags) {
- Read(&flags->text_size_);
ReadSimple(&flags->color_);
Read(&flags->width_);
Read(&flags->miter_limit_);
@@ -386,13 +386,8 @@ void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
if (!valid_ || size == 0)
return;
- // To avoid TOCTOU issues, make a copy of this prior to turning it
- // into an SkColorSpace. SkColorSpace::Deserialize reads header
- // fields multiple times, so is not safe to pass memory_ to directly.
- std::unique_ptr<char[]> data(new char[size]);
- memcpy(data.get(), const_cast<const char*>(memory_), size);
-
- *color_space = SkColorSpace::Deserialize(data.get(), size);
+ auto* scratch = CopyScratchSpace(size);
+ *color_space = SkColorSpace::Deserialize(scratch, size);
// If this had non-zero bytes, it should be a valid color space.
if (!color_space)
SetInvalid();
@@ -431,8 +426,9 @@ void PaintOpReader::Read(sk_sp<SkTextBlob>* blob) {
TypefaceCtx typeface_ctx(options_.strike_client);
procs.fTypefaceProc = &DeserializeTypeface;
procs.fTypefaceCtx = &typeface_ctx;
- sk_sp<SkTextBlob> deserialized_blob = SkTextBlob::Deserialize(
- const_cast<const char*>(memory_), data_bytes, procs);
+ auto* scratch = CopyScratchSpace(data_bytes);
+ sk_sp<SkTextBlob> deserialized_blob =
+ SkTextBlob::Deserialize(scratch, data_bytes, procs);
if (!deserialized_blob || typeface_ctx.invalid_typeface) {
SetInvalid();
return;
@@ -513,7 +509,7 @@ void PaintOpReader::Read(sk_sp<PaintShader>* shader) {
ReadSize(&colors_size);
// If there are too many colors, abort.
- if (colors_size > kMaxShaderColorsSupported) {
+ if (colors_size > remaining_bytes_) {
SetInvalid();
return;
}
@@ -614,9 +610,8 @@ void PaintOpReader::AlignMemory(size_t alignment) {
}
inline void PaintOpReader::SetInvalid() {
- if (valid_ && options_.crash_dump_on_failure) {
- // TODO(enne): make this DumpWithoutCrashing after http://crbug.com/910772
- // base::debug::DumpWithoutCrashing();
+ if (valid_ && options_.crash_dump_on_failure && base::RandInt(1, 10) == 1) {
+ base::debug::DumpWithoutCrashing();
}
valid_ = false;
}
@@ -909,7 +904,7 @@ void PaintOpReader::ReadMatrixConvolutionPaintFilter(
return;
auto size =
static_cast<size_t>(sk_64_mul(kernel_size.width(), kernel_size.height()));
- if (size > kMaxKernelSize) {
+ if (size > remaining_bytes_) {
SetInvalid();
return;
}
@@ -1008,7 +1003,12 @@ void PaintOpReader::ReadMergePaintFilter(
const base::Optional<PaintFilter::CropRect>& crop_rect) {
size_t input_count = 0;
ReadSimple(&input_count);
- if (input_count > kMaxMergeFilterCount)
+
+ // The minimum size for a serialized filter is 4 bytes (a zero uint32_t to
+ // indicate a null filter). Make sure the |input_count| doesn't exceed the
+ // maximum number of filters possible for the remaining data.
+ const size_t max_filters = remaining_bytes_ / 4u;
+ if (input_count > max_filters)
SetInvalid();
if (!valid_)
return;
@@ -1271,7 +1271,7 @@ size_t PaintOpReader::Read(sk_sp<PaintRecord>* record) {
void PaintOpReader::Read(SkRegion* region) {
size_t region_bytes = 0;
ReadSize(&region_bytes);
- if (region_bytes == 0 || region_bytes > kMaxRegionByteSize)
+ if (region_bytes == 0 || region_bytes > remaining_bytes_)
SetInvalid();
if (!valid_)
return;
diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h
index 6a9c8de4193..e3ed7b86052 100644
--- a/chromium/cc/paint/paint_op_reader.h
+++ b/chromium/cc/paint/paint_op_reader.h
@@ -188,6 +188,7 @@ class CC_PAINT_EXPORT PaintOpReader {
size_t Read(sk_sp<PaintRecord>* record);
void Read(SkRegion* region);
+ uint8_t* CopyScratchSpace(size_t bytes);
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 f933da967e4..72783966429 100644
--- a/chromium/cc/paint/paint_op_writer.cc
+++ b/chromium/cc/paint/paint_op_writer.cc
@@ -24,7 +24,7 @@ namespace {
const size_t kSkiaAlignment = 4u;
size_t RoundDownToAlignment(size_t bytes, size_t alignment) {
- return bytes - (bytes & (alignment - 1));
+ return base::bits::AlignDown(bytes, alignment);
}
SkIRect MakeSrcRect(const PaintImage& image) {
@@ -194,7 +194,6 @@ void PaintOpWriter::Write(const SkPath& path) {
}
void PaintOpWriter::Write(const PaintFlags& flags) {
- Write(flags.text_size_);
WriteSimple(flags.color_);
Write(flags.width_);
Write(flags.miter_limit_);
diff --git a/chromium/cc/paint/paint_worklet_input.h b/chromium/cc/paint/paint_worklet_input.h
new file mode 100644
index 00000000000..165729147d0
--- /dev/null
+++ b/chromium/cc/paint/paint_worklet_input.h
@@ -0,0 +1,26 @@
+// Copyright 2018 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_PAINT_PAINT_WORKLET_INPUT_H_
+#define CC_PAINT_PAINT_WORKLET_INPUT_H_
+
+#include "base/memory/ref_counted.h"
+#include "cc/cc_export.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace cc {
+
+class CC_EXPORT PaintWorkletInput
+ : public base::RefCountedThreadSafe<PaintWorkletInput> {
+ public:
+ virtual gfx::SizeF GetSize() const = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<PaintWorkletInput>;
+ virtual ~PaintWorkletInput() = default;
+};
+
+} // namespace cc
+
+#endif // CC_PAINT_PAINT_WORKLET_INPUT_H_
diff --git a/chromium/cc/paint/paint_worklet_layer_painter.h b/chromium/cc/paint/paint_worklet_layer_painter.h
new file mode 100644
index 00000000000..c1a8e097921
--- /dev/null
+++ b/chromium/cc/paint/paint_worklet_layer_painter.h
@@ -0,0 +1,22 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_PAINT_PAINT_WORKLET_LAYER_PAINTER_H_
+#define CC_PAINT_PAINT_WORKLET_LAYER_PAINTER_H_
+
+#include "cc/cc_export.h"
+#include "cc/paint/paint_record.h"
+
+namespace cc {
+
+class CC_EXPORT PaintWorkletLayerPainter {
+ public:
+ virtual ~PaintWorkletLayerPainter() {}
+
+ virtual sk_sp<PaintRecord> Paint() = 0;
+};
+
+} // namespace cc
+
+#endif // CC_PAINT_PAINT_WORKLET_LAYER_PAINTER_H_
diff --git a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
index aa6fb645733..8f8e746f01a 100644
--- a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -10,15 +10,18 @@ namespace cc {
ClientRawMemoryTransferCacheEntry::ClientRawMemoryTransferCacheEntry(
std::vector<uint8_t> data)
- : id_(s_next_id_.GetNext()), data_(std::move(data)) {}
+ : id_(s_next_id_.GetNext()), data_(std::move(data)) {
+ DCHECK_LE(data_.size(), UINT32_MAX);
+}
+
ClientRawMemoryTransferCacheEntry::~ClientRawMemoryTransferCacheEntry() =
default;
// static
base::AtomicSequenceNumber ClientRawMemoryTransferCacheEntry::s_next_id_;
-size_t ClientRawMemoryTransferCacheEntry::SerializedSize() const {
- return data_.size();
+uint32_t ClientRawMemoryTransferCacheEntry::SerializedSize() const {
+ return static_cast<uint32_t>(data_.size());
}
uint32_t ClientRawMemoryTransferCacheEntry::Id() const {
diff --git a/chromium/cc/paint/raw_memory_transfer_cache_entry.h b/chromium/cc/paint/raw_memory_transfer_cache_entry.h
index c6ce52af731..2e9aafd490a 100644
--- a/chromium/cc/paint/raw_memory_transfer_cache_entry.h
+++ b/chromium/cc/paint/raw_memory_transfer_cache_entry.h
@@ -22,7 +22,7 @@ class CC_PAINT_EXPORT ClientRawMemoryTransferCacheEntry
explicit ClientRawMemoryTransferCacheEntry(std::vector<uint8_t> data);
~ClientRawMemoryTransferCacheEntry() final;
uint32_t Id() const final;
- size_t SerializedSize() const final;
+ uint32_t SerializedSize() const final;
bool Serialize(base::span<uint8_t> data) const final;
private:
diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc
index 2d9b4e4eb40..24e7819d212 100644
--- a/chromium/cc/paint/record_paint_canvas.cc
+++ b/chromium/cc/paint/record_paint_canvas.cc
@@ -49,7 +49,7 @@ int RecordPaintCanvas::saveLayer(const SkRect* bounds,
// TODO(enne): maybe more callers should know this and call
// saveLayerAlpha instead of needing to check here.
uint8_t alpha = SkColorGetA(flags->getColor());
- return saveLayerAlpha(bounds, alpha, false);
+ return saveLayerAlpha(bounds, alpha);
}
// TODO(enne): it appears that image filters affect matrices and color
@@ -63,10 +63,8 @@ int RecordPaintCanvas::saveLayer(const SkRect* bounds,
return GetCanvas()->saveLayer(bounds, nullptr);
}
-int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests) {
- list_->push<SaveLayerAlphaOp>(bounds, alpha, preserve_lcd_text_requests);
+int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
+ list_->push<SaveLayerAlphaOp>(bounds, alpha);
return GetCanvas()->saveLayerAlpha(bounds, alpha);
}
diff --git a/chromium/cc/paint/record_paint_canvas.h b/chromium/cc/paint/record_paint_canvas.h
index cfa24116f45..183f8fefdca 100644
--- a/chromium/cc/paint/record_paint_canvas.h
+++ b/chromium/cc/paint/record_paint_canvas.h
@@ -34,9 +34,7 @@ class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas {
int save() override;
int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
- int saveLayerAlpha(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests) override;
+ int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
void restore() override;
int getSaveCount() const override;
diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc
index 4bb07e76333..99e9dfee798 100644
--- a/chromium/cc/paint/skia_paint_canvas.cc
+++ b/chromium/cc/paint/skia_paint_canvas.cc
@@ -81,14 +81,7 @@ int SkiaPaintCanvas::saveLayer(const SkRect* bounds, const PaintFlags* flags) {
return canvas_->saveLayer(bounds, &paint);
}
-int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests) {
- if (preserve_lcd_text_requests) {
- SkPaint paint;
- paint.setAlpha(alpha);
- return canvas_->saveLayerPreserveLCDTextRequests(bounds, &paint);
- }
+int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
return canvas_->saveLayerAlpha(bounds, alpha);
}
diff --git a/chromium/cc/paint/skia_paint_canvas.h b/chromium/cc/paint/skia_paint_canvas.h
index 458bf99d4da..e22e6f2365f 100644
--- a/chromium/cc/paint/skia_paint_canvas.h
+++ b/chromium/cc/paint/skia_paint_canvas.h
@@ -55,9 +55,7 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas {
int save() override;
int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
- int saveLayerAlpha(const SkRect* bounds,
- uint8_t alpha,
- bool preserve_lcd_text_requests) override;
+ int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
void restore() override;
int getSaveCount() const override;
diff --git a/chromium/cc/paint/solid_color_analyzer.cc b/chromium/cc/paint/solid_color_analyzer.cc
index 12ad8e46f1d..9d3ed900fb8 100644
--- a/chromium/cc/paint/solid_color_analyzer.cc
+++ b/chromium/cc/paint/solid_color_analyzer.cc
@@ -4,12 +4,51 @@
#include "cc/paint/solid_color_analyzer.h"
+#include <cmath>
+
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "cc/paint/paint_op_buffer.h"
+#include "third_party/skia/include/core/SkTypes.h"
#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
namespace cc {
namespace {
+
+SkColor DoSrcOverAlphaBlend(SkColor src, SkColor dst) {
+ if (SkColorGetA(src) == 0)
+ return dst;
+ if (SkColorGetA(src) == 255)
+ return src;
+
+ // Note: using alpha blending formulas adapted from
+ // https://en.wikipedia.org/wiki/Alpha_compositing:
+ //
+ // outA = srcA + dstA * (1 - srcA)
+ // outRGB = srcRGB * (srcA / outA) + dstRGB * [dstA * (1 - srcA) / outA]
+ const float src_alpha = SkColorGetA(src) / 255.0f;
+ const float src_alpha_complement = (255.0f - SkColorGetA(src)) / 255.0f;
+ const float dst_alpha = SkColorGetA(dst) / 255.0f;
+ const float out_alpha = src_alpha + dst_alpha * src_alpha_complement;
+ if (out_alpha == 0.0f)
+ return SK_ColorTRANSPARENT;
+
+ const float inverse_out_alpha = 1.0f / out_alpha;
+ const float src_weight = src_alpha * inverse_out_alpha;
+ const float dst_weight = dst_alpha * src_alpha_complement * inverse_out_alpha;
+ const float out_red =
+ (SkColorGetR(src) * src_weight + SkColorGetR(dst) * dst_weight);
+ const float out_green =
+ (SkColorGetG(src) * src_weight + SkColorGetG(dst) * dst_weight);
+ const float out_blue =
+ (SkColorGetB(src) * src_weight + SkColorGetB(dst) * dst_weight);
+
+ return SkColorSetARGB(static_cast<U8CPU>(std::floor(out_alpha * 255.0f)),
+ static_cast<U8CPU>(std::floor(out_red)),
+ static_cast<U8CPU>(std::floor(out_green)),
+ static_cast<U8CPU>(std::floor(out_blue)));
+}
+
bool ActsLikeClear(SkBlendMode mode, unsigned src_alpha) {
switch (mode) {
case SkBlendMode::kClear:
@@ -27,22 +66,29 @@ bool ActsLikeClear(SkBlendMode mode, unsigned src_alpha) {
}
}
-bool IsSolidColor(SkColor color, SkBlendMode blendmode) {
- return SkColorGetA(color) == 255 &&
- (blendmode == SkBlendMode::kSrc || blendmode == SkBlendMode::kSrcOver);
+bool IsSolidColorBlendMode(SkBlendMode blendmode) {
+ return blendmode == SkBlendMode::kSrc || blendmode == SkBlendMode::kSrcOver;
}
bool IsSolidColorPaint(const PaintFlags& flags) {
SkBlendMode blendmode = flags.getBlendMode();
// Paint is solid color if the following holds:
- // - Alpha is 1.0, style is fill, and there are no special effects
- // - Xfer mode is either kSrc or kSrcOver (kSrcOver is equivalent
- // to kSrc if source alpha is 1.0, which is already checked).
- return IsSolidColor(flags.getColor(), blendmode) && !flags.HasShader() &&
- !flags.getLooper() && !flags.getMaskFilter() &&
- !flags.getColorFilter() && !flags.getImageFilter() &&
- flags.getStyle() == PaintFlags::kFill_Style;
+ // - Style is fill, and there are no special effects.
+ // - Blend mode is either kSrc or kSrcOver.
+ bool is_solid_color =
+ IsSolidColorBlendMode(blendmode) && !flags.HasShader() &&
+ !flags.getLooper() && !flags.getMaskFilter() && !flags.getColorFilter() &&
+ !flags.getImageFilter() && flags.getStyle() == PaintFlags::kFill_Style;
+
+#if defined(OS_MACOSX)
+ // Additionally, on Mac, we require that the color is opaque due to
+ // https://crbug.com/922899.
+ // TODO(andrescj): remove this condition once that bug is fixed.
+ is_solid_color = (is_solid_color && SkColorGetA(flags.getColor()) == 255);
+#endif // OS_MACOSX
+
+ return is_solid_color;
}
// Returns true if the specified |drawn_shape| will cover the entire canvas
@@ -75,6 +121,28 @@ bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) {
return drawn_shape.contains(clip_rect);
}
+void CalculateSolidColor(SkColor src_color,
+ SkBlendMode blendmode,
+ SkColor* dst_color,
+ bool* is_solid_color) {
+ if (blendmode == SkBlendMode::kSrc) {
+ // In the Src mode, we don't have to worry about what's in the canvas
+ // because we'll replace it with |src_color|.
+ *dst_color = src_color;
+ *is_solid_color = true;
+ } else {
+ DCHECK_EQ(SkBlendMode::kSrcOver, blendmode);
+
+ // When using the SrcOver mode, we must ensure that either a) we're
+ // completely occluding what's in the canvas with an opaque color, or
+ // b) whatever is in the canvas is already a solid color.
+ if (SkColorGetA(src_color) == 255 || *is_solid_color) {
+ *dst_color = DoSrcOverAlphaBlend(src_color, *dst_color);
+ *is_solid_color = true;
+ }
+ }
+}
+
void CheckIfSolidColor(const SkCanvas& canvas,
SkColor color,
SkBlendMode blendmode,
@@ -95,9 +163,19 @@ void CheckIfSolidColor(const SkCanvas& canvas,
else if (alpha != 0 || blendmode != SkBlendMode::kSrc)
*is_transparent = false;
- if (does_cover_canvas && IsSolidColor(color, blendmode)) {
- *is_solid_color = true;
- *out_color = color;
+ bool solid_color_candidate =
+ does_cover_canvas && IsSolidColorBlendMode(blendmode);
+
+#if defined(OS_MACOSX)
+ // Additionally, on Mac, we require that the color is opaque due to
+ // https://crbug.com/922899.
+ // TODO(andrescj): remove this condition once that bug is fixed.
+ solid_color_candidate = (solid_color_candidate && alpha == 255);
+#endif // OS_MACOSX
+
+ if (solid_color_candidate) {
+ CalculateSolidColor(color /* src_color */, blendmode,
+ out_color /* dst_color */, is_solid_color);
} else {
*is_solid_color = false;
}
@@ -123,8 +201,8 @@ void CheckIfSolidShape(const SkCanvas& canvas,
*is_transparent = false;
if (does_cover_canvas && IsSolidColorPaint(flags)) {
- *is_solid_color = true;
- *color = flags.getColor();
+ CalculateSolidColor(flags.getColor() /* src_color */, flags.getBlendMode(),
+ color /* dst_color */, is_solid_color);
} else {
*is_solid_color = false;
}
@@ -147,7 +225,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
if (buffer->size() == 0 || (offsets && offsets->empty()))
return SK_ColorTRANSPARENT;
- bool is_solid = false;
+ bool is_solid = true;
bool is_transparent = true;
SkColor color = SK_ColorTRANSPARENT;
diff --git a/chromium/cc/paint/solid_color_analyzer_unittest.cc b/chromium/cc/paint/solid_color_analyzer_unittest.cc
index 939e517af61..3c95df2b2d7 100644
--- a/chromium/cc/paint/solid_color_analyzer_unittest.cc
+++ b/chromium/cc/paint/solid_color_analyzer_unittest.cc
@@ -6,6 +6,8 @@
#include "base/memory/ref_counted.h"
#include "base/optional.h"
+#include "base/stl_util.h"
+#include "build/build_config.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/record_paint_canvas.h"
@@ -41,17 +43,17 @@ class SolidColorAnalyzerTest : public testing::Test {
}
RecordPaintCanvas* canvas() { return &*canvas_; }
- bool IsSolidColor() {
+ bool IsSolidColor(int max_ops_to_analyze = 1) {
Finalize();
- auto color = SolidColorAnalyzer::DetermineIfSolidColor(buffer_.get(), rect_,
- 1, nullptr);
+ auto color = SolidColorAnalyzer::DetermineIfSolidColor(
+ buffer_.get(), rect_, max_ops_to_analyze, nullptr);
return !!color;
}
- SkColor GetColor() {
+ SkColor GetColor(int max_ops_to_analyze = 1) {
Finalize();
- auto color = SolidColorAnalyzer::DetermineIfSolidColor(buffer_.get(), rect_,
- 1, nullptr);
+ auto color = SolidColorAnalyzer::DetermineIfSolidColor(
+ buffer_.get(), rect_, max_ops_to_analyze, nullptr);
EXPECT_TRUE(color);
return color ? *color : SK_ColorTRANSPARENT;
}
@@ -95,7 +97,13 @@ TEST_F(SolidColorAnalyzerTest, ClearTranslucent) {
Initialize();
SkColor color = SkColorSetARGB(128, 11, 22, 33);
canvas()->clear(color);
+#if defined(OS_MACOSX)
+ // TODO(andrescj): remove the special treatment of OS_MACOSX once
+ // https://crbug.com/922899 is fixed.
EXPECT_FALSE(IsSolidColor());
+#else
+ EXPECT_EQ(color, GetColor());
+#endif // OS_MACOSX
}
TEST_F(SolidColorAnalyzerTest, DrawColor) {
@@ -280,6 +288,71 @@ TEST_F(SolidColorAnalyzerTest, DrawRectClipPath) {
EXPECT_FALSE(IsSolidColor());
}
+TEST_F(SolidColorAnalyzerTest, DrawRectTranslucent) {
+ Initialize();
+ PaintFlags flags;
+ SkColor color = SkColorSetARGB(128, 128, 0, 0);
+ flags.setColor(color);
+ SkRect rect = SkRect::MakeWH(100, 100);
+ canvas()->drawRect(rect, flags);
+#if defined(OS_MACOSX)
+ // TODO(andrescj): remove the special treatment of OS_MACOSX once
+ // https://crbug.com/922899 is fixed.
+ EXPECT_FALSE(IsSolidColor());
+#else
+ EXPECT_EQ(color, GetColor());
+#endif // OS_MACOSX
+}
+
+TEST_F(SolidColorAnalyzerTest, DrawRectTranslucentOverNonSolid) {
+ Initialize();
+ PaintFlags flags;
+ SkColor color = SkColorSetARGB(255, 128, 0, 0);
+ flags.setColor(color);
+ SkRect rect = SkRect::MakeWH(100, 50);
+ canvas()->drawRect(rect, flags);
+ color = SkColorSetARGB(128, 0, 128, 0);
+ flags.setColor(color);
+ rect = SkRect::MakeWH(100, 100);
+ canvas()->drawRect(rect, flags);
+ EXPECT_FALSE(IsSolidColor(2 /* max_ops_to_analyze */));
+}
+
+TEST_F(SolidColorAnalyzerTest, DrawRectOpaqueOccludesNonSolid) {
+ Initialize();
+ PaintFlags flags;
+ SkColor color = SkColorSetARGB(255, 128, 0, 0);
+ flags.setColor(color);
+ SkRect rect = SkRect::MakeWH(100, 50);
+ canvas()->drawRect(rect, flags);
+ color = SkColorSetARGB(255, 0, 128, 0);
+ flags.setColor(color);
+ rect = SkRect::MakeWH(100, 100);
+ canvas()->drawRect(rect, flags);
+ EXPECT_EQ(color, GetColor(2 /* max_ops_to_analyze */));
+}
+
+TEST_F(SolidColorAnalyzerTest, DrawRectSolidWithSrcOverBlending) {
+ Initialize();
+ PaintFlags flags;
+ SkColor color = SkColorSetARGB(64, 40, 50, 60);
+ flags.setColor(color);
+ SkRect rect = SkRect::MakeWH(100, 100);
+ canvas()->drawRect(rect, flags);
+ color = SkColorSetARGB(128, 10, 20, 30);
+ flags.setColor(color);
+ rect = SkRect::MakeWH(100, 100);
+ canvas()->drawRect(rect, flags);
+#if defined(OS_MACOSX)
+ // TODO(andrescj): remove the special treatment of OS_MACOSX once
+ // https://crbug.com/922899 is fixed.
+ EXPECT_FALSE(IsSolidColor());
+#else
+ EXPECT_EQ(SkColorSetARGB(159, 15, 25, 35),
+ GetColor(2 /* max_ops_to_analyze */));
+#endif // OS_MACOSX
+}
+
TEST_F(SolidColorAnalyzerTest, SaveLayer) {
Initialize();
PaintFlags flags;
@@ -351,7 +424,7 @@ TEST_F(SolidColorAnalyzerTest, ClipRRectCoversCanvas) {
for (int case_scale = 0; case_scale < 2; ++case_scale) {
bool scaled = case_scale > 0;
- for (size_t i = 0; i < arraysize(cases); ++i) {
+ for (size_t i = 0; i < base::size(cases); ++i) {
Reset();
Initialize(canvas_rect);
diff --git a/chromium/cc/paint/transfer_cache_entry.h b/chromium/cc/paint/transfer_cache_entry.h
index 374607e2497..5488aa16fca 100644
--- a/chromium/cc/paint/transfer_cache_entry.h
+++ b/chromium/cc/paint/transfer_cache_entry.h
@@ -45,7 +45,7 @@ class CC_PAINT_EXPORT ClientTransferCacheEntry {
// Returns the serialized sized of this entry in bytes. This function will be
// used to determine how much memory is going to be allocated and passed to
// the Serialize() call.
- virtual size_t SerializedSize() const = 0;
+ virtual uint32_t SerializedSize() const = 0;
// Serializes the entry into the given span of memory. The size of the span is
// guaranteed to be at least SerializedSize() bytes. Returns true on success
diff --git a/chromium/cc/paint/transfer_cache_serialize_helper.cc b/chromium/cc/paint/transfer_cache_serialize_helper.cc
index f50f150f7c7..7a59ca0d197 100644
--- a/chromium/cc/paint/transfer_cache_serialize_helper.cc
+++ b/chromium/cc/paint/transfer_cache_serialize_helper.cc
@@ -27,7 +27,7 @@ bool TransferCacheSerializeHelper::LockEntry(TransferCacheEntryType type,
return true;
}
-size_t TransferCacheSerializeHelper::CreateEntry(
+uint32_t TransferCacheSerializeHelper::CreateEntry(
const ClientTransferCacheEntry& entry,
char* memory) {
// We shouldn't be creating entries if they were already created or locked.
diff --git a/chromium/cc/paint/transfer_cache_serialize_helper.h b/chromium/cc/paint/transfer_cache_serialize_helper.h
index 1a204407538..03b95c33de6 100644
--- a/chromium/cc/paint/transfer_cache_serialize_helper.h
+++ b/chromium/cc/paint/transfer_cache_serialize_helper.h
@@ -22,7 +22,7 @@ class CC_PAINT_EXPORT TransferCacheSerializeHelper {
// The PaintOpWriter passes the address where the transfer cache may inline
// this entry. The size returned is the memory used if the entry is inlined,
// or 0u if no data is inlined.
- size_t CreateEntry(const ClientTransferCacheEntry& entry, char* memory);
+ uint32_t CreateEntry(const ClientTransferCacheEntry& entry, char* memory);
void FlushEntries();
void AssertLocked(TransferCacheEntryType type, uint32_t id);
@@ -31,8 +31,8 @@ class CC_PAINT_EXPORT TransferCacheSerializeHelper {
using EntryKey = std::pair<TransferCacheEntryType, uint32_t>;
virtual bool LockEntryInternal(const EntryKey& key) = 0;
- virtual size_t CreateEntryInternal(const ClientTransferCacheEntry& entry,
- char* memory) = 0;
+ virtual uint32_t CreateEntryInternal(const ClientTransferCacheEntry& entry,
+ char* memory) = 0;
virtual void FlushEntriesInternal(std::set<EntryKey> keys) = 0;
private:
diff --git a/chromium/cc/paint/transfer_cache_unittest.cc b/chromium/cc/paint/transfer_cache_unittest.cc
index f24917ab29d..7b606ab9110 100644
--- a/chromium/cc/paint/transfer_cache_unittest.cc
+++ b/chromium/cc/paint/transfer_cache_unittest.cc
@@ -75,7 +75,7 @@ class TransferCacheTest : public testing::Test {
}
void CreateEntry(const ClientTransferCacheEntry& entry) {
auto* context_support = ContextSupport();
- size_t size = entry.SerializedSize();
+ uint32_t size = entry.SerializedSize();
void* data = context_support->MapTransferCacheEntry(size);
ASSERT_TRUE(data);
entry.Serialize(base::make_span(static_cast<uint8_t*>(data), size));
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index fc981249cd6..e2713a24064 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -156,7 +156,7 @@ bool BitmapRasterBufferProvider::IsResourceReadyToDraw(
uint64_t BitmapRasterBufferProvider::SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const {
// Bitmap resources are immediately ready to draw.
return 0;
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.h b/chromium/cc/raster/bitmap_raster_buffer_provider.h
index 9ceb0012b23..f9c1b9ed706 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.h
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.h
@@ -40,7 +40,7 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider {
const ResourcePool::InUsePoolResource& resource) const override;
uint64_t SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const override;
void Shutdown() override;
bool CheckRasterFinishedQueries() override;
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index 2a731285a2c..2053c56dfc3 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -24,8 +24,6 @@
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
-#include "components/viz/common/gpu/texture_allocation.h"
-#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -149,8 +147,6 @@ static void RasterizeSourceOOP(
// use GL_TEXTURE_2D.
ri->BeginRasterCHROMIUM(raster_source->background_color(), msaa_sample_count,
playback_settings.use_lcd_text,
- viz::ResourceFormatToClosestSkColorType(
- /*gpu_compositing=*/true, resource_format),
playback_settings.raster_color_space, mailbox->name);
float recording_to_raster_scale =
transform.scale() / raster_source->recording_scale_factor();
@@ -204,9 +200,7 @@ static void RasterizeSource(
// valid by the time the consume command executes.
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
- GLuint texture_id = ri->CreateAndConsumeTexture(
- texture_is_overlay_candidate, gfx::BufferUsage::SCANOUT, resource_format,
- mailbox->name);
+ GLuint texture_id = ri->CreateAndConsumeForGpuRaster(mailbox->name);
{
ScopedGrContextAccess gr_context_access(context_provider);
base::Optional<viz::ClientResourceProvider::ScopedSkSurface> scoped_surface;
@@ -245,7 +239,7 @@ static void RasterizeSource(
playback_settings);
}
- ri->DeleteTextures(1, &texture_id);
+ ri->DeleteGpuRasterTexture(texture_id);
}
} // namespace
@@ -417,7 +411,7 @@ bool GpuRasterBufferProvider::IsResourceReadyToDraw(
uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const {
gpu::SyncToken latest_sync_token;
for (const auto* in_use : resources) {
@@ -436,7 +430,7 @@ uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
// Use the compositor context because we want this callback on the
// compositor thread.
compositor_context_provider_->ContextSupport()->SignalSyncToken(
- latest_sync_token, callback);
+ latest_sync_token, std::move(callback));
}
return callback_id;
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h
index 0ef41dd0bea..cf726868a6f 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.h
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.h
@@ -53,7 +53,7 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
const ResourcePool::InUsePoolResource& resource) const override;
uint64_t SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const override;
void Shutdown() override;
bool CheckRasterFinishedQueries() override;
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index 75e11544218..f134a48b12f 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -221,7 +221,7 @@ bool OneCopyRasterBufferProvider::IsResourceReadyToDraw(
uint64_t OneCopyRasterBufferProvider::SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const {
gpu::SyncToken latest_sync_token;
for (const auto* in_use : resources) {
@@ -240,7 +240,7 @@ uint64_t OneCopyRasterBufferProvider::SetReadyToDrawCallback(
// Use the compositor context because we want this callback on the
// compositor thread.
compositor_context_provider_->ContextSupport()->SignalSyncToken(
- latest_sync_token, callback);
+ latest_sync_token, std::move(callback));
}
return callback_id;
@@ -404,12 +404,6 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
DCHECK(ri);
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
- GLuint mailbox_texture_id = ri->CreateAndConsumeTexture(
- mailbox_texture_is_overlay_candidate, gfx::BufferUsage::SCANOUT,
- resource_format, mailbox->name);
- GLuint staging_texture_id = ri->CreateAndConsumeTexture(
- true, StagingBufferUsage(), staging_buffer->format,
- staging_buffer->mailbox.name);
// Do not use queries unless COMMANDS_COMPLETED queries are supported, or
// COMMANDS_ISSUED queries are sufficient.
@@ -456,8 +450,9 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
int rows_to_copy = std::min(chunk_size_in_rows, height - y);
DCHECK_GT(rows_to_copy, 0);
- ri->CopySubTexture(staging_texture_id, mailbox_texture_id, 0, y, 0, y,
- rect_to_copy.width(), rows_to_copy);
+ ri->CopySubTexture(staging_buffer->mailbox, *mailbox,
+ mailbox_texture_target, 0, y, 0, y, rect_to_copy.width(),
+ rows_to_copy);
y += rows_to_copy;
// Increment |bytes_scheduled_since_last_flush_| by the amount of memory
@@ -473,9 +468,6 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
if (query_target != GL_NONE)
ri->EndQueryEXT(query_target);
- GLuint textures_to_delete[] = {mailbox_texture_id, staging_texture_id};
- ri->DeleteTextures(2, textures_to_delete);
-
// Generate sync token on the worker context that will be sent to and waited
// for by the display compositor before using the content generated here.
// The same sync token is used to synchronize operations on the staging
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h
index 6766cae7a40..c2dec8e7d43 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h
@@ -55,7 +55,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
const ResourcePool::InUsePoolResource& resource) const override;
uint64_t SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const override;
void Shutdown() override;
bool CheckRasterFinishedQueries() override;
diff --git a/chromium/cc/raster/paint_worklet_image_provider.cc b/chromium/cc/raster/paint_worklet_image_provider.cc
new file mode 100644
index 00000000000..38feceb5ec0
--- /dev/null
+++ b/chromium/cc/raster/paint_worklet_image_provider.cc
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/raster/paint_worklet_image_provider.h"
+
+#include "cc/tiles/paint_worklet_image_cache.h"
+
+namespace cc {
+
+PaintWorkletImageProvider::PaintWorkletImageProvider(
+ PaintWorkletImageCache* cache)
+ : cache_(cache) {
+ DCHECK(cache_);
+}
+
+PaintWorkletImageProvider::~PaintWorkletImageProvider() = default;
+
+PaintWorkletImageProvider::PaintWorkletImageProvider(
+ PaintWorkletImageProvider&& other) = default;
+
+PaintWorkletImageProvider& PaintWorkletImageProvider::operator=(
+ PaintWorkletImageProvider&& other) = default;
+
+} // namespace cc
diff --git a/chromium/cc/raster/paint_worklet_image_provider.h b/chromium/cc/raster/paint_worklet_image_provider.h
new file mode 100644
index 00000000000..0712b12ba97
--- /dev/null
+++ b/chromium/cc/raster/paint_worklet_image_provider.h
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RASTER_PAINT_WORKLET_IMAGE_PROVIDER_H_
+#define CC_RASTER_PAINT_WORKLET_IMAGE_PROVIDER_H_
+
+#include "cc/cc_export.h"
+#include "cc/paint/image_provider.h"
+
+namespace cc {
+class PaintWorkletImageCache;
+
+// PaintWorkletImageProvider is a bridge between PaintWorkletImageCache and its
+// rasterization.
+class CC_EXPORT PaintWorkletImageProvider {
+ public:
+ explicit PaintWorkletImageProvider(PaintWorkletImageCache* cache);
+ ~PaintWorkletImageProvider();
+
+ PaintWorkletImageProvider(PaintWorkletImageProvider&& other);
+ PaintWorkletImageProvider& operator=(PaintWorkletImageProvider&& other);
+
+ private:
+ PaintWorkletImageCache* cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(PaintWorkletImageProvider);
+};
+
+} // namespace cc
+
+#endif // CC_RASTER_PAINT_WORKLET_IMAGE_PROVIDER_H_
diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h
index 74354c7aceb..a4755ccfda0 100644
--- a/chromium/cc/raster/raster_buffer_provider.h
+++ b/chromium/cc/raster/raster_buffer_provider.h
@@ -83,7 +83,7 @@ class CC_EXPORT RasterBufferProvider {
// have a pending callback, 0 should be passed for |pending_callback_id|.
virtual uint64_t SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Callback<void()>& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const = 0;
// Shutdown for doing cleanup.
diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc
index 63dd9fd95d1..098c5b94db9 100644
--- a/chromium/cc/raster/raster_buffer_provider_perftest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc
@@ -86,7 +86,7 @@ class PerfContextProvider
capabilities_.sync_query = true;
raster_context_ = std::make_unique<gpu::raster::RasterImplementationGLES>(
- context_gl_.get(), capabilities_);
+ context_gl_.get());
}
// viz::ContextProvider implementation.
diff --git a/chromium/cc/raster/raster_buffer_provider_unittest.cc b/chromium/cc/raster/raster_buffer_provider_unittest.cc
index 0cbd9467744..3f62b72140c 100644
--- a/chromium/cc/raster/raster_buffer_provider_unittest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_unittest.cc
@@ -145,8 +145,8 @@ class RasterBufferProviderTest
RasterBufferProviderTest()
: all_tile_tasks_finished_(
base::ThreadTaskRunnerHandle::Get().get(),
- base::Bind(&RasterBufferProviderTest::AllTileTasksFinished,
- base::Unretained(this))),
+ base::BindRepeating(&RasterBufferProviderTest::AllTileTasksFinished,
+ base::Unretained(this))),
timeout_seconds_(5),
timed_out_(false) {}
@@ -322,7 +322,6 @@ class RasterBufferProviderTest
std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
viz::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
SynchronousTaskGraphRunner task_graph_runner_;
- base::CancelableClosure timeout_;
UniqueNotifier all_tile_tasks_finished_;
int timeout_seconds_;
bool timed_out_;
@@ -410,9 +409,7 @@ TEST_P(RasterBufferProviderTest, ReadyToDrawCallback) {
base::RunLoop run_loop;
uint64_t callback_id = raster_buffer_provider_->SetReadyToDrawCallback(
- array,
- base::Bind([](base::RunLoop* run_loop) { run_loop->Quit(); }, &run_loop),
- 0);
+ array, run_loop.QuitClosure(), 0);
if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_GPU ||
GetParam() == RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY)
@@ -503,9 +500,7 @@ TEST_P(RasterBufferProviderTest, MeasureGpuRasterDuration) {
for (const auto& resource : resources_)
array.push_back(&resource);
uint64_t callback_id = raster_buffer_provider_->SetReadyToDrawCallback(
- array,
- base::Bind([](base::RunLoop* run_loop) { run_loop->Quit(); }, &run_loop),
- 0);
+ array, run_loop.QuitClosure(), 0);
ASSERT_TRUE(callback_id);
run_loop.Run();
diff --git a/chromium/cc/raster/raster_source.cc b/chromium/cc/raster/raster_source.cc
index 8f510fadc4c..1ab4da244fa 100644
--- a/chromium/cc/raster/raster_source.cc
+++ b/chromium/cc/raster/raster_source.cc
@@ -169,17 +169,21 @@ void RasterSource::PlaybackToCanvas(
raster_canvas->clear(SK_ColorTRANSPARENT);
}
- PlaybackToCanvas(raster_canvas, settings.image_provider);
+ PlaybackToCanvas(raster_canvas, settings.image_provider,
+ settings.paint_worklet_image_provider);
raster_canvas->restore();
}
-void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas,
- ImageProvider* image_provider) const {
+void RasterSource::PlaybackToCanvas(
+ SkCanvas* raster_canvas,
+ ImageProvider* image_provider,
+ PaintWorkletImageProvider* paint_worklet_image_provider) const {
// TODO(enne): Temporary CHECK debugging for http://crbug.com/823835
CHECK(display_list_.get());
int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
for (int i = 0; i < repeat_count; ++i)
- display_list_->Raster(raster_canvas, image_provider);
+ display_list_->Raster(raster_canvas, image_provider,
+ paint_worklet_image_provider);
}
sk_sp<SkPicture> RasterSource::GetFlattenedPicture() {
@@ -189,7 +193,7 @@ sk_sp<SkPicture> RasterSource::GetFlattenedPicture() {
SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height());
if (!size_.IsEmpty()) {
canvas->clear(SK_ColorTRANSPARENT);
- PlaybackToCanvas(canvas, nullptr);
+ PlaybackToCanvas(canvas, nullptr, nullptr);
}
return recorder.finishRecordingAsPicture();
diff --git a/chromium/cc/raster/raster_source.h b/chromium/cc/raster/raster_source.h
index 0fa0f86484c..1b8b62384f8 100644
--- a/chromium/cc/raster/raster_source.h
+++ b/chromium/cc/raster/raster_source.h
@@ -27,6 +27,7 @@ namespace cc {
class DisplayItemList;
class DrawImage;
class ImageProvider;
+class PaintWorkletImageProvider;
class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
public:
@@ -42,6 +43,10 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
// The ImageProvider used to replace images during playback.
ImageProvider* image_provider = nullptr;
+ // The PaintWorkletImageProvider is a bridge connecting the playback and the
+ // paint worklet image cache.
+ PaintWorkletImageProvider* paint_worklet_image_provider = nullptr;
+
RasterColorSpace raster_color_space;
};
@@ -70,8 +75,10 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
//
// Note that this should only be called after the image decode controller has
// been set, which happens during commit.
- virtual void PlaybackToCanvas(SkCanvas* canvas,
- ImageProvider* image_provider) const;
+ virtual void PlaybackToCanvas(
+ SkCanvas* canvas,
+ ImageProvider* image_provider,
+ PaintWorkletImageProvider* paint_worklet_image_provider) const;
// Returns whether the given rect at given scale is of solid color in
// this raster source, as well as the solid color value.
diff --git a/chromium/cc/raster/raster_source_unittest.cc b/chromium/cc/raster/raster_source_unittest.cc
index b9100522081..c694083f3ca 100644
--- a/chromium/cc/raster/raster_source_unittest.cc
+++ b/chromium/cc/raster/raster_source_unittest.cc
@@ -8,9 +8,11 @@
#include <memory>
+#include "base/memory/scoped_refptr.h"
#include "cc/raster/playback_image_provider.h"
#include "cc/test/fake_recording_source.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_paint_worklet_input.h"
#include "cc/test/test_skcanvas.h"
#include "cc/tiles/software_image_decode_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -184,6 +186,63 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) {
}
}
+TEST(RasterSourceTest, MultiPaintWorkletImages) {
+ gfx::Size layer_bounds(512, 512);
+
+ std::unique_ptr<FakeRecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
+
+ scoped_refptr<TestPaintWorkletInput> input1 =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(32.0f, 32.0f));
+ scoped_refptr<TestPaintWorkletInput> input2 =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(64.0f, 64.0f));
+ scoped_refptr<TestPaintWorkletInput> input3 =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100.0f, 100.0f));
+
+ PaintImage discardable_image[2][2];
+ discardable_image[0][0] = CreatePaintWorkletPaintImage(input1);
+ discardable_image[0][1] = CreatePaintWorkletPaintImage(input2);
+ discardable_image[1][1] = CreatePaintWorkletPaintImage(input3);
+
+ recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0));
+ recording_source->add_draw_image(discardable_image[0][1], gfx::Point(260, 0));
+ recording_source->add_draw_image(discardable_image[1][1],
+ gfx::Point(260, 260));
+ recording_source->Rerecord();
+
+ scoped_refptr<RasterSource> raster = recording_source->CreateRasterSource();
+
+ // Tile sized iterators. These should find only one image.
+ {
+ std::vector<const DrawImage*> images;
+ raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), &images);
+ EXPECT_EQ(1u, images.size());
+ EXPECT_EQ(discardable_image[0][0], images[0]->paint_image());
+ }
+ // Shifted tile sized iterators. These should find only one image.
+ {
+ std::vector<const DrawImage*> images;
+ raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), &images);
+ EXPECT_EQ(1u, images.size());
+ EXPECT_EQ(discardable_image[1][1], images[0]->paint_image());
+ }
+ // Ensure there's no discardable pixel refs in the empty cell
+ {
+ std::vector<const DrawImage*> images;
+ raster->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), &images);
+ EXPECT_EQ(0u, images.size());
+ }
+ // Layer sized iterators. These should find three images.
+ {
+ std::vector<const DrawImage*> images;
+ raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), &images);
+ EXPECT_EQ(3u, images.size());
+ EXPECT_EQ(discardable_image[0][0], images[0]->paint_image());
+ EXPECT_EQ(discardable_image[0][1], images[1]->paint_image());
+ EXPECT_EQ(discardable_image[1][1], images[2]->paint_image());
+ }
+}
+
TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) {
gfx::Size layer_bounds(512, 512);
diff --git a/chromium/cc/raster/single_thread_task_graph_runner.cc b/chromium/cc/raster/single_thread_task_graph_runner.cc
index 0bb96a42a42..afb47e818a0 100644
--- a/chromium/cc/raster/single_thread_task_graph_runner.cc
+++ b/chromium/cc/raster/single_thread_task_graph_runner.cc
@@ -29,7 +29,7 @@ void SingleThreadTaskGraphRunner::Start(
const base::SimpleThread::Options& thread_options) {
thread_.reset(
new base::DelegateSimpleThread(this, thread_name, thread_options));
- thread_->Start();
+ thread_->StartAsync();
}
void SingleThreadTaskGraphRunner::Shutdown() {
diff --git a/chromium/cc/raster/staging_buffer_pool.cc b/chromium/cc/raster/staging_buffer_pool.cc
index a02c43e4e98..40ea9367c97 100644
--- a/chromium/cc/raster/staging_buffer_pool.cc
+++ b/chromium/cc/raster/staging_buffer_pool.cc
@@ -137,7 +137,7 @@ StagingBufferPool::StagingBufferPool(
base::BindRepeating(&StagingBufferPool::OnMemoryPressure,
weak_ptr_factory_.GetWeakPtr())));
- reduce_memory_usage_callback_ = base::Bind(
+ reduce_memory_usage_callback_ = base::BindRepeating(
&StagingBufferPool::ReduceMemoryUsage, weak_ptr_factory_.GetWeakPtr());
}
@@ -404,7 +404,7 @@ void StagingBufferPool::ReleaseBuffersNotUsedSince(base::TimeTicks time) {
// buffers as soon as we find a buffer that has been used since |time|.
while (!free_buffers_.empty()) {
if (free_buffers_.front()->last_usage > time)
- return;
+ break;
destroyed_buffers = true;
free_buffers_.front()->DestroyGLResources(ri, sii);
@@ -415,7 +415,7 @@ void StagingBufferPool::ReleaseBuffersNotUsedSince(base::TimeTicks time) {
while (!busy_buffers_.empty()) {
if (busy_buffers_.front()->last_usage > time)
- return;
+ break;
destroyed_buffers = true;
busy_buffers_.front()->DestroyGLResources(ri, sii);
diff --git a/chromium/cc/raster/staging_buffer_pool.h b/chromium/cc/raster/staging_buffer_pool.h
index cfd0f3a414c..d3331323d6f 100644
--- a/chromium/cc/raster/staging_buffer_pool.h
+++ b/chromium/cc/raster/staging_buffer_pool.h
@@ -136,7 +136,7 @@ class CC_EXPORT StagingBufferPool
int free_staging_buffer_usage_in_bytes_;
const base::TimeDelta staging_buffer_expiration_delay_;
bool reduce_memory_usage_pending_;
- base::Closure reduce_memory_usage_callback_;
+ base::RepeatingClosure reduce_memory_usage_callback_;
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
diff --git a/chromium/cc/raster/task.h b/chromium/cc/raster/task.h
index 66ebc932680..d67cb7ac055 100644
--- a/chromium/cc/raster/task.h
+++ b/chromium/cc/raster/task.h
@@ -77,6 +77,8 @@ class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> {
typedef std::vector<scoped_refptr<Task>> Vector;
TaskState& state() { return state_; }
+ void set_frame_number(int64_t frame_number) { frame_number_ = frame_number; }
+ int64_t frame_number() { return frame_number_; }
// Subclasses should implement this method. RunOnWorkerThread may be called
// on any thread, and subclasses are responsible for locking and thread
@@ -91,6 +93,7 @@ class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> {
private:
TaskState state_;
+ int64_t frame_number_ = -1;
};
// A task dependency graph describes the order in which to execute a set
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
index b61b669e57e..8e5eb1cf279 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -225,7 +225,7 @@ bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const {
// Zero-copy resources are immediately ready to draw.
return 0;
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.h b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
index 106f7c9bbc7..680d6b02128 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
@@ -46,7 +46,7 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
const ResourcePool::InUsePoolResource& resource) const override;
uint64_t SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::Closure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id) const override;
void Shutdown() override;
bool CheckRasterFinishedQueries() override;
diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc
index e648071a367..affa7ac4ab7 100644
--- a/chromium/cc/scheduler/compositor_timing_history.cc
+++ b/chromium/cc/scheduler/compositor_timing_history.cc
@@ -9,6 +9,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "cc/debug/rendering_stats_instrumentation.h"
@@ -121,12 +122,12 @@ const int kUMADurationBuckets[] = {
2000000, 4000000, 8000000, 16000000, 32000000,
};
-#define UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(name, sample) \
- do { \
- UMA_HISTOGRAM_CUSTOM_ENUMERATION( \
- name "2", sample.InMicroseconds(), \
- std::vector<int>(kUMAVSyncBuckets, \
- kUMAVSyncBuckets + arraysize(kUMAVSyncBuckets))); \
+#define UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(name, sample) \
+ do { \
+ UMA_HISTOGRAM_CUSTOM_ENUMERATION( \
+ name "2", sample.InMicroseconds(), \
+ std::vector<int>(kUMAVSyncBuckets, \
+ kUMAVSyncBuckets + base::size(kUMAVSyncBuckets))); \
} while (false)
#define UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, suffix, sample) \
@@ -135,7 +136,7 @@ const int kUMADurationBuckets[] = {
name "2" suffix, sample.InMicroseconds(), \
std::vector<int>( \
kUMADurationBuckets, \
- kUMADurationBuckets + arraysize(kUMADurationBuckets))); \
+ kUMADurationBuckets + base::size(kUMADurationBuckets))); \
} while (false)
#define UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(name, sample) \
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index 715ecc43ca0..60c8018b8d5 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -227,19 +227,20 @@ class FakeSchedulerClient : public SchedulerClient,
bool IsInsideBeginImplFrame() const { return inside_begin_impl_frame_; }
- base::Callback<bool(void)> InsideBeginImplFrame(bool state) {
- return base::Bind(&FakeSchedulerClient::InsideBeginImplFrameCallback,
- base::Unretained(this), state);
+ base::RepeatingCallback<bool(void)> InsideBeginImplFrame(bool state) {
+ return base::BindRepeating(
+ &FakeSchedulerClient::InsideBeginImplFrameCallback,
+ base::Unretained(this), state);
}
bool IsCurrentFrame(int last_frame_number) const {
return scheduler_->current_frame_number() == last_frame_number;
}
- base::Callback<bool(void)> FrameHasNotAdvancedCallback() {
- return base::Bind(&FakeSchedulerClient::IsCurrentFrame,
- base::Unretained(this),
- scheduler_->current_frame_number());
+ base::RepeatingCallback<bool(void)> FrameHasNotAdvancedCallback() {
+ return base::BindRepeating(&FakeSchedulerClient::IsCurrentFrame,
+ base::Unretained(this),
+ scheduler_->current_frame_number());
}
void PushAction(const char* description) {
diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc
index ce854bc73a1..2308d922a35 100644
--- a/chromium/cc/tiles/checker_image_tracker.cc
+++ b/chromium/cc/tiles/checker_image_tracker.cc
@@ -444,8 +444,8 @@ void CheckerImageTracker::ScheduleNextImageDecode() {
image_id);
ImageController::ImageDecodeRequestId request_id =
image_controller_->QueueImageDecode(
- draw_image, base::Bind(&CheckerImageTracker::DidFinishImageDecode,
- weak_factory_.GetWeakPtr(), image_id));
+ draw_image, base::BindOnce(&CheckerImageTracker::DidFinishImageDecode,
+ weak_factory_.GetWeakPtr(), image_id));
image_id_to_decode_.emplace(image_id, std::make_unique<ScopedDecodeHolder>(
image_controller_, request_id));
diff --git a/chromium/cc/tiles/checker_image_tracker_unittest.cc b/chromium/cc/tiles/checker_image_tracker_unittest.cc
index c375a591363..44cba670c23 100644
--- a/chromium/cc/tiles/checker_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/checker_image_tracker_unittest.cc
@@ -50,7 +50,7 @@ class TestImageController : public ImageController {
ImageDecodeRequestId QueueImageDecode(
const DrawImage& image,
- const ImageDecodedCallback& callback) override {
+ ImageDecodedCallback callback) override {
ImageDecodeRequestId request_id = next_image_request_id_++;
decoded_images_.push_back(image);
@@ -60,8 +60,8 @@ class TestImageController : public ImageController {
// Post the callback asynchronously to match the behaviour in
// ImageController.
worker_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(callback, request_id, ImageDecodeResult::SUCCESS));
+ FROM_HERE, base::BindOnce(std::move(callback), request_id,
+ ImageDecodeResult::SUCCESS));
return request_id;
}
diff --git a/chromium/cc/tiles/decoded_image_tracker.cc b/chromium/cc/tiles/decoded_image_tracker.cc
index ad1b297cfd7..197b749f63e 100644
--- a/chromium/cc/tiles/decoded_image_tracker.cc
+++ b/chromium/cc/tiles/decoded_image_tracker.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/tiles/decoded_image_tracker.h"
+#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
namespace cc {
@@ -27,7 +28,7 @@ DecodedImageTracker::DecodedImageTracker(
scoped_refptr<base::SequencedTaskRunner> task_runner)
: image_controller_(controller),
task_runner_(std::move(task_runner)),
- now_fn_(base::Bind(&base::TimeTicks::Now)),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
weak_ptr_factory_(this) {
DCHECK(image_controller_);
}
@@ -38,7 +39,7 @@ DecodedImageTracker::~DecodedImageTracker() {
void DecodedImageTracker::QueueImageDecode(
const PaintImage& image,
- const base::Callback<void(bool)>& callback) {
+ base::OnceCallback<void(bool)> callback) {
size_t frame_index = PaintImage::kDefaultFrameIndex;
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"DecodedImageTracker::QueueImageDecode", "frame_key",
@@ -50,9 +51,9 @@ void DecodedImageTracker::QueueImageDecode(
DrawImage draw_image(image, image_bounds, kNone_SkFilterQuality,
SkMatrix::I(), frame_index);
image_controller_->QueueImageDecode(
- draw_image,
- base::Bind(&DecodedImageTracker::ImageDecodeFinished,
- base::Unretained(this), callback, image.stable_id()));
+ draw_image, base::BindOnce(&DecodedImageTracker::ImageDecodeFinished,
+ base::Unretained(this), std::move(callback),
+ image.stable_id()));
}
void DecodedImageTracker::UnlockAllImages() {
@@ -66,7 +67,7 @@ void DecodedImageTracker::OnImagesUsedInDraw(
}
void DecodedImageTracker::ImageDecodeFinished(
- const base::Callback<void(bool)>& callback,
+ base::OnceCallback<void(bool)> callback,
PaintImage::Id image_id,
ImageController::ImageDecodeRequestId request_id,
ImageController::ImageDecodeResult result) {
@@ -78,13 +79,14 @@ void DecodedImageTracker::ImageDecodeFinished(
// decode.
locked_images_.erase(image_id);
locked_images_.emplace(
- image_id, std::make_unique<ImageLock>(this, request_id, now_fn_.Run()));
+ image_id,
+ std::make_unique<ImageLock>(this, request_id, tick_clock_->NowTicks()));
EnqueueTimeout();
}
bool decode_succeeded =
result == ImageController::ImageDecodeResult::SUCCESS ||
result == ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED;
- callback.Run(decode_succeeded);
+ std::move(callback).Run(decode_succeeded);
}
void DecodedImageTracker::OnTimeoutImages() {
@@ -92,7 +94,7 @@ void DecodedImageTracker::OnTimeoutImages() {
if (locked_images_.size() == 0)
return;
- auto now = now_fn_.Run();
+ auto now = tick_clock_->NowTicks();
auto timeout = base::TimeDelta::FromMilliseconds(kTimeoutDurationMs);
for (auto it = locked_images_.begin(); it != locked_images_.end();) {
auto& image = it->second;
@@ -115,8 +117,8 @@ void DecodedImageTracker::EnqueueTimeout() {
timeout_pending_ = true;
task_runner_->PostDelayedTask(
FROM_HERE,
- base::Bind(&DecodedImageTracker::OnTimeoutImages,
- weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(&DecodedImageTracker::OnTimeoutImages,
+ weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kTimeoutDurationMs));
}
diff --git a/chromium/cc/tiles/decoded_image_tracker.h b/chromium/cc/tiles/decoded_image_tracker.h
index e16b614e48d..c88bd2b593a 100644
--- a/chromium/cc/tiles/decoded_image_tracker.h
+++ b/chromium/cc/tiles/decoded_image_tracker.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/tiles/image_controller.h"
@@ -34,7 +35,7 @@ class CC_EXPORT DecodedImageTracker {
// completion. The callback takes a bool indicating whether the decode was
// successful or not.
void QueueImageDecode(const PaintImage& image,
- const base::Callback<void(bool)>& callback);
+ base::OnceCallback<void(bool)> callback);
// Unlock all locked images - used to respond to memory pressure or
// application background.
@@ -44,8 +45,9 @@ class CC_EXPORT DecodedImageTracker {
// unlock them.
void OnImagesUsedInDraw(const std::vector<DrawImage>& draw_images);
- using NowFn = base::Callback<base::TimeTicks()>;
- void SetNowFunctionForTesting(NowFn now_fn) { now_fn_ = now_fn; }
+ void SetTickClockForTesting(const base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
+ }
// Test only functions:
size_t NumLockedImagesForTesting() const { return locked_images_.size(); }
@@ -53,7 +55,7 @@ class CC_EXPORT DecodedImageTracker {
private:
friend class DecodedImageTrackerTest;
- void ImageDecodeFinished(const base::Callback<void(bool)>& callback,
+ void ImageDecodeFinished(base::OnceCallback<void(bool)> callback,
PaintImage::Id image_id,
ImageController::ImageDecodeRequestId request_id,
ImageController::ImageDecodeResult result);
@@ -83,7 +85,7 @@ class CC_EXPORT DecodedImageTracker {
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Defaults to base::TimeTicks::Now(), but overrideable for testing.
- NowFn now_fn_;
+ const base::TickClock* tick_clock_;
base::WeakPtrFactory<DecodedImageTracker> weak_ptr_factory_;
diff --git a/chromium/cc/tiles/decoded_image_tracker_unittest.cc b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
index 4049261893f..e481894e866 100644
--- a/chromium/cc/tiles/decoded_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
@@ -32,12 +32,12 @@ class TestImageController : public ImageController {
ImageDecodeRequestId QueueImageDecode(
const DrawImage& image,
- const ImageDecodedCallback& callback) override {
+ ImageDecodedCallback callback) override {
auto id = next_id_++;
locked_ids_.insert(
std::make_pair(id, SoftwareImageDecodeCache::CacheKey::FromDrawImage(
image, kRGBA_8888_SkColorType)));
- callback.Run(id, ImageDecodeResult::SUCCESS);
+ std::move(callback).Run(id, ImageDecodeResult::SUCCESS);
return id;
}
@@ -67,8 +67,8 @@ class DecodedImageTrackerTest : public testing::Test {
DecodedImageTrackerTest()
: task_runner_(new base::TestMockTimeTaskRunner()),
decoded_image_tracker_(&image_controller_, task_runner_) {
- decoded_image_tracker_.SetNowFunctionForTesting(
- base::Bind(&base::TestMockTimeTaskRunner::NowTicks, task_runner_));
+ decoded_image_tracker_.SetTickClockForTesting(
+ task_runner_->GetMockTickClock());
}
TestImageController* image_controller() { return &image_controller_; }
@@ -87,8 +87,8 @@ TEST_F(DecodedImageTrackerTest, QueueImageLocksImages) {
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
CreateDiscardablePaintImage(gfx::Size(1, 1)),
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
}
@@ -98,8 +98,8 @@ TEST_F(DecodedImageTrackerTest, ImagesTimeOut) {
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
CreateDiscardablePaintImage(gfx::Size(1, 1)),
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
@@ -110,8 +110,8 @@ TEST_F(DecodedImageTrackerTest, ImagesTimeOut) {
// Add an image, this will not start a new timeout, as one is pending.
decoded_image_tracker()->QueueImageDecode(
CreateDiscardablePaintImage(gfx::Size(1, 1)),
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(2u, image_controller()->num_locked_images());
@@ -131,16 +131,16 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
auto paint_image_1 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
paint_image_1,
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
auto paint_image_2 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
paint_image_2,
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(2u, image_controller()->num_locked_images());
@@ -167,14 +167,14 @@ TEST_F(DecodedImageTrackerTest, UnlockAllImages) {
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
CreateDiscardablePaintImage(gfx::Size(1, 1)),
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
decoded_image_tracker()->QueueImageDecode(
CreateDiscardablePaintImage(gfx::Size(1, 1)),
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(2u, image_controller()->num_locked_images());
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 6e3ae2ba974..18fd0734195 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -1543,7 +1543,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
ClientImageTransferCacheEntry image_entry(&pixmap, color_space.get(),
image_data->needs_mips);
- size_t size = image_entry.SerializedSize();
+ uint32_t size = image_entry.SerializedSize();
void* data = context_->ContextSupport()->MapTransferCacheEntry(size);
if (data) {
bool succeeded = image_entry.Serialize(
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index 526c1dd4aaf..5cb51724f89 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -132,7 +132,7 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
void CompleteLockDiscardableTexureOnContextThread(
uint32_t texture_id) override {}
- void* MapTransferCacheEntry(size_t serialized_size) override {
+ void* MapTransferCacheEntry(uint32_t serialized_size) override {
mapped_entry_size_ = serialized_size;
mapped_entry_.reset(new uint8_t[serialized_size]);
return mapped_entry_.get();
@@ -2120,7 +2120,8 @@ TEST_P(GpuImageDecodeCacheTest,
// image we've cached.
EXPECT_TRUE(decoded_image == decoded_draw_image.image());
// Ensure that the SW decoded image had colorspace conversion applied.
- EXPECT_TRUE(decoded_image->colorSpace() == target_color_space.get());
+ EXPECT_TRUE(SkColorSpace::Equals(decoded_image->colorSpace(),
+ target_color_space.get()));
}
cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -2169,8 +2170,8 @@ TEST_P(GpuImageDecodeCacheTest,
target_color_space.get()));
} else {
// Ensure that the HW uploaded image had color space conversion applied.
- EXPECT_TRUE(decoded_draw_image.image()->colorSpace() ==
- target_color_space.get());
+ EXPECT_TRUE(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
+ target_color_space.get()));
}
cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -2547,12 +2548,6 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
}
TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
-#if defined(OS_WIN)
- // TODO(ericrk): Mips are temporarily disabled to investigate a memory
- // regression on Windows. https://crbug.com/867468
- return;
-#endif // defined(OS_WIN)
-
auto cache = CreateCache();
bool is_decomposable = true;
auto filter_quality = kMedium_SkFilterQuality;
diff --git a/chromium/cc/tiles/image_controller.cc b/chromium/cc/tiles/image_controller.cc
index d6a91504c08..844f8c42d65 100644
--- a/chromium/cc/tiles/image_controller.cc
+++ b/chromium/cc/tiles/image_controller.cc
@@ -29,7 +29,7 @@ ImageController::ImageController(
ImageController::~ImageController() {
StopWorkerTasks();
for (auto& request : orphaned_decode_requests_)
- request.callback.Run(request.id, ImageDecodeResult::FAILURE);
+ std::move(request.callback).Run(request.id, ImageDecodeResult::FAILURE);
}
void ImageController::StopWorkerTasks() {
@@ -129,6 +129,11 @@ void ImageController::StopWorkerTasks() {
image_decode_queue_.clear();
}
+void ImageController::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ paint_worklet_image_cache_.SetPaintWorkletLayerPainter(std::move(painter));
+}
+
void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) {
DCHECK(!cache_ || !cache);
@@ -147,7 +152,27 @@ void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) {
}
}
-void ImageController::GetTasksForImagesAndRef(
+void ImageController::ConvertPaintWorkletImagesToTask(
+ std::vector<DrawImage>* sync_decoded_images,
+ std::vector<scoped_refptr<TileTask>>* tasks) {
+ for (auto it = sync_decoded_images->begin();
+ it != sync_decoded_images->end();) {
+ if (!it->paint_image().IsPaintWorklet()) {
+ ++it;
+ continue;
+ }
+ scoped_refptr<TileTask> result =
+ paint_worklet_image_cache_.GetTaskForPaintWorkletImage(*it);
+ DCHECK(result);
+ tasks->push_back(std::move(result));
+ // Remove it so that there is no need to check whether an image is
+ // PaintWorklet generated or not in TileManager's
+ // work_to_schedule->extra_prepaint_images.insert.
+ it = sync_decoded_images->erase(it);
+ }
+}
+
+void ImageController::ConvertDataImagesToTasks(
std::vector<DrawImage>* sync_decoded_images,
std::vector<scoped_refptr<TileTask>>* tasks,
bool* has_at_raster_images,
@@ -156,6 +181,10 @@ void ImageController::GetTasksForImagesAndRef(
*has_at_raster_images = false;
for (auto it = sync_decoded_images->begin();
it != sync_decoded_images->end();) {
+ if (it->paint_image().IsPaintWorklet()) {
+ ++it;
+ continue;
+ }
ImageDecodeCache::TaskResult result =
cache_->GetTaskForImageAndRef(*it, tracing_info);
*has_at_raster_images |= result.IsAtRaster();
@@ -183,8 +212,8 @@ std::vector<scoped_refptr<TileTask>> ImageController::SetPredecodeImages(
const ImageDecodeCache::TracingInfo& tracing_info) {
std::vector<scoped_refptr<TileTask>> new_tasks;
bool has_at_raster_images = false;
- GetTasksForImagesAndRef(&images, &new_tasks, &has_at_raster_images,
- tracing_info);
+ ConvertDataImagesToTasks(&images, &new_tasks, &has_at_raster_images,
+ tracing_info);
UnrefImages(predecode_locked_images_);
predecode_locked_images_ = std::move(images);
return new_tasks;
@@ -192,7 +221,7 @@ std::vector<scoped_refptr<TileTask>> ImageController::SetPredecodeImages(
ImageController::ImageDecodeRequestId ImageController::QueueImageDecode(
const DrawImage& draw_image,
- const ImageDecodedCallback& callback) {
+ ImageDecodedCallback callback) {
// We must not receive any image requests if we have no worker.
CHECK(worker_task_runner_);
@@ -211,8 +240,9 @@ ImageController::ImageDecodeRequestId ImageController::QueueImageDecode(
// Schedule the task and signal that there is more work.
base::AutoLock hold(lock_);
- image_decode_queue_[id] = ImageDecodeRequest(
- id, draw_image, callback, std::move(result.task), result.need_unref);
+ image_decode_queue_[id] =
+ ImageDecodeRequest(id, draw_image, std::move(callback),
+ std::move(result.task), result.need_unref);
// If this is the only image decode request, schedule a task to run.
// Otherwise, the task will be scheduled in the previou task's completion.
@@ -239,7 +269,8 @@ void ImageController::UnlockImageDecode(ImageDecodeRequestId id) {
void ImageController::ProcessNextImageDecodeOnWorkerThread() {
TRACE_EVENT0("cc", "ImageController::ProcessNextImageDecodeOnWorkerThread");
- ImageDecodeRequest decode;
+ scoped_refptr<TileTask> decode_task;
+ ImageDecodeRequestId decode_id;
{
base::AutoLock hold(lock_);
@@ -250,8 +281,8 @@ void ImageController::ProcessNextImageDecodeOnWorkerThread() {
// Take the next request from the queue.
auto decode_it = image_decode_queue_.begin();
DCHECK(decode_it != image_decode_queue_.end());
- decode = std::move(decode_it->second);
- image_decode_queue_.erase(decode_it);
+ decode_task = decode_it->second.task;
+ decode_id = decode_it->second.id;
// Notify that the task will need completion. Note that there are two cases
// where we process this. First, we might complete this task as a response
@@ -260,7 +291,9 @@ void ImageController::ProcessNextImageDecodeOnWorkerThread() {
// (either post task happens after running, or the thread was already joined
// which means the task ran). This means that we can put the decode into
// |requests_needing_completion_| here before actually running the task.
- requests_needing_completion_[decode.id] = decode;
+ requests_needing_completion_[decode_id] = std::move(decode_it->second);
+
+ image_decode_queue_.erase(decode_it);
}
// Run the task if we need to run it. If the task state isn't new, then
@@ -269,15 +302,15 @@ void ImageController::ProcessNextImageDecodeOnWorkerThread() {
// Note that the other tasks's completion will also run first, since the
// requests are ordered. So, when we process this task's completion, we
// won't actually do anything with the task and simply issue the callback.
- if (decode.task && decode.task->state().IsNew()) {
- decode.task->state().DidSchedule();
- decode.task->state().DidStart();
- decode.task->RunOnWorkerThread();
- decode.task->state().DidFinish();
+ if (decode_task && decode_task->state().IsNew()) {
+ decode_task->state().DidSchedule();
+ decode_task->state().DidStart();
+ decode_task->RunOnWorkerThread();
+ decode_task->state().DidFinish();
}
origin_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ImageController::ImageDecodeCompleted,
- weak_ptr_, decode.id));
+ weak_ptr_, decode_id));
}
void ImageController::ImageDecodeCompleted(ImageDecodeRequestId id) {
@@ -328,7 +361,7 @@ void ImageController::ImageDecodeCompleted(ImageDecodeRequestId id) {
base::Unretained(this)));
// Finally run the requested callback.
- callback.Run(id, result);
+ std::move(callback).Run(id, result);
}
void ImageController::GenerateTasksForOrphanedRequests() {
@@ -364,23 +397,19 @@ ImageController::ImageDecodeRequest::ImageDecodeRequest() = default;
ImageController::ImageDecodeRequest::ImageDecodeRequest(
ImageDecodeRequestId id,
const DrawImage& draw_image,
- const ImageDecodedCallback& callback,
+ ImageDecodedCallback callback,
scoped_refptr<TileTask> task,
bool need_unref)
: id(id),
draw_image(draw_image),
- callback(callback),
+ callback(std::move(callback)),
task(std::move(task)),
need_unref(need_unref) {}
ImageController::ImageDecodeRequest::ImageDecodeRequest(
ImageDecodeRequest&& other) = default;
-ImageController::ImageDecodeRequest::ImageDecodeRequest(
- const ImageDecodeRequest& other) = default;
ImageController::ImageDecodeRequest::~ImageDecodeRequest() = default;
ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest::
operator=(ImageDecodeRequest&& other) = default;
-ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest::
-operator=(const ImageDecodeRequest& other) = default;
} // namespace cc
diff --git a/chromium/cc/tiles/image_controller.h b/chromium/cc/tiles/image_controller.h
index b15c6b545ff..d5540106f94 100644
--- a/chromium/cc/tiles/image_controller.h
+++ b/chromium/cc/tiles/image_controller.h
@@ -20,6 +20,7 @@
#include "cc/paint/draw_image.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/image_decode_cache.h"
+#include "cc/tiles/paint_worklet_image_cache.h"
namespace cc {
@@ -29,18 +30,39 @@ class CC_EXPORT ImageController {
using ImageDecodeRequestId = uint64_t;
using ImageDecodedCallback =
- base::Callback<void(ImageDecodeRequestId, ImageDecodeResult)>;
+ base::OnceCallback<void(ImageDecodeRequestId, ImageDecodeResult)>;
explicit ImageController(
base::SequencedTaskRunner* origin_task_runner,
scoped_refptr<base::SequencedTaskRunner> worker_task_runner);
virtual ~ImageController();
void SetImageDecodeCache(ImageDecodeCache* cache);
- void GetTasksForImagesAndRef(
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
+ // The name "Data images" are the images that are not generated by
+ // PaintWorklet.
+ // Build tile tasks for synchronously decoded images that are not generated by
+ // PaintWorklet.
+ // |sync_decoded_images| is the input. These are the images from a particular
+ // tile, retrieved by the DiscardableImageMap. Images can be removed from the
+ // vector under certain conditions.
+ // |tasks| is an output, which are the built tile tasks.
+ // |has_at_raster_images| is an output parameter.
+ // |tracing_info| is used in tracing or UMA only.
+ void ConvertDataImagesToTasks(
std::vector<DrawImage>* sync_decoded_images,
std::vector<scoped_refptr<TileTask>>* tasks,
bool* has_at_raster_images,
const ImageDecodeCache::TracingInfo& tracing_info);
+ // TODO(crbug.com/915566): bundle all tasks into a big TaskBag.
+ // Build tile tasks for images that are generated by PaintWorklet.
+ // |sync_decoded_images| is the input, which are the images from a particular
+ // tile, retrieved by DiscardableImageMap. Images are removed from the vector
+ // once the tile task is built.
+ // |tasks| is an output, which are the built tile tasks.
+ void ConvertPaintWorkletImagesToTask(
+ std::vector<DrawImage>* sync_decoded_images,
+ std::vector<scoped_refptr<TileTask>>* tasks);
void UnrefImages(const std::vector<DrawImage>& images);
void ReduceMemoryUsage();
std::vector<scoped_refptr<TileTask>> SetPredecodeImages(
@@ -55,9 +77,8 @@ class CC_EXPORT ImageController {
// unlock this image. It is up to the caller to ensure that the image is later
// unlocked using UnlockImageDecode.
// Virtual for testing.
- virtual ImageDecodeRequestId QueueImageDecode(
- const DrawImage& draw_image,
- const ImageDecodedCallback& callback);
+ virtual ImageDecodeRequestId QueueImageDecode(const DrawImage& draw_image,
+ ImageDecodedCallback callback);
size_t image_cache_max_limit_bytes() const {
return image_cache_max_limit_bytes_;
}
@@ -67,6 +88,9 @@ class CC_EXPORT ImageController {
}
ImageDecodeCache* cache() const { return cache_; }
+ PaintWorkletImageCache* paint_worklet_image_cache() {
+ return &paint_worklet_image_cache_;
+ }
protected:
scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;
@@ -76,15 +100,13 @@ class CC_EXPORT ImageController {
ImageDecodeRequest();
ImageDecodeRequest(ImageDecodeRequestId id,
const DrawImage& draw_image,
- const ImageDecodedCallback& callback,
+ ImageDecodedCallback callback,
scoped_refptr<TileTask> task,
bool need_unref);
ImageDecodeRequest(ImageDecodeRequest&& other);
- ImageDecodeRequest(const ImageDecodeRequest& other);
~ImageDecodeRequest();
ImageDecodeRequest& operator=(ImageDecodeRequest&& other);
- ImageDecodeRequest& operator=(const ImageDecodeRequest& other);
ImageDecodeRequestId id;
DrawImage draw_image;
@@ -104,6 +126,7 @@ class CC_EXPORT ImageController {
base::WeakPtr<ImageController> weak_ptr_;
ImageDecodeCache* cache_ = nullptr;
+ PaintWorkletImageCache paint_worklet_image_cache_;
std::vector<DrawImage> predecode_locked_images_;
static ImageDecodeRequestId s_next_image_decode_queue_id_;
diff --git a/chromium/cc/tiles/image_controller_unittest.cc b/chromium/cc/tiles/image_controller_unittest.cc
index 473c7c25d5f..dad3a619c23 100644
--- a/chromium/cc/tiles/image_controller_unittest.cc
+++ b/chromium/cc/tiles/image_controller_unittest.cc
@@ -15,6 +15,7 @@
#include "cc/paint/paint_image_builder.h"
#include "cc/test/skia_common.h"
#include "cc/test/stub_decode_cache.h"
+#include "cc/test/test_paint_worklet_input.h"
#include "cc/tiles/image_decode_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -285,6 +286,24 @@ class ImageControllerTest : public testing::Test {
void ResetController() { controller_.reset(); }
+ SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
+ SkMatrix matrix;
+ matrix.setScale(scale.width(), scale.height());
+
+ if (!is_decomposable) {
+ // Perspective is not decomposable, add it.
+ matrix[SkMatrix::kMPersp0] = 0.1f;
+ }
+
+ return matrix;
+ }
+
+ PaintImage CreatePaintImage(int width, int height) {
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(width, height));
+ return CreatePaintWorkletPaintImage(input);
+ }
+
private:
scoped_refptr<base::SequencedTaskRunner> task_runner_;
scoped_refptr<WorkerTaskRunner> worker_task_runner_;
@@ -295,6 +314,28 @@ class ImageControllerTest : public testing::Test {
base::WeakPtrFactory<ImageControllerTest> weak_ptr_factory_;
};
+// Test that GetTasksForImagesAndRef does not generate task for PaintWorklet
+// images.
+TEST_F(ImageControllerTest, GetTasksForImagesAndRefForPaintWorkletImages) {
+ std::vector<DrawImage> images(1);
+ ImageDecodeCache::TracingInfo tracing_info;
+
+ PaintImage paint_image = CreatePaintImage(100, 100);
+ DrawImage draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ kNone_SkFilterQuality, CreateMatrix(SkSize::Make(1.f, 1.f), true),
+ PaintImage::kDefaultFrameIndex);
+ images[0] = draw_image;
+
+ ASSERT_EQ(1u, images.size());
+
+ std::vector<scoped_refptr<TileTask>> tasks;
+ bool has_at_raster_images = false;
+ controller()->ConvertDataImagesToTasks(&images, &tasks, &has_at_raster_images,
+ tracing_info);
+ EXPECT_EQ(tasks.size(), 0u);
+}
+
TEST_F(ImageControllerTest, NullControllerUnrefsImages) {
std::vector<DrawImage> images(10);
ImageDecodeCache::TracingInfo tracing_info;
@@ -315,9 +356,9 @@ TEST_F(ImageControllerTest, QueueImageDecode) {
EXPECT_EQ(image().paint_image().width(), 1);
ImageController::ImageDecodeRequestId expected_id =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
- run_loop.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id, decode_client.id());
EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
@@ -332,9 +373,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeNonLazy) {
ImageController::ImageDecodeRequestId expected_id =
controller()->QueueImageDecode(
- image,
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
- run_loop.QuitClosure()));
+ image, base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id, decode_client.id());
EXPECT_EQ(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED,
@@ -348,9 +389,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeTooLarge) {
DrawImage image = CreateDiscardableDrawImage(gfx::Size(2000, 2000));
ImageController::ImageDecodeRequestId expected_id =
controller()->QueueImageDecode(
- image,
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
- run_loop.QuitClosure()));
+ image, base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id, decode_client.id());
EXPECT_EQ(ImageController::ImageDecodeResult::FAILURE,
@@ -362,21 +403,21 @@ TEST_F(ImageControllerTest, QueueImageDecodeMultipleImages) {
DecodeClient decode_client1;
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- base::Bind([] {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ base::DoNothing::Once()));
DecodeClient decode_client2;
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- base::Bind([] {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ base::DoNothing::Once()));
DecodeClient decode_client3;
ImageController::ImageDecodeRequestId expected_id3 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3),
- run_loop.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client3),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id1, decode_client1.id());
EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
@@ -397,9 +438,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeWithTask) {
DecodeClient decode_client;
ImageController::ImageDecodeRequestId expected_id =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
- run_loop.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id, decode_client.id());
EXPECT_TRUE(task->has_run());
@@ -414,21 +455,21 @@ TEST_F(ImageControllerTest, QueueImageDecodeMultipleImagesSameTask) {
DecodeClient decode_client1;
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- base::Bind([] {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ base::DoNothing::Once()));
DecodeClient decode_client2;
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- base::Bind([] {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ base::DoNothing::Once()));
DecodeClient decode_client3;
ImageController::ImageDecodeRequestId expected_id3 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3),
- run_loop.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client3),
+ run_loop.QuitClosure()));
RunOrTimeout(&run_loop);
EXPECT_EQ(expected_id1, decode_client1.id());
EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
@@ -450,9 +491,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeChangeControllerWithTaskQueued) {
DecodeClient decode_client1;
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- base::Bind([] {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ base::DoNothing::Once()));
scoped_refptr<BlockingTask> task_two(new BlockingTask);
cache()->SetTaskToUse(task_two);
@@ -461,9 +502,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeChangeControllerWithTaskQueued) {
DecodeClient decode_client2;
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- run_loop.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ run_loop.QuitClosure()));
task_one->AllowToRun();
task_two->AllowToRun();
@@ -486,9 +527,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeImageAlreadyLocked) {
DecodeClient decode_client1;
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- run_loop1.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ run_loop1.QuitClosure()));
RunOrTimeout(&run_loop1);
EXPECT_EQ(expected_id1, decode_client1.id());
EXPECT_TRUE(task->has_run());
@@ -498,9 +539,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeImageAlreadyLocked) {
DecodeClient decode_client2;
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- run_loop2.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ run_loop2.QuitClosure()));
RunOrTimeout(&run_loop2);
EXPECT_EQ(expected_id2, decode_client2.id());
EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
@@ -515,9 +556,9 @@ TEST_F(ImageControllerTest, QueueImageDecodeLockedImageControllerChange) {
DecodeClient decode_client1;
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- run_loop1.QuitClosure()));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ run_loop1.QuitClosure()));
RunOrTimeout(&run_loop1);
EXPECT_EQ(expected_id1, decode_client1.id());
EXPECT_TRUE(task->has_run());
@@ -538,12 +579,12 @@ TEST_F(ImageControllerTest, DispatchesDecodeCallbacksAfterCacheReset) {
controller()->QueueImageDecode(
image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- run_loop1.QuitClosure()));
+ base::BindOnce(&DecodeClient::Callback, base::Unretained(&decode_client1),
+ run_loop1.QuitClosure()));
controller()->QueueImageDecode(
image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- run_loop2.QuitClosure()));
+ base::BindOnce(&DecodeClient::Callback, base::Unretained(&decode_client2),
+ run_loop2.QuitClosure()));
// Now reset the image cache before decode completed callbacks are posted to
// the compositor thread. Ensure that the completion callbacks for the decode
@@ -571,12 +612,12 @@ TEST_F(ImageControllerTest, DispatchesDecodeCallbacksAfterCacheChanged) {
controller()->QueueImageDecode(
image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- run_loop1.QuitClosure()));
+ base::BindOnce(&DecodeClient::Callback, base::Unretained(&decode_client1),
+ run_loop1.QuitClosure()));
controller()->QueueImageDecode(
image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- run_loop2.QuitClosure()));
+ base::BindOnce(&DecodeClient::Callback, base::Unretained(&decode_client2),
+ run_loop2.QuitClosure()));
// Now reset the image cache before decode completed callbacks are posted to
// the compositor thread. This should orphan the requests.
@@ -615,15 +656,15 @@ TEST_F(ImageControllerTest, QueueImageDecodeLazyCancelImmediately) {
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- base::Bind([]() {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ base::DoNothing::Once()));
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image(),
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- base::Bind([]() {})));
+ image(), base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ base::DoNothing::Once()));
// This needs a ref because it is lazy.
EXPECT_EQ(2, cache()->number_of_refs());
@@ -660,14 +701,14 @@ TEST_F(ImageControllerTest, QueueImageDecodeNonLazyCancelImmediately) {
ImageController::ImageDecodeRequestId expected_id1 =
controller()->QueueImageDecode(
- image1,
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
- base::Bind([]() {})));
+ image1, base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client1),
+ base::DoNothing::Once()));
ImageController::ImageDecodeRequestId expected_id2 =
controller()->QueueImageDecode(
- image2,
- base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
- base::Bind([]() {})));
+ image2, base::BindOnce(&DecodeClient::Callback,
+ base::Unretained(&decode_client2),
+ base::DoNothing::Once()));
// No ref needed here, because it is non-lazy.
EXPECT_EQ(0, cache()->number_of_refs());
diff --git a/chromium/cc/tiles/paint_worklet_image_cache.cc b/chromium/cc/tiles/paint_worklet_image_cache.cc
new file mode 100644
index 00000000000..47f7773692c
--- /dev/null
+++ b/chromium/cc/tiles/paint_worklet_image_cache.cc
@@ -0,0 +1,61 @@
+// Copyright 2018 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/tiles/paint_worklet_image_cache.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
+
+namespace cc {
+
+// TODO(xidachen): Rename this to PaintWorkletTaskImpl.
+class PaintWorkletImageCacheImpl : public TileTask {
+ public:
+ PaintWorkletImageCacheImpl(PaintWorkletImageCache* cache,
+ const PaintImage& paint_image)
+ : TileTask(true), cache_(cache), paint_image_(paint_image) {}
+
+ // Overridden from Task:
+ void RunOnWorkerThread() override { cache_->PaintImageInTask(paint_image_); }
+
+ // Overridden from TileTask:
+ void OnTaskCompleted() override {}
+
+ protected:
+ ~PaintWorkletImageCacheImpl() override = default;
+
+ private:
+ PaintWorkletImageCache* cache_;
+ PaintImage paint_image_;
+
+ DISALLOW_COPY_AND_ASSIGN(PaintWorkletImageCacheImpl);
+};
+
+PaintWorkletImageCache::PaintWorkletImageCache() {}
+
+PaintWorkletImageCache::~PaintWorkletImageCache() {}
+
+void PaintWorkletImageCache::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ painter_ = std::move(painter);
+}
+
+scoped_refptr<TileTask> PaintWorkletImageCache::GetTaskForPaintWorkletImage(
+ const DrawImage& image) {
+ return base::MakeRefCounted<PaintWorkletImageCacheImpl>(this,
+ image.paint_image());
+}
+
+// TODO(xidachen): dispatch the work to a worklet thread, invoke JS callback.
+// Do check the cache first. If there is already a cache entry for this input,
+// then there is no need to call the Paint() function.
+void PaintWorkletImageCache::PaintImageInTask(const PaintImage& paint_image) {
+ sk_sp<PaintRecord> record = painter_->Paint();
+ records_[paint_image.paint_worklet_input()] = record;
+}
+
+PaintRecord* PaintWorkletImageCache::GetPaintRecordForTest(
+ PaintWorkletInput* input) {
+ return records_[input].get();
+}
+
+} // namespace cc
diff --git a/chromium/cc/tiles/paint_worklet_image_cache.h b/chromium/cc/tiles/paint_worklet_image_cache.h
new file mode 100644
index 00000000000..d857dc3ebeb
--- /dev/null
+++ b/chromium/cc/tiles/paint_worklet_image_cache.h
@@ -0,0 +1,52 @@
+// Copyright 2018 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_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
+#define CC_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
+
+#include "base/containers/flat_map.h"
+#include "cc/cc_export.h"
+#include "cc/paint/draw_image.h"
+#include "cc/paint/paint_record.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
+#include "cc/raster/tile_task.h"
+#include "cc/tiles/image_decode_cache.h"
+
+namespace cc {
+
+// PaintWorkletImageCache is responsible for generating tasks of executing
+// PaintWorklet JS paint callbacks, and being able to return the generated
+// results when requested.
+class CC_EXPORT PaintWorkletImageCache {
+ public:
+ PaintWorkletImageCache();
+
+ ~PaintWorkletImageCache();
+
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
+
+ scoped_refptr<TileTask> GetTaskForPaintWorkletImage(const DrawImage& image);
+
+ void PaintImageInTask(const PaintImage& paint_image);
+
+ PaintRecord* GetPaintRecordForTest(PaintWorkletInput* input);
+ const base::flat_map<PaintWorkletInput*, sk_sp<PaintRecord>>&
+ GetRecordsForTest() {
+ return records_;
+ }
+
+ private:
+ // The PaintRecord is produced by PaintWorkletLayerPainter::Paint(), and used
+ // for raster.
+ base::flat_map<PaintWorkletInput*, sk_sp<PaintRecord>> records_;
+ // The PaintWorkletImageCache is owned by ImageController, which has the same
+ // life time as the LayerTreeHostImpl, that guarantees that the painter will
+ // live as long as the LayerTreeHostImpl.
+ std::unique_ptr<PaintWorkletLayerPainter> painter_;
+};
+
+} // namespace cc
+
+#endif // CC_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
diff --git a/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc b/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
new file mode 100644
index 00000000000..18355d430b7
--- /dev/null
+++ b/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2018 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/tiles/paint_worklet_image_cache.h"
+
+#include "cc/paint/draw_image.h"
+#include "cc/test/skia_common.h"
+#include "cc/test/test_paint_worklet_input.h"
+#include "cc/test/test_paint_worklet_layer_painter.h"
+#include "cc/test/test_tile_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class TestPaintWorkletImageCache : public PaintWorkletImageCache {
+ public:
+ TestPaintWorkletImageCache() {}
+};
+
+SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
+ SkMatrix matrix;
+ matrix.setScale(scale.width(), scale.height());
+
+ if (!is_decomposable) {
+ // Perspective is not decomposable, add it.
+ matrix[SkMatrix::kMPersp0] = 0.1f;
+ }
+
+ return matrix;
+}
+
+PaintImage CreatePaintImage(int width, int height) {
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(width, height));
+ return CreatePaintWorkletPaintImage(input);
+}
+
+scoped_refptr<TileTask> GetTaskForPaintWorkletImage(
+ const PaintImage& paint_image,
+ TestPaintWorkletImageCache* cache) {
+ DrawImage draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ kNone_SkFilterQuality, CreateMatrix(SkSize::Make(1.f, 1.f), true),
+ PaintImage::kDefaultFrameIndex);
+ std::unique_ptr<TestPaintWorkletLayerPainter> painter =
+ std::make_unique<TestPaintWorkletLayerPainter>();
+ cache->SetPaintWorkletLayerPainter(std::move(painter));
+ return cache->GetTaskForPaintWorkletImage(draw_image);
+}
+
+void TestPaintRecord(PaintRecord* record) {
+ EXPECT_EQ(record->total_op_count(), 1u);
+
+ // GetOpAtForTesting check whether the type is the same as DrawImageOp or not.
+ // If not, it returns a nullptr.
+ auto* paint_op = record->GetOpAtForTesting<DrawImageOp>(0);
+ EXPECT_TRUE(paint_op);
+}
+
+TEST(PaintWorkletImageCacheTest, GetTaskForImage) {
+ TestPaintWorkletImageCache cache;
+ PaintImage paint_image = CreatePaintImage(100, 100);
+ scoped_refptr<TileTask> task =
+ GetTaskForPaintWorkletImage(paint_image, &cache);
+ EXPECT_TRUE(task);
+
+ TestTileTaskRunner::ProcessTask(task.get());
+
+ PaintRecord* record =
+ cache.GetPaintRecordForTest(paint_image.paint_worklet_input());
+ TestPaintRecord(record);
+}
+
+TEST(PaintWorkletImageCacheTest, MultipleRecordsInCache) {
+ TestPaintWorkletImageCache cache;
+ PaintImage paint_image1 = CreatePaintImage(100, 100);
+ scoped_refptr<TileTask> task1 =
+ GetTaskForPaintWorkletImage(paint_image1, &cache);
+ EXPECT_TRUE(task1);
+ PaintImage paint_image2 = CreatePaintImage(200, 200);
+ scoped_refptr<TileTask> task2 =
+ GetTaskForPaintWorkletImage(paint_image2, &cache);
+ EXPECT_TRUE(task2);
+
+ TestTileTaskRunner::ProcessTask(task1.get());
+ TestTileTaskRunner::ProcessTask(task2.get());
+
+ base::flat_map<PaintWorkletInput*, sk_sp<PaintRecord>> records =
+ cache.GetRecordsForTest();
+ EXPECT_EQ(records.size(), 2u);
+
+ PaintRecord* record1 = records[paint_image1.paint_worklet_input()].get();
+ EXPECT_TRUE(record1);
+ TestPaintRecord(record1);
+
+ PaintRecord* record2 = records[paint_image2.paint_worklet_input()].get();
+ EXPECT_TRUE(record2);
+ TestPaintRecord(record2);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc
index c16c0bb291b..d8347eb17ec 100644
--- a/chromium/cc/tiles/picture_layer_tiling.cc
+++ b/chromium/cc/tiles/picture_layer_tiling.cc
@@ -14,6 +14,7 @@
#include "base/containers/flat_map.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
+#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
@@ -587,7 +588,7 @@ void PictureLayerTiling::ComputeTilePriorityRects(
&visible_rect_in_layer_space, &skewport_in_layer_space,
&soon_border_rect_in_layer_space, &eventually_rect_in_layer_space};
gfx::Rect output_rects[4];
- for (size_t i = 0; i < arraysize(input_rects); ++i)
+ for (size_t i = 0; i < base::size(input_rects); ++i)
output_rects[i] = EnclosingContentsRectFromLayerRect(*input_rects[i]);
// Make sure the eventually rect is aligned to tile bounds.
output_rects[3] =
diff --git a/chromium/cc/tiles/picture_layer_tiling_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_unittest.cc
index 7931cbb31e4..4a98325ef56 100644
--- a/chromium/cc/tiles/picture_layer_tiling_unittest.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_unittest.cc
@@ -86,6 +86,9 @@ class TestablePictureLayerTiling : public PictureLayerTiling {
class PictureLayerTilingIteratorTest : public testing::Test {
public:
+ using VerifyTilesCallback =
+ base::RepeatingCallback<void(Tile* tile, const gfx::Rect& geometry_rect)>;
+
PictureLayerTilingIteratorTest() = default;
~PictureLayerTilingIteratorTest() override = default;
@@ -183,27 +186,19 @@ class PictureLayerTilingIteratorTest : public testing::Test {
VerifyTilesExactlyCoverRect(rect_scale, rect, rect);
}
- void VerifyTiles(
- float rect_scale,
- const gfx::Rect& rect,
- base::Callback<void(Tile* tile,
- const gfx::Rect& geometry_rect)> callback) {
- VerifyTiles(tiling_.get(),
- rect_scale,
- rect,
- callback);
+ void VerifyTiles(float rect_scale,
+ const gfx::Rect& rect,
+ VerifyTilesCallback callback) {
+ VerifyTiles(tiling_.get(), rect_scale, rect, callback);
}
- void VerifyTiles(
- PictureLayerTiling* tiling,
- float rect_scale,
- const gfx::Rect& rect,
- base::Callback<void(Tile* tile,
- const gfx::Rect& geometry_rect)> callback) {
+ void VerifyTiles(PictureLayerTiling* tiling,
+ float rect_scale,
+ const gfx::Rect& rect,
+ VerifyTilesCallback callback) {
Region remaining = rect;
for (PictureLayerTiling::CoverageIterator iter(tiling, rect_scale, rect);
- iter;
- ++iter) {
+ iter; ++iter) {
remaining.Subtract(iter.geometry_rect());
callback.Run(*iter, iter.geometry_rect());
}
@@ -676,7 +671,8 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, false));
tiling_->ComputeTilePriorityRects(
gfx::Rect(layer_bounds), // visible rect
@@ -685,19 +681,22 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
gfx::Rect(layer_bounds), // eventually rect
1.f, // current contents scale
Occlusion());
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, true));
// Make the viewport rect empty. All tiles are killed and become zombies.
tiling_->ComputeTilePriorityRects(gfx::Rect(), gfx::Rect(), gfx::Rect(),
gfx::Rect(), 1.f, Occlusion());
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, false));
}
TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, false));
gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
@@ -708,19 +707,22 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
gfx::Rect(layer_bounds), // eventually rect
1.f, // current contents scale
Occlusion());
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, true));
// If the visible content rect is huge, we should still have live tiles.
tiling_->ComputeTilePriorityRects(giant_rect, giant_rect, giant_rect,
giant_rect, 1.f, Occlusion());
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, true));
}
TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, false));
// This rect does not intersect with the layer, as the layer is outside the
// viewport.
@@ -733,7 +735,8 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
-settings.tiling_interest_area_padding);
tiling_->ComputeTilePriorityRects(viewport_rect, viewport_rect, viewport_rect,
eventually_rect, 1.f, Occlusion());
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, true));
}
static void TilesIntersectingRectExist(const gfx::Rect& rect,
@@ -760,7 +763,8 @@ TEST_F(PictureLayerTilingIteratorTest,
PENDING_TREE, gfx::AxisTransform2d(), raster_source, &client_, settings);
tiling_->set_resolution(HIGH_RESOLUTION);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ VerifyTiles(1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TileExists, false));
gfx::Rect visible_rect(8000, 8000, 50, 50);
@@ -770,9 +774,9 @@ TEST_F(PictureLayerTilingIteratorTest,
visible_rect, // eventually rect
1.f, // current contents scale
Occlusion());
- VerifyTiles(1.f,
- gfx::Rect(layer_bounds),
- base::Bind(&TilesIntersectingRectExist, visible_rect, true));
+ VerifyTiles(
+ 1.f, gfx::Rect(layer_bounds),
+ base::BindRepeating(&TilesIntersectingRectExist, visible_rect, true));
}
TEST(ComputeTilePriorityRectsTest, VisibleTiles) {
@@ -1116,7 +1120,7 @@ TEST_F(PictureLayerTilingIteratorTest, UseLeastTilesToCover) {
ASSERT_TRUE(tiling_->tiling_data()->TexelExtent(1, 1).Contains(overlaped));
VerifyTilesExactlyCoverRect(2.f, gfx::Rect(199, 199));
VerifyTiles(2.f, gfx::Rect(199, 199),
- base::Bind(&TileHasGeometryRect, gfx::Rect(199, 199)));
+ base::BindRepeating(&TileHasGeometryRect, gfx::Rect(199, 199)));
}
TEST_F(PictureLayerTilingIteratorTest, UseLeastTilesToCover2) {
@@ -1130,7 +1134,8 @@ TEST_F(PictureLayerTilingIteratorTest, UseLeastTilesToCover2) {
ASSERT_TRUE(tiling_->tiling_data()->TexelExtent(1, 2).Contains(overlaped));
gfx::Rect dest_rect(197, 393, 198, 198);
VerifyTilesExactlyCoverRect(2.f, dest_rect);
- VerifyTiles(2.f, dest_rect, base::Bind(&TileHasGeometryRect, dest_rect));
+ VerifyTiles(2.f, dest_rect,
+ base::BindRepeating(&TileHasGeometryRect, dest_rect));
}
TEST_F(PictureLayerTilingIteratorTest, TightCover) {
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index 48e78c00e11..6970e507093 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -24,6 +24,7 @@
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/layers/picture_layer_impl.h"
+#include "cc/raster/paint_worklet_image_provider.h"
#include "cc/raster/playback_image_provider.h"
#include "cc/raster/raster_buffer.h"
#include "cc/raster/task_category.h"
@@ -85,6 +86,7 @@ class RasterTaskImpl : public TileTask {
TileTask::Vector* dependencies,
bool is_gpu_rasterization,
PlaybackImageProvider image_provider,
+ PaintWorkletImageProvider paint_worklet_image_provider,
GURL url)
: TileTask(!is_gpu_rasterization, dependencies),
tile_manager_(tile_manager),
@@ -104,9 +106,12 @@ class RasterTaskImpl : public TileTask {
is_gpu_rasterization_(is_gpu_rasterization),
raster_buffer_(std::move(raster_buffer)),
image_provider_(std::move(image_provider)),
+ paint_worklet_image_provider_(std::move(paint_worklet_image_provider)),
url_(std::move(url)) {
DCHECK(origin_thread_checker_.CalledOnValidThread());
playback_settings_.image_provider = &image_provider_;
+ playback_settings_.paint_worklet_image_provider =
+ &paint_worklet_image_provider_;
}
// Overridden from Task:
@@ -173,6 +178,7 @@ class RasterTaskImpl : public TileTask {
bool is_gpu_rasterization_;
std::unique_ptr<RasterBuffer> raster_buffer_;
PlaybackImageProvider image_provider_;
+ PaintWorkletImageProvider paint_worklet_image_provider_;
GURL url_;
DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl);
@@ -298,10 +304,11 @@ class TaskSetFinishedTaskImpl : public TileTask {
public:
explicit TaskSetFinishedTaskImpl(
base::SequencedTaskRunner* task_runner,
- const base::Closure& on_task_set_finished_callback)
+ base::RepeatingClosure on_task_set_finished_callback)
: TileTask(true),
task_runner_(task_runner),
- on_task_set_finished_callback_(on_task_set_finished_callback) {}
+ on_task_set_finished_callback_(
+ std::move(on_task_set_finished_callback)) {}
// Overridden from Task:
void RunOnWorkerThread() override {
@@ -321,7 +328,7 @@ class TaskSetFinishedTaskImpl : public TileTask {
private:
base::SequencedTaskRunner* task_runner_;
- const base::Closure on_task_set_finished_callback_;
+ const base::RepeatingClosure on_task_set_finished_callback_;
DISALLOW_COPY_AND_ASSIGN(TaskSetFinishedTaskImpl);
};
@@ -397,11 +404,12 @@ TileManager::TileManager(
tile_manager_settings_.min_image_bytes_to_checker),
more_tiles_need_prepare_check_notifier_(
task_runner_,
- base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared,
- base::Unretained(this))),
- signals_check_notifier_(task_runner_,
- base::Bind(&TileManager::FlushAndIssueSignals,
- base::Unretained(this))),
+ base::BindRepeating(&TileManager::CheckIfMoreTilesNeedToBePrepared,
+ base::Unretained(this))),
+ signals_check_notifier_(
+ task_runner_,
+ base::BindRepeating(&TileManager::FlushAndIssueSignals,
+ base::Unretained(this))),
has_scheduled_tile_tasks_(false),
prepare_tiles_count_(0u),
next_tile_id_(0u),
@@ -997,6 +1005,7 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
DCHECK(tile->HasRasterTask());
TileTask* task = tile->raster_task_.get();
+ task->set_frame_number(tile->source_frame_number());
DCHECK(!task->HasCompleted());
@@ -1177,8 +1186,10 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
prepare_tiles_count_, prioritized_tile.priority().priority_bin,
ImageDecodeCache::TaskType::kInRaster);
bool has_at_raster_images = false;
- image_controller_.GetTasksForImagesAndRef(
+ image_controller_.ConvertDataImagesToTasks(
&sync_decoded_images, &decode_tasks, &has_at_raster_images, tracing_info);
+ image_controller_.ConvertPaintWorkletImagesToTask(&sync_decoded_images,
+ &decode_tasks);
// Notify |decoded_image_tracker_| after |image_controller_| to ensure we've
// taken new refs on the images before releasing the predecode API refs.
decoded_image_tracker_.OnImagesUsedInDraw(sync_decoded_images);
@@ -1233,12 +1244,16 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
std::move(settings));
playback_settings.raster_color_space = raster_color_space;
+
+ PaintWorkletImageProvider paint_worklet_image_provider(
+ image_controller_.paint_worklet_image_cache());
+
return base::MakeRefCounted<RasterTaskImpl>(
this, tile, std::move(resource), prioritized_tile.raster_source(),
playback_settings, prioritized_tile.priority().resolution,
invalidated_rect, prepare_tiles_count_, std::move(raster_buffer),
&decode_tasks, use_gpu_rasterization_, std::move(image_provider),
- active_url_);
+ std::move(paint_worklet_image_provider), active_url_);
}
void TileManager::ResetSignalsForTesting() {
@@ -1384,7 +1399,7 @@ void TileManager::ScheduleCheckRasterFinishedQueries() {
if (!check_pending_tile_queries_callback_.IsCancelled())
return;
- check_pending_tile_queries_callback_.Reset(base::Bind(
+ check_pending_tile_queries_callback_.Reset(base::BindOnce(
&TileManager::CheckRasterFinishedQueries, base::Unretained(this)));
task_runner_->PostDelayedTask(FROM_HERE,
check_pending_tile_queries_callback_.callback(),
@@ -1647,8 +1662,9 @@ void TileManager::CheckPendingGpuWorkAndIssueSignals() {
pending_required_for_activation_callback_id_ =
raster_buffer_provider_->SetReadyToDrawCallback(
required_for_activation,
- base::Bind(&TileManager::CheckPendingGpuWorkAndIssueSignals,
- ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(
+ &TileManager::CheckPendingGpuWorkAndIssueSignals,
+ ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
pending_required_for_activation_callback_id_);
}
@@ -1658,8 +1674,9 @@ void TileManager::CheckPendingGpuWorkAndIssueSignals() {
pending_required_for_draw_callback_id_ =
raster_buffer_provider_->SetReadyToDrawCallback(
required_for_draw,
- base::Bind(&TileManager::CheckPendingGpuWorkAndIssueSignals,
- ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(
+ &TileManager::CheckPendingGpuWorkAndIssueSignals,
+ ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
pending_required_for_draw_callback_id_);
}
@@ -1681,7 +1698,8 @@ scoped_refptr<TileTask> TileManager::CreateTaskSetFinishedTask(
void (TileManager::*callback)()) {
return base::MakeRefCounted<TaskSetFinishedTaskImpl>(
task_runner_,
- base::Bind(callback, task_set_finished_weak_ptr_factory_.GetWeakPtr()));
+ base::BindRepeating(callback,
+ task_set_finished_weak_ptr_factory_.GetWeakPtr()));
}
std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
@@ -1691,6 +1709,11 @@ TileManager::ActivationStateAsValue() {
return std::move(state);
}
+void TileManager::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ image_controller_.SetPaintWorkletLayerPainter(std::move(painter));
+}
+
void TileManager::ActivationStateAsValueInto(
base::trace_event::TracedValue* state) {
state->SetString("tree_priority",
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index ac58ccfdc99..244eea4c6f2 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -292,6 +292,9 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void set_active_url(const GURL& url) { active_url_ = url; }
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
+
protected:
friend class Tile;
// Must be called by tile during destruction.
@@ -459,7 +462,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
// The callback scheduled to poll whether the GPU side work for pending tiles
// has completed.
bool has_pending_queries_ = false;
- base::CancelableClosure check_pending_tile_queries_callback_;
+ base::CancelableOnceClosure check_pending_tile_queries_callback_;
// We need two WeakPtrFactory objects as the invalidation pattern of each is
// different. The |task_set_finished_weak_ptr_factory_| is invalidated any
diff --git a/chromium/cc/tiles/tile_manager_perftest.cc b/chromium/cc/tiles/tile_manager_perftest.cc
index 8842bc326a6..8a875845f9b 100644
--- a/chromium/cc/tiles/tile_manager_perftest.cc
+++ b/chromium/cc/tiles/tile_manager_perftest.cc
@@ -7,6 +7,7 @@
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "cc/base/lap_timer.h"
@@ -80,7 +81,7 @@ class TileManagerPerfTest : public TestLayerTreeHostBase {
std::unique_ptr<RasterTilePriorityQueue> queue(
host_impl()->BuildRasterQueue(priorities[priority_count],
RasterTilePriorityQueue::Type::ALL));
- priority_count = (priority_count + 1) % arraysize(priorities);
+ priority_count = (priority_count + 1) % base::size(priorities);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -115,7 +116,7 @@ class TileManagerPerfTest : public TestLayerTreeHostBase {
ASSERT_TRUE(queue->Top().tile());
queue->Pop();
}
- priority_count = (priority_count + 1) % arraysize(priorities);
+ priority_count = (priority_count + 1) % base::size(priorities);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -148,7 +149,7 @@ class TileManagerPerfTest : public TestLayerTreeHostBase {
do {
std::unique_ptr<EvictionTilePriorityQueue> queue(
host_impl()->BuildEvictionQueue(priorities[priority_count]));
- priority_count = (priority_count + 1) % arraysize(priorities);
+ priority_count = (priority_count + 1) % base::size(priorities);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -188,7 +189,7 @@ class TileManagerPerfTest : public TestLayerTreeHostBase {
ASSERT_TRUE(queue->Top().tile());
queue->Pop();
}
- priority_count = (priority_count + 1) % arraysize(priorities);
+ priority_count = (priority_count + 1) % base::size(priorities);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 7fbe4f370dd..d1d8105d1ae 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -1746,7 +1746,7 @@ TEST_F(PixelInspectTileManagerTest, LowResHasNoImage) {
gfx::Size size(10, 12);
TileResolution resolutions[] = {HIGH_RESOLUTION, LOW_RESOLUTION};
- for (size_t i = 0; i < arraysize(resolutions); ++i) {
+ for (size_t i = 0; i < base::size(resolutions); ++i) {
SCOPED_TRACE(resolutions[i]);
// Make a RasterSource that will draw a blue bitmap image.
@@ -2265,7 +2265,7 @@ class MockReadyToDrawRasterBufferProviderImpl
SetReadyToDrawCallback,
uint64_t(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
- const base::RepeatingClosure& callback,
+ base::OnceClosure callback,
uint64_t pending_callback_id));
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
@@ -2369,7 +2369,7 @@ TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
SetupTreesWithPendingTreeTiles();
- base::RepeatingClosure callback;
+ base::OnceClosure callback;
{
base::RunLoop run_loop;
@@ -2380,16 +2380,15 @@ TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
.WillRepeatedly(Return(false));
EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
- .WillOnce(testing::Invoke(
- [&run_loop, &callback](
- const std::vector<const ResourcePool::InUsePoolResource*>&
- resources,
- const base::RepeatingClosure& callback_in,
- uint64_t pending_callback_id) {
- callback = callback_in;
- run_loop.Quit();
- return 1;
- }));
+ .WillOnce([&run_loop, &callback](
+ const std::vector<const ResourcePool::InUsePoolResource*>&
+ resources,
+ base::OnceClosure callback_in,
+ uint64_t pending_callback_id) {
+ callback = std::move(callback_in);
+ run_loop.Quit();
+ return 1;
+ });
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
run_loop.Run();
}
@@ -2404,7 +2403,7 @@ TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
EXPECT_CALL(*mock_raster_buffer_provider(),
IsResourceReadyToDraw(testing::_))
.WillRepeatedly(Return(true));
- callback.Run();
+ std::move(callback).Run();
run_loop.Run();
}
@@ -2432,7 +2431,7 @@ TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
SetupTreesWithActiveTreeTiles();
- base::RepeatingClosure callback;
+ base::OnceClosure callback;
{
base::RunLoop run_loop;
@@ -2443,16 +2442,15 @@ TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
.WillRepeatedly(Return(false));
EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
- .WillOnce(Invoke(
- [&run_loop, &callback](
- const std::vector<const ResourcePool::InUsePoolResource*>&
- resources,
- const base::RepeatingClosure& callback_in,
- uint64_t pending_callback_id) {
- callback = callback_in;
- run_loop.Quit();
- return 1;
- }));
+ .WillOnce([&run_loop, &callback](
+ const std::vector<const ResourcePool::InUsePoolResource*>&
+ resources,
+ base::OnceClosure callback_in,
+ uint64_t pending_callback_id) {
+ callback = std::move(callback_in);
+ run_loop.Quit();
+ return 1;
+ });
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
run_loop.Run();
}
@@ -2467,7 +2465,7 @@ TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
EXPECT_CALL(*mock_raster_buffer_provider(),
IsResourceReadyToDraw(testing::_))
.WillRepeatedly(Return(true));
- callback.Run();
+ std::move(callback).Run();
run_loop.Run();
}
@@ -2633,21 +2631,20 @@ TEST_F(TileManagerReadyToDrawTest, ReadyToDrawRespectsRequirementChange) {
EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(testing::_))
.WillRepeatedly(Return(false));
- base::RepeatingClosure callback;
+ base::OnceClosure callback;
{
base::RunLoop run_loop;
EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
- .WillOnce(testing::Invoke(
- [&run_loop, &callback](
- const std::vector<const ResourcePool::InUsePoolResource*>&
- resources,
- const base::RepeatingClosure& callback_in,
- uint64_t pending_callback_id) {
- callback = callback_in;
- run_loop.Quit();
- return 1;
- }));
+ .WillOnce([&run_loop, &callback](
+ const std::vector<const ResourcePool::InUsePoolResource*>&
+ resources,
+ base::OnceClosure callback_in,
+ uint64_t pending_callback_id) {
+ callback = std::move(callback_in);
+ run_loop.Quit();
+ return 1;
+ });
host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
run_loop.Run();
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index 03d1e971600..a96cc8c979a 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -73,7 +73,6 @@ class DamageTrackerTest : public testing::Test {
std::unique_ptr<LayerImpl> root =
LayerImpl::Create(host_impl_.active_tree(), 1);
- root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
@@ -81,7 +80,7 @@ class DamageTrackerTest : public testing::Test {
for (int i = 0; i < number_of_children; ++i) {
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl_.active_tree(), 2 + i);
- child->SetPosition(gfx::PointF(100.f, 100.f));
+ child->test_properties()->position = gfx::PointF(100.f, 100.f);
child->SetBounds(gfx::Size(30, 30));
child->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(child));
@@ -109,12 +108,11 @@ class DamageTrackerTest : public testing::Test {
std::unique_ptr<LayerImpl> grand_child2 =
LayerImpl::Create(host_impl_.active_tree(), 5);
- root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
- child1->SetPosition(gfx::PointF(100.f, 100.f));
+ child1->test_properties()->position = gfx::PointF(100.f, 100.f);
child1->SetBounds(gfx::Size(30, 30));
// With a child that draws_content, opacity will cause the layer to create
// its own RenderSurface. This layer does not draw, but is intended to
@@ -122,15 +120,15 @@ class DamageTrackerTest : public testing::Test {
child1->SetDrawsContent(false);
child1->test_properties()->force_render_surface = true;
- child2->SetPosition(gfx::PointF(11.f, 11.f));
+ child2->test_properties()->position = gfx::PointF(11.f, 11.f);
child2->SetBounds(gfx::Size(18, 18));
child2->SetDrawsContent(true);
- grand_child1->SetPosition(gfx::PointF(200.f, 200.f));
+ grand_child1->test_properties()->position = gfx::PointF(200.f, 200.f);
grand_child1->SetBounds(gfx::Size(6, 8));
grand_child1->SetDrawsContent(true);
- grand_child2->SetPosition(gfx::PointF(190.f, 190.f));
+ grand_child2->test_properties()->position = gfx::PointF(190.f, 190.f);
grand_child2->SetBounds(gfx::Size(6, 8));
grand_child2->SetDrawsContent(true);
@@ -582,7 +580,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) {
ClearDamageForAllSurfaces(root);
child->test_properties()->transform_origin = gfx::Point3F(
child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f);
- child->SetPosition(gfx::PointF(85.f, 85.f));
+ child->test_properties()->position = gfx::PointF(85.f, 85.f);
child->NoteLayerPropertyChanged();
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
@@ -653,7 +651,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
transform.Translate3d(-50.0, -50.0, 0.0);
// Set up the child
- child->SetPosition(gfx::PointF(0.f, 0.f));
+ child->test_properties()->position = gfx::PointF(0.f, 0.f);
child->SetBounds(gfx::Size(100, 100));
child->test_properties()->transform = transform;
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -661,7 +659,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
// Sanity check that the child layer's bounds would actually get clipped by
// w < 0, otherwise this test is not actually testing the intended scenario.
- gfx::RectF test_rect(child->position(), gfx::SizeF(child->bounds()));
+ gfx::RectF test_rect(child->test_properties()->position,
+ gfx::SizeF(child->bounds()));
bool clipped = false;
MathUtil::MapQuad(transform, gfx::QuadF(test_rect), &clipped);
EXPECT_TRUE(clipped);
@@ -1057,7 +1056,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// to get expanded. We position child1 so that an expansion of the empty rect
// would have non-empty intersection with child1 in its target space (root
// space).
- child1->SetPosition(gfx::PointF());
+ child1->test_properties()->position = gfx::PointF();
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
@@ -1082,7 +1081,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) {
{
std::unique_ptr<LayerImpl> child2 =
LayerImpl::Create(host_impl_.active_tree(), 3);
- child2->SetPosition(gfx::PointF(400.f, 380.f));
+ child2->test_properties()->position = gfx::PointF(400.f, 380.f);
child2->SetBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(child2));
@@ -1140,7 +1139,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) {
{
std::unique_ptr<LayerImpl> child2 =
LayerImpl::Create(host_impl_.active_tree(), 3);
- child2->SetPosition(gfx::PointF(400.f, 380.f));
+ child2->test_properties()->position = gfx::PointF(400.f, 380.f);
child2->SetBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(child2));
@@ -1179,7 +1178,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
{
std::unique_ptr<LayerImpl> child2 =
LayerImpl::Create(host_impl_.active_tree(), 3);
- child2->SetPosition(gfx::PointF(400.f, 380.f));
+ child2->test_properties()->position = gfx::PointF(400.f, 380.f);
child2->SetBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(child2));
@@ -1290,7 +1289,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) {
gfx::Rect root_damage_rect;
ClearDamageForAllSurfaces(root);
- grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
+ grand_child1->test_properties()->position = gfx::PointF(195.f, 205.f);
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid(
@@ -1501,7 +1500,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) {
{
std::unique_ptr<LayerImpl> mask_layer =
LayerImpl::Create(host_impl_.active_tree(), 3);
- mask_layer->SetPosition(child->position());
+ mask_layer->test_properties()->position =
+ child->test_properties()->position;
mask_layer->SetBounds(child->bounds());
child->test_properties()->SetMaskLayer(std::move(mask_layer));
child->test_properties()->force_render_surface = true;
@@ -1513,7 +1513,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) {
{
std::unique_ptr<LayerImpl> grand_child =
LayerImpl::Create(host_impl_.active_tree(), 4);
- grand_child->SetPosition(gfx::PointF(2.f, 2.f));
+ grand_child->test_properties()->position = gfx::PointF(2.f, 2.f);
grand_child->SetBounds(gfx::Size(2, 2));
grand_child->SetDrawsContent(true);
child->test_properties()->AddChild(std::move(grand_child));
@@ -1730,7 +1730,6 @@ TEST_F(DamageTrackerTest, HugeDamageRect) {
// The child layer covers (0, 0, i, i) of the viewport,
// but has a huge negative position.
- child->SetPosition(gfx::PointF());
child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
child->test_properties()->transform = transform;
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -1760,11 +1759,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) {
LayerImpl* child2 = root->test_properties()->children[1];
// Really far left.
- child1->SetPosition(gfx::PointF(std::numeric_limits<int>::min() + 100, 0));
+ child1->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::min() + 100, 0);
child1->SetBounds(gfx::Size(1, 1));
// Really far right.
- child2->SetPosition(gfx::PointF(std::numeric_limits<int>::max() - 100, 0));
+ child2->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::max() - 100, 0);
child2->SetBounds(gfx::Size(1, 1));
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -1794,11 +1795,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) {
root->test_properties()->backdrop_filters = filters;
// Really far left.
- child1->SetPosition(gfx::PointF(std::numeric_limits<int>::min() + 100, 0));
+ child1->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::min() + 100, 0);
child1->SetBounds(gfx::Size(1, 1));
// Really far right.
- child2->SetPosition(gfx::PointF(std::numeric_limits<int>::max() - 100, 0));
+ child2->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::max() - 100, 0);
child2->SetBounds(gfx::Size(1, 1));
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -1824,14 +1827,14 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) {
LayerImpl* grandchild2 = child1->test_properties()->children[1];
// Really far left.
- grandchild1->SetPosition(
- gfx::PointF(std::numeric_limits<int>::min() + 500, 0));
+ grandchild1->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::min() + 500, 0);
grandchild1->SetBounds(gfx::Size(1, 1));
grandchild1->SetDrawsContent(true);
// Really far right.
- grandchild2->SetPosition(
- gfx::PointF(std::numeric_limits<int>::max() - 500, 0));
+ grandchild2->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::max() - 500, 0);
grandchild2->SetBounds(gfx::Size(1, 1));
grandchild2->SetDrawsContent(true);
@@ -1920,14 +1923,14 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) {
child1->test_properties()->backdrop_filters = filters;
// Really far left.
- grandchild1->SetPosition(
- gfx::PointF(std::numeric_limits<int>::min() + 500, 0));
+ grandchild1->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::min() + 500, 0);
grandchild1->SetBounds(gfx::Size(1, 1));
grandchild1->SetDrawsContent(true);
// Really far right.
- grandchild2->SetPosition(
- gfx::PointF(std::numeric_limits<int>::max() - 500, 0));
+ grandchild2->test_properties()->position =
+ gfx::PointF(std::numeric_limits<int>::max() - 500, 0);
grandchild2->SetBounds(gfx::Size(1, 1));
grandchild2->SetDrawsContent(true);
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index b0138a10a4a..93ebe0be89c 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -51,6 +51,7 @@ bool EffectNode::operator==(const EffectNode& other) const {
has_copy_request == other.has_copy_request &&
filters == other.filters &&
backdrop_filters == other.backdrop_filters &&
+ backdrop_filter_bounds == other.backdrop_filter_bounds &&
filters_origin == other.filters_origin &&
blend_mode == other.blend_mode &&
surface_contents_scale == other.surface_contents_scale &&
diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h
index 0f8bf3399a6..276b808584d 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -9,6 +9,7 @@
#include "cc/paint/filter_operations.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size_f.h"
namespace base {
@@ -40,6 +41,7 @@ struct CC_EXPORT EffectNode {
FilterOperations filters;
FilterOperations backdrop_filters;
+ gfx::RectF backdrop_filter_bounds;
float backdrop_filter_quality;
gfx::PointF filters_origin;
diff --git a/chromium/cc/trees/element_id.cc b/chromium/cc/trees/element_id.cc
index 95c79a7b19c..b460a2e8675 100644
--- a/chromium/cc/trees/element_id.cc
+++ b/chromium/cc/trees/element_id.cc
@@ -14,22 +14,6 @@
namespace cc {
-bool ElementId::operator==(const ElementId& o) const {
- return id_ == o.id_;
-}
-
-bool ElementId::operator!=(const ElementId& o) const {
- return !(*this == o);
-}
-
-bool ElementId::operator<(const ElementId& o) const {
- return id_ < o.id_;
-}
-
-ElementId::operator bool() const {
- return !!id_;
-}
-
ElementId LayerIdToElementIdForTesting(int layer_id) {
return ElementId(std::numeric_limits<int>::max() - layer_id);
}
diff --git a/chromium/cc/trees/element_id.h b/chromium/cc/trees/element_id.h
index ad88cc6a997..482ed3e152b 100644
--- a/chromium/cc/trees/element_id.h
+++ b/chromium/cc/trees/element_id.h
@@ -50,12 +50,12 @@ struct CC_EXPORT ElementId {
explicit ElementId(ElementIdType id) : id_(id) {}
ElementId() : ElementId(kInvalidElementId) {}
- bool operator==(const ElementId& o) const;
- bool operator!=(const ElementId& o) const;
- bool operator<(const ElementId& o) const;
+ bool operator==(const ElementId& o) const { return id_ == o.id_; }
+ bool operator!=(const ElementId& o) const { return !(*this == o); }
+ bool operator<(const ElementId& o) const { return id_ < o.id_; }
// An ElementId's conversion to a boolean value depends only on its primaryId.
- explicit operator bool() const;
+ explicit operator bool() const { return !!id_; }
void AddToTracedValue(base::trace_event::TracedValue* res) const;
std::unique_ptr<base::Value> AsValue() const;
diff --git a/chromium/cc/trees/image_animation_controller.cc b/chromium/cc/trees/image_animation_controller.cc
index a781c08f8cd..62900fb0a7c 100644
--- a/chromium/cc/trees/image_animation_controller.cc
+++ b/chromium/cc/trees/image_animation_controller.cc
@@ -426,7 +426,7 @@ void ImageAnimationController::DelayedNotifier::Schedule(
pending_notification_time_.emplace(notification_time);
task_runner_->PostDelayedTask(
FROM_HERE,
- base::Bind(&DelayedNotifier::Notify, weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DelayedNotifier::Notify, weak_factory_.GetWeakPtr()),
notification_time - now);
}
diff --git a/chromium/cc/trees/image_animation_controller_unittest.cc b/chromium/cc/trees/image_animation_controller_unittest.cc
index ea59f849c4c..f8abed7741c 100644
--- a/chromium/cc/trees/image_animation_controller_unittest.cc
+++ b/chromium/cc/trees/image_animation_controller_unittest.cc
@@ -74,11 +74,11 @@ class ImageAnimationControllerTest : public testing::Test {
void SetUp() override {
task_runner_ =
new DelayTrackingTaskRunner(base::ThreadTaskRunnerHandle::Get().get());
- base::Closure invalidation_callback =
- base::Bind(&ImageAnimationControllerTest::RequestInvalidation,
- base::Unretained(this));
+ auto invalidation_callback =
+ base::BindRepeating(&ImageAnimationControllerTest::RequestInvalidation,
+ base::Unretained(this));
controller_ = std::make_unique<ImageAnimationController>(
- task_runner_.get(), invalidation_callback,
+ task_runner_.get(), std::move(invalidation_callback),
GetEnableImageAnimationResync());
now_ += base::TimeDelta::FromSeconds(10);
}
diff --git a/chromium/cc/trees/layer_tree_frame_sink.cc b/chromium/cc/trees/layer_tree_frame_sink.cc
index e1a1b803b72..024981ce300 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink.cc
@@ -66,6 +66,11 @@ bool LayerTreeFrameSink::BindToClient(LayerTreeFrameSinkClient* client) {
DCHECK(!client_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Note: If |context_provider_| was always bound to a thread before here then
+ // the return value could be replaced with a PostTask to OnContextLost(). This
+ // would simplify the calling code so it didn't have to handle failures in
+ // BindToClient().
+
if (context_provider_) {
context_provider_->AddObserver(this);
auto result = context_provider_->BindToCurrentThread();
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index 15b3568a8cf..7ae114e3fe7 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -81,6 +81,10 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
bool HasClient() { return !!client_; }
+ void set_source_frame_number(int64_t frame_number) {
+ source_frame_number_ = frame_number;
+ }
+
// The viz::ContextProviders may be null if frames should be submitted with
// software SharedMemory resources.
viz::ContextProvider* context_provider() const {
@@ -105,10 +109,15 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
// For successful swaps, the implementation must call
// DidReceiveCompositorFrameAck() asynchronously when the frame has been
- // processed in order to unthrottle the next frame. |show_hit_test_borders|
- // controls whether viz will insert debug borders over hit-test data and is
- // passed from LayerTreeDebugState.
+ // processed in order to unthrottle the next frame.
+ // If |hit_test_data_changed| is false, we do an equality check
+ // with the old hit-test data. If there is no change, we do not send the
+ // hit-test data. False positives are allowed. The value of
+ // |hit_test_data_changed| should remain constant in the caller.
+ // |show_hit_test_borders| controls whether viz will insert debug borders over
+ // hit-test data and is passed from LayerTreeDebugState.
virtual void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool hit_test_data_changed,
bool show_hit_test_borders) = 0;
// Signals that a BeginFrame issued by the viz::BeginFrameSource provided to
@@ -139,6 +148,8 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
std::unique_ptr<ContextLostForwarder> worker_context_lost_forwarder_;
+ int64_t source_frame_number_;
+
private:
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<LayerTreeFrameSink> weak_ptr_factory_;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index b89a6e738c4..8037825c25e 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -48,8 +48,8 @@ class CC_EXPORT LayerTreeFrameSinkClient {
// If set, |callback| will be called subsequent to each new tree activation,
// regardless of the compositor visibility or damage. |callback| must remain
// valid for the lifetime of the LayerTreeFrameSinkClient or until
- // unregistered by giving a null base::Closure.
- virtual void SetTreeActivationCallback(const base::Closure& callback) = 0;
+ // unregistered by giving a null callback.
+ virtual void SetTreeActivationCallback(base::RepeatingClosure callback) = 0;
// Notification that the previous CompositorFrame given to
// SubmitCompositorFrame() has been processed and that another frame
diff --git a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
index cd40a54d467..58334b8322f 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
@@ -29,6 +29,7 @@ class StubLayerTreeFrameSink : public LayerTreeFrameSink {
nullptr) {}
void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool hit_test_data_changed,
bool show_hit_test_borders) override {
client_->DidReceiveCompositorFrameAck();
}
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 01ec4196d06..7e0328a5f0a 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -16,7 +16,6 @@
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/command_line.h"
-#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@@ -41,6 +40,7 @@
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/painted_scrollbar_layer.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/trees/clip_node.h"
@@ -305,14 +305,11 @@ void LayerTreeHost::FinishCommitOnImplThread(
}
sync_tree->set_source_frame_number(SourceFrameNumber());
- bool request_presentation_time =
- settings_.always_request_presentation_time ||
- !pending_presentation_time_callbacks_.empty();
- if (request_presentation_time && pending_presentation_time_callbacks_.empty())
- pending_presentation_time_callbacks_.push_back(base::DoNothing());
- sync_tree->AddPresentationCallbacks(
- std::move(pending_presentation_time_callbacks_));
- pending_presentation_time_callbacks_.clear();
+ if (!pending_presentation_time_callbacks_.empty()) {
+ sync_tree->AddPresentationCallbacks(
+ std::move(pending_presentation_time_callbacks_));
+ pending_presentation_time_callbacks_.clear();
+ }
if (needs_full_tree_sync_)
TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree);
@@ -377,14 +374,11 @@ void LayerTreeHost::FinishCommitOnImplThread(
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host=3
if (VLOG_IS_ON(3)) {
- std::string property_trees;
- base::JSONWriter::WriteWithOptions(
- *sync_tree->property_trees()->AsTracedValue()->ToBaseValue(),
- base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
VLOG(3) << "After finishing commit on impl, the sync tree:"
<< "\nproperty_trees:\n"
- << property_trees << "\nlayers:\n"
- << host_impl->LayerListAsJson();
+ << sync_tree->property_trees()->ToString() << "\n"
+ << "cc::LayerImpls:\n"
+ << sync_tree->LayerListAsJson();
}
}
@@ -445,7 +439,7 @@ void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() {
}
bool LayerTreeHost::IsUsingLayerLists() const {
- return settings_.use_layer_lists;
+ return settings_.use_layer_lists && !force_use_property_tree_builder_;
}
void LayerTreeHost::CommitComplete() {
@@ -564,7 +558,7 @@ void LayerTreeHost::SetNeedsCommit() {
swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit();
}
-bool LayerTreeHost::RequestedMainFramePending() {
+bool LayerTreeHost::RequestedMainFramePendingForTesting() {
return proxy_->RequestedAnimatePending();
}
@@ -668,10 +662,11 @@ bool LayerTreeHost::UpdateLayers() {
property_trees_.clear();
return false;
}
+
DCHECK(!root_layer()->parent());
base::ElapsedTimer timer;
- bool result = DoUpdateLayers(root_layer());
+ bool result = DoUpdateLayers();
micro_benchmark_controller_.DidUpdateLayers();
if (const char* client_name = GetClientNameForMetrics()) {
@@ -694,6 +689,11 @@ void LayerTreeHost::DidPresentCompositorFrame(
client_->DidPresentCompositorFrame(frame_token, feedback);
}
+void LayerTreeHost::DidGenerateLocalSurfaceIdAllocation(
+ const viz::LocalSurfaceIdAllocation& allocation) {
+ client_->DidGenerateLocalSurfaceIdAllocation(allocation);
+}
+
void LayerTreeHost::DidCompletePageScaleAnimation() {
did_complete_scale_animation_ = true;
}
@@ -737,7 +737,7 @@ void LayerTreeHost::RecordGpuRasterizationHistogram(
gpu_rasterization_histogram_recorded_ = true;
}
-bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
+bool LayerTreeHost::DoUpdateLayers() {
TRACE_EVENT1("cc,benchmark", "LayerTreeHost::DoUpdateLayers",
"source_frame_number", SourceFrameNumber());
@@ -747,17 +747,17 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
// and cc needs to compute property trees from that.
// In layer lists mode, blink sends cc property trees directly so they do not
// need to be built here. Layer lists mode is used by BlinkGenPropertyTrees
- // and SlimmingPaintV2.
+ // and CompositeAfterPaint.
if (!IsUsingLayerLists()) {
TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
Layer* root_scroll =
- PropertyTreeBuilder::FindFirstScrollableLayer(root_layer);
+ PropertyTreeBuilder::FindFirstScrollableLayer(root_layer_.get());
Layer* page_scale_layer = viewport_layers_.page_scale.get();
if (!page_scale_layer && root_scroll)
page_scale_layer = root_scroll->parent();
gfx::Transform identity_transform;
PropertyTreeBuilder::BuildPropertyTrees(
- root_layer, page_scale_layer, inner_viewport_scroll_layer(),
+ root_layer_.get(), page_scale_layer, inner_viewport_scroll_layer(),
outer_viewport_scroll_layer(), overscroll_elasticity_element_id(),
elastic_overscroll_, page_scale_factor_, device_scale_factor_,
gfx::Rect(device_viewport_size_), identity_transform, &property_trees_);
@@ -793,6 +793,11 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
DCHECK(property_trees_.clip_tree.Node(layer->clip_tree_index()));
DCHECK(property_trees_.scroll_tree.Node(layer->scroll_tree_index()));
}
+#else
+ // This is a quick sanity check for readiness of paint properties.
+ // TODO(crbug.com/913464): This is to help analysis of crashes of the bug.
+ // Remove this CHECK when we close the bug.
+ CHECK(property_trees_.effect_tree.Node(root_layer_->effect_tree_index()));
#endif
draw_property_utils::UpdatePropertyTrees(this, &property_trees_);
@@ -803,29 +808,17 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host=3
- // This only prints output for the renderer.
- if (VLOG_IS_ON(3) && GetClientNameForMetrics() == std::string("Renderer")) {
- std::string property_trees;
- base::JSONWriter::WriteWithOptions(
- *property_trees_.AsTracedValue()->ToBaseValue(),
- base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
+ // This only prints output in unit test or for the renderer.
+ if (VLOG_IS_ON(3) && (!GetClientNameForMetrics() ||
+ GetClientNameForMetrics() == std::string("Renderer"))) {
std::ostringstream layers;
- for (auto* layer : *this) {
- layers << "\n layer id " << layer->id();
- layers << "\n element_id: " << layer->element_id();
- layers << "\n bounds: " << layer->bounds().ToString();
- layers << "\n opacity: " << layer->opacity();
- layers << "\n position: " << layer->position().ToString();
- layers << "\n draws_content: " << layer->DrawsContent();
- layers << "\n scrollable: " << layer->scrollable();
- layers << "\n contents_opaque: " << layer->contents_opaque();
- layers << "\n transform_tree_index: " << layer->transform_tree_index();
- layers << "\n clip_tree_index: " << layer->clip_tree_index();
- layers << "\n effect_tree_index: " << layer->effect_tree_index();
- layers << "\n scroll_tree_index: " << layer->scroll_tree_index();
- }
- VLOG(3) << "After updating layers on the main thread:\nproperty trees:\n"
- << property_trees << "\nlayers:" << layers.str();
+ for (auto* layer : *this)
+ layers << layer->ToString() << "\n";
+ VLOG(3) << "After updating layers on the main thread:\n"
+ << "property trees:\n"
+ << property_trees_.ToString() << "\n"
+ << "cc::Layers:\n"
+ << layers.str();
}
bool painted_content_has_slow_paths = false;
@@ -899,6 +892,19 @@ void LayerTreeHost::RecordWheelAndTouchScrollingCount(
}
}
+void LayerTreeHost::SendOverscrollAndScrollEndEventsFromImplSide(
+ const ScrollAndScaleSet& info) {
+ if (info.scroll_latched_element_id == ElementId())
+ return;
+
+ if (!info.overscroll_delta.IsZero()) {
+ client_->SendOverscrollEventFromImplSide(info.overscroll_delta,
+ info.scroll_latched_element_id);
+ }
+ if (info.scroll_gesture_did_end)
+ client_->SendScrollEndEventFromImplSide(info.scroll_latched_element_id);
+}
+
void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
DCHECK(info);
for (auto& swap_promise : info->swap_promises) {
@@ -926,6 +932,8 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
}
}
+ SendOverscrollAndScrollEndEventsFromImplSide(*info);
+
// This needs to happen after scroll deltas have been sent to prevent top
// controls from clamping the layout viewport both on the compositor and
// on the main thread.
@@ -997,6 +1005,16 @@ void LayerTreeHost::SetLayerTreeMutator(
proxy_->SetMutator(std::move(mutator));
}
+void LayerTreeHost::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ // The paint worklet system assumes that the painter will never be called from
+ // the main thread, which will not be the case if we're running in
+ // single-threaded mode.
+ DCHECK(task_runner_provider_->HasImplThread())
+ << "PaintWorkletLayerPainter not supported in single-thread mode";
+ proxy_->SetPaintWorkletLayerPainter(std::move(painter));
+}
+
bool LayerTreeHost::IsSingleThreaded() const {
DCHECK(compositor_mode_ != CompositorMode::SINGLE_THREADED ||
!task_runner_provider_->HasImplThread());
@@ -1035,9 +1053,20 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
content_has_non_aa_paint_ = false;
gpu_rasterization_histogram_recorded_ = false;
+ force_use_property_tree_builder_ = false;
+
SetNeedsFullTreeSync();
}
+void LayerTreeHost::SetNonBlinkManagedRootLayer(
+ scoped_refptr<Layer> root_layer) {
+ SetRootLayer(std::move(root_layer));
+
+ DCHECK(root_layer_->children().empty());
+ if (IsUsingLayerLists() && root_layer_)
+ force_use_property_tree_builder_ = true;
+}
+
LayerTreeHost::ViewportLayers::ViewportLayers() = default;
LayerTreeHost::ViewportLayers::~ViewportLayers() = default;
@@ -1101,18 +1130,9 @@ void LayerTreeHost::SetEventListenerProperties(
// layer tree sets a wheel event handler region to be its entire bounds,
// otherwise it sets it to empty.
//
- // Thus when it changes, we might want to request every layer to push
- // properties and recompute its wheel event handler region, since the
- // computation is done in PushPropertiesTo. However neither
- // SetSubtreePropertyChanged() nor SetNeedsFullTreeSync() do this, so
- // it is unclear why we call them.
- // Also why we don't want to recompute the wheel event handler region for all
- // layers when the blocking state goes away is unclear. Also why we mark all
- // layers below the root layer as damaged is unclear.
- // TODO(bokan): Sort out what should be set and why. https://crbug.com/881011
- //
- // TODO(sunxd): Remove NeedsFullTreeSync when computing mouse wheel event
- // handler region is done.
+ // Thus when it changes, we want to request every layer to push properties
+ // and recompute its wheel event handler region, since the computation is
+ // done in PushPropertiesTo.
if (event_class == EventListenerClass::kMouseWheel) {
bool new_property_is_blocking =
properties == EventListenerProperties::kBlocking ||
@@ -1122,10 +1142,9 @@ void LayerTreeHost::SetEventListenerProperties(
old_properties == EventListenerProperties::kBlocking ||
old_properties == EventListenerProperties::kBlockingAndPassive;
- if (!old_property_is_blocking && new_property_is_blocking) {
- if (root_layer())
- root_layer()->SetSubtreePropertyChanged();
- SetNeedsFullTreeSync();
+ if (old_property_is_blocking != new_property_is_blocking) {
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ this, [](Layer* layer) { layer->SetNeedsPushProperties(); });
}
}
@@ -1138,37 +1157,51 @@ void LayerTreeHost::SetViewportSizeAndScale(
float device_scale_factor,
const viz::LocalSurfaceIdAllocation&
local_surface_id_allocation_from_parent) {
+ const viz::LocalSurfaceId previous_local_surface_id =
+ local_surface_id_allocation_from_parent_.local_surface_id();
SetLocalSurfaceIdAllocationFromParent(
local_surface_id_allocation_from_parent);
- bool changed = false;
+ bool device_viewport_size_changed = false;
if (device_viewport_size_ != device_viewport_size) {
device_viewport_size_ = device_viewport_size;
- changed = true;
+ device_viewport_size_changed = true;
}
+ bool painted_device_scale_factor_changed = false;
+ bool device_scale_factor_changed = false;
if (settings_.use_painted_device_scale_factor) {
DCHECK_EQ(device_scale_factor_, 1.f);
if (painted_device_scale_factor_ != device_scale_factor) {
painted_device_scale_factor_ = device_scale_factor;
- changed = true;
+ painted_device_scale_factor_changed = true;
}
} else {
DCHECK_EQ(painted_device_scale_factor_, 1.f);
if (device_scale_factor_ != device_scale_factor) {
device_scale_factor_ = device_scale_factor;
- changed = true;
+ device_scale_factor_changed = true;
}
}
- if (changed) {
+ if (device_viewport_size_changed || painted_device_scale_factor_changed ||
+ device_scale_factor_changed) {
SetPropertyTreesNeedRebuild();
SetNeedsCommit();
#if defined(OS_MACOSX)
- // TODO(ccameron): This check is not valid on Aura or Mus yet, but should
- // be.
+ // TODO(jonross): This check is not valid on Aura or Mus yet, but should be.
CHECK(!has_pushed_local_surface_id_from_parent_ ||
new_local_surface_id_request_ ||
- !local_surface_id_allocation_from_parent_.IsValid());
+ !local_surface_id_allocation_from_parent_.IsValid())
+ << "Invalid Surface Id State: !has_pushed "
+ << !has_pushed_local_surface_id_from_parent_ << " new_id_request "
+ << new_local_surface_id_request_ << " !valid_parent_id "
+ << !local_surface_id_allocation_from_parent_.IsValid()
+ << ". Changed state: device_viewport_size "
+ << device_viewport_size_changed << " painted_device_scale_factor "
+ << painted_device_scale_factor_changed << " device_scale_factor "
+ << device_scale_factor_changed << " cached LSId "
+ << previous_local_surface_id.ToString() << " new LSId "
+ << local_surface_id_allocation_from_parent.ToString();
#endif
}
}
@@ -1282,14 +1315,8 @@ void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent(
local_surface_id_allocation_from_parent) {
const viz::LocalSurfaceId& local_surface_id_from_parent =
local_surface_id_allocation_from_parent.local_surface_id();
- const viz::LocalSurfaceId& current_local_surface_id_from_parent =
+ const viz::LocalSurfaceId current_local_surface_id_from_parent =
local_surface_id_allocation_from_parent_.local_surface_id();
- if (current_local_surface_id_from_parent.parent_sequence_number() ==
- local_surface_id_from_parent.parent_sequence_number() &&
- current_local_surface_id_from_parent.embed_token() ==
- local_surface_id_from_parent.embed_token()) {
- return;
- }
// If the viz::LocalSurfaceId is valid but the allocation time is invalid then
// this API is not being used correctly.
@@ -1303,9 +1330,24 @@ void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
"SetLocalSurfaceAllocationIdFromParent", "local_surface_id_allocation",
local_surface_id_allocation_from_parent.ToString());
+ // Always update the cached state of the viz::LocalSurfaceId to reflect the
+ // latest value received from our parent.
local_surface_id_allocation_from_parent_ =
local_surface_id_allocation_from_parent;
has_pushed_local_surface_id_from_parent_ = false;
+
+ // 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
+ // parent agreed upon these without needing to further advance its sequence
+ // number. When this occurs the child is already up-to-date and a commit here
+ // is simply redundant.
+ if (current_local_surface_id_from_parent.parent_sequence_number() ==
+ local_surface_id_from_parent.parent_sequence_number() &&
+ current_local_surface_id_from_parent.embed_token() ==
+ local_surface_id_from_parent.embed_token()) {
+ return;
+ }
UpdateDeferMainFrameUpdateInternal();
SetNeedsCommit();
}
@@ -1568,16 +1610,24 @@ Layer* LayerTreeHost::LayerByElementId(ElementId element_id) const {
void LayerTreeHost::RegisterElement(ElementId element_id,
ElementListType list_type,
Layer* layer) {
+ // When using layer lists only scrollable layers should be registered.
+ DCHECK(!IsUsingLayerLists() || layer->inputs_.scrollable);
element_layers_map_[element_id] = layer;
- elements_in_property_trees_.insert(element_id);
- mutator_host_->RegisterElement(element_id, list_type);
+
+ // Animation ElementIds are unregistered by |SetActiveRegisteredElementIds|
+ // when using layer lists.
+ if (!IsUsingLayerLists())
+ mutator_host_->RegisterElement(element_id, list_type);
}
void LayerTreeHost::UnregisterElement(ElementId element_id,
ElementListType list_type) {
- mutator_host_->UnregisterElement(element_id, list_type);
+ // Animation ElementIds are unregistered by |SetActiveRegisteredElementIds|
+ // when using layer lists.
+ if (!IsUsingLayerLists())
+ mutator_host_->UnregisterElement(element_id, list_type);
+
element_layers_map_.erase(element_id);
- elements_in_property_trees_.erase(element_id);
}
void LayerTreeHost::SetActiveRegisteredElementIds(const ElementIdSet& ids) {
@@ -1587,8 +1637,10 @@ void LayerTreeHost::SetActiveRegisteredElementIds(const ElementIdSet& ids) {
for (auto id_iter = elements_in_property_trees_.begin();
id_iter != elements_in_property_trees_.end();) {
const auto& id = *(id_iter++);
- if (!ids.count(id))
- UnregisterElement(id, ElementListType::ACTIVE);
+ if (!ids.count(id)) {
+ mutator_host_->UnregisterElement(id, ElementListType::ACTIVE);
+ elements_in_property_trees_.erase(id);
+ }
}
// Register new ids that were not already registered.
@@ -1638,8 +1690,8 @@ void LayerTreeHost::SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) {
if (IsUsingLayerLists()) {
- // In SPv2 we always have property trees and can set the filter
- // directly on the effect node.
+ // In BlinkGenPropertyTrees/CompositeAfterPaint we always have property
+ // tree nodes and can set the filter directly on the effect node.
property_trees_.effect_tree.OnFilterAnimated(element_id, filters);
return;
}
@@ -1715,12 +1767,12 @@ void LayerTreeHost::SetElementScrollOffsetMutated(
}
void LayerTreeHost::ElementIsAnimatingChanged(
- ElementId element_id,
+ const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) {
DCHECK_EQ(ElementListType::ACTIVE, list_type);
- property_trees()->ElementIsAnimatingChanged(mutator_host(), element_id,
+ property_trees()->ElementIsAnimatingChanged(mutator_host(), element_id_map,
list_type, mask, state, true);
}
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index d35269410a8..d98608d246d 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -61,6 +61,7 @@ class LayerTreeHostImpl;
class LayerTreeHostImplClient;
class LayerTreeHostSingleThreadClient;
class LayerTreeMutator;
+class PaintWorkletLayerPainter;
class MutatorEvents;
class MutatorHost;
struct PendingPageScaleAnimation;
@@ -87,6 +88,12 @@ class CC_EXPORT ScopedDeferMainFrameUpdate {
class CC_EXPORT LayerTreeHost : public MutatorHostClient {
public:
struct CC_EXPORT InitParams {
+ InitParams();
+ ~InitParams();
+
+ InitParams(InitParams&&);
+ InitParams& operator=(InitParams&&);
+
LayerTreeHostClient* client = nullptr;
TaskGraphRunner* task_graph_runner = nullptr;
LayerTreeSettings const* settings = nullptr;
@@ -99,12 +106,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner;
std::unique_ptr<UkmRecorderFactory> ukm_recorder_factory;
-
- InitParams();
- ~InitParams();
-
- InitParams(InitParams&&);
- InitParams& operator=(InitParams&&);
};
// Constructs a LayerTreeHost with a compositor thread where scrolling and
@@ -151,6 +152,11 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// state on the compositor thread. (Compositor-Worker)
void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator);
+ // Sets the LayerTreePainter interface used to dispatch the JS paint callback
+ // to a worklet thread.
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
+
// Attachs a SwapPromise to the Layer tree, that passes through the
// LayerTreeHost and LayerTreeHostImpl with the next commit and frame
// submission, which can be used to observe that progress. This also
@@ -162,10 +168,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// when a main frame is requested.
SwapPromiseManager* GetSwapPromiseManager();
- // Sets whether the content is suitable to use Gpu Rasterization. This flag is
- // used to enable gpu rasterization, and can be modified at any time to change
- // the setting based on content.
+ // Sets or gets whether the content is suitable to use Gpu Rasterization. This
+ // flag is used to enable gpu rasterization, and can be modified at any time
+ // to change the setting based on content.
void SetHasGpuRasterizationTrigger(bool has_trigger);
+ bool has_gpu_rasterization_trigger() const {
+ return has_gpu_rasterization_trigger_;
+ }
// Visibility and LayerTreeFrameSink -------------------------------
@@ -211,7 +220,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// Returns true after SetNeedsAnimate(), SetNeedsUpdateLayers() or
// SetNeedsCommit(), until it is satisfied.
- bool RequestedMainFramePending();
+ bool RequestedMainFramePendingForTesting();
// Requests that the next frame re-chooses crisp raster scales for all layers.
void SetNeedsRecalculateRasterScales();
@@ -300,6 +309,14 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
Layer* root_layer() { return root_layer_.get(); }
const Layer* root_layer() const { return root_layer_.get(); }
+ // Sets the root layer which is not managed by blink, and we will initialize
+ // its paint properties using PropertyTreeBuilder. For ui::Compositor, because
+ // for now we always use PropertyTreeBulder, this function is equivalent to
+ // SetRootLayer().
+ // TODO(crbug.com/925855): This is temporary. Eventually we should let the
+ // caller inform blink about the layer and remove the function.
+ void SetNonBlinkManagedRootLayer(scoped_refptr<Layer> root_layer);
+
// Viewport Layers are used to identify key layers to the compositor thread,
// so that it can perform viewport-based scrolling independently, such as
// for pinch-zoom or overscroll elasticity.
@@ -337,6 +354,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// viewport layers.
struct ViewportPropertyIds {
int page_scale_transform = TransformTree::kInvalidNodeId;
+ int inner_scroll = ScrollTree::kInvalidNodeId;
// TODO(crbug.com/909750): Switch other usages of viewport layers to
// property ids for CompositeAfterPaint.
};
@@ -525,6 +543,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
MutatorHost* mutator_host() const { return mutator_host_; }
+ // Returns the layer with the given |element_id|. In layer-list mode, only
+ // scrollable layers are registered in this map.
Layer* LayerByElementId(ElementId element_id) const;
void RegisterElement(ElementId element_id,
ElementListType list_type,
@@ -577,6 +597,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback);
+ void DidGenerateLocalSurfaceIdAllocation(
+ const viz::LocalSurfaceIdAllocation& allocation);
// Called when the compositor completed page scale animation.
void DidCompletePageScaleAnimation();
void ApplyScrollAndScale(ScrollAndScaleSet* info);
@@ -596,10 +618,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void SetAnimationEvents(std::unique_ptr<MutatorEvents> events);
- bool has_gpu_rasterization_trigger() const {
- return has_gpu_rasterization_trigger_;
- }
-
Proxy* proxy() const { return proxy_.get(); }
bool IsSingleThreaded() const;
@@ -629,7 +647,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
ElementListType list_type,
const gfx::ScrollOffset& scroll_offset) override;
- void ElementIsAnimatingChanged(ElementId element_id,
+ void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) override;
@@ -693,10 +711,12 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void ApplyViewportChanges(const ScrollAndScaleSet& info);
void RecordWheelAndTouchScrollingCount(const ScrollAndScaleSet& info);
+ void SendOverscrollAndScrollEndEventsFromImplSide(
+ const ScrollAndScaleSet& info);
void ApplyPageScaleDeltaFromImplSide(float page_scale_delta);
void InitializeProxy(std::unique_ptr<Proxy> proxy);
- bool DoUpdateLayers(Layer* root_layer);
+ bool DoUpdateLayers();
void UpdateDeferMainFrameUpdateInternal();
@@ -817,6 +837,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// Layer id to Layer map.
std::unordered_map<int, Layer*> layer_id_map_;
+ // In layer-list mode, this map is only used for scrollable layers.
std::unordered_map<ElementId, Layer*, ElementIdHash> element_layers_map_;
// The set of registered element ids when using layer list mode. In non-layer-
@@ -830,6 +851,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// for every layer during property tree building.
bool has_copy_request_ = false;
+ // When settings_.use_layer_lists is true, paint properties are generated by
+ // blink and we don't use PropertyTreeBuilder, except that the root layer
+ // is set by SetNonBlinkManagedRootLayer().
+ // TODO(crbug.com/925855): Remove this field when removing
+ // SetNonBlinkManagedRootLayer().
+ bool force_use_property_tree_builder_ = false;
+
MutatorHost* mutator_host_;
std::vector<std::pair<PaintImage, base::OnceCallback<void(bool)>>>
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 2973940a711..a282dae8f01 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -18,10 +18,12 @@ struct PresentationFeedback;
}
namespace viz {
+class LocalSurfaceIdAllocation;
struct BeginFrameArgs;
}
namespace cc {
+struct ElementId;
struct ApplyViewportChangesArgs {
// Scroll offset delta of the inner (visual) viewport.
@@ -103,6 +105,15 @@ class LayerTreeHostClient {
virtual void RecordWheelAndTouchScrollingCount(
bool has_scrolled_by_wheel,
bool has_scrolled_by_touch) = 0;
+
+ // Notifies the client when an overscroll has happened.
+ virtual void SendOverscrollEventFromImplSide(
+ const gfx::Vector2dF& overscroll_delta,
+ ElementId scroll_latched_element_id) = 0;
+ // Notifies the client when a gesture scroll has ended.
+ virtual void SendScrollEndEventFromImplSide(
+ ElementId scroll_latched_element_id) = 0;
+
// Request a LayerTreeFrameSink from the client. When the client has one it
// should call LayerTreeHost::SetLayerTreeFrameSink. This will result in
// either DidFailToInitializeLayerTreeFrameSink or
@@ -121,6 +132,8 @@ class LayerTreeHostClient {
// Record UMA and UKM metrics that require the time from the start of
// BeginMainFrame to the Commit, or early out.
virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0;
+ virtual void DidGenerateLocalSurfaceIdAllocation(
+ const viz::LocalSurfaceIdAllocation& allocation) = 0;
protected:
virtual ~LayerTreeHostClient() {}
diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc
index 16bee1698d4..e2f1c0d45e3 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -574,7 +574,7 @@ void CalculateDrawPropertiesInternal(
combine_dsf_and_psf ? inputs->page_scale_factor : 1.f;
property_trees->transform_tree.SetRootTransformsAndScales(
inputs->device_scale_factor, page_scale_factor_for_root,
- inputs->device_transform, inputs->root_layer->position());
+ inputs->device_transform);
draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
inputs->root_layer, inputs->property_trees,
inputs->can_adjust_raster_scales);
diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h
index 42de6d2ab68..235910b58d3 100644
--- a/chromium/cc/trees/layer_tree_host_common.h
+++ b/chromium/cc/trees/layer_tree_host_common.h
@@ -168,7 +168,19 @@ struct CC_EXPORT ScrollAndScaleSet {
std::vector<LayerTreeHostCommon::ScrollUpdateInfo> scrolls;
float page_scale_delta;
+
+ // Elastic overscroll effect offset delta. This is used only on Mac and shows
+ // the pixels that the page is rubber-banned/stretched by.
gfx::Vector2dF elastic_overscroll_delta;
+
+ // Unconsumed scroll delta used to send overscroll events to the latched
+ // element on the main thread;
+ gfx::Vector2dF overscroll_delta;
+
+ // The element id of the node to which scrolling is latched. This is used to
+ // send overscroll/scrollend DOM events to proper targets whenever needed.
+ ElementId scroll_latched_element_id;
+
float top_controls_delta;
std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars;
std::vector<std::unique_ptr<SwapPromise>> swap_promises;
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 17a78468e72..05a2290e760 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -350,11 +350,12 @@ class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest {
root->SetBounds(gfx::Size(500, 500));
root->test_properties()->force_render_surface = true;
- target->SetPosition(gfx::PointF(target_rect.origin()));
+ target->test_properties()->position = gfx::PointF(target_rect.origin());
target->SetBounds(target_rect.size());
target->test_properties()->force_render_surface = true;
drawing_layer->test_properties()->transform = layer_transform;
- drawing_layer->SetPosition(gfx::PointF(layer_rect.origin()));
+ drawing_layer->test_properties()->position =
+ gfx::PointF(layer_rect.origin());
drawing_layer->SetBounds(layer_rect.size());
drawing_layer->test_properties()->should_flatten_transform = false;
@@ -396,7 +397,7 @@ TEST_F(LayerTreeHostCommonTest, EffectTreeTransformIdTest) {
child->SetDrawsContent(true);
parent->SetBounds(gfx::Size(100, 100));
- child->SetPosition(gfx::PointF(10, 10));
+ child->test_properties()->position = gfx::PointF(10, 10);
child->SetBounds(gfx::Size(100, 100));
child->test_properties()->opacity = 0.f;
ExecuteCalculateDrawProperties(parent);
@@ -448,7 +449,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
// screen space transform.
gfx::Transform position_transform;
position_transform.Translate(0.f, 1.2f);
- layer->SetPosition(gfx::PointF(0.f, 1.2f));
+ layer->test_properties()->position = gfx::PointF(0.f, 1.2f);
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -465,7 +466,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
layer_transform.Scale3d(2.0, 2.0, 1.0);
layer->test_properties()->transform = layer_transform;
layer->test_properties()->transform_origin = gfx::Point3F();
- layer->SetPosition(gfx::PointF());
+ layer->test_properties()->position = gfx::PointF();
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -495,7 +496,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
// it is still worth testing to detect accidental regressions.
expected_result = position_transform * translation_to_anchor *
layer_transform * Inverse(translation_to_anchor);
- layer->SetPosition(gfx::PointF(0.f, 1.2f));
+ layer->test_properties()->position = gfx::PointF(0.f, 1.2f);
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -645,7 +646,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
// Case 2: parent's position affects child and grand_child.
gfx::Transform parent_position_transform;
parent_position_transform.Translate(0.f, 1.2f);
- parent->SetPosition(gfx::PointF(0.f, 1.2f));
+ parent->test_properties()->position = gfx::PointF(0.f, 1.2f);
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -670,7 +671,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
parent_translation_to_anchor * parent_layer_transform *
Inverse(parent_translation_to_anchor);
parent->test_properties()->transform = parent_layer_transform;
- parent->SetPosition(gfx::PointF());
+ parent->test_properties()->position = gfx::PointF();
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -1367,7 +1368,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->SetBounds(gfx::Size(10, 10));
render_surface1->test_properties()->force_render_surface = true;
child->SetDrawsContent(true);
- child->SetPosition(gfx::PointF(30.f, 30.f));
+ child->test_properties()->position = gfx::PointF(30.f, 30.f);
child->SetBounds(gfx::Size(10, 10));
ExecuteCalculateDrawProperties(root);
@@ -1481,7 +1482,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) {
child1->SetBounds(gfx::Size(25, 25));
child1->SetDrawsContent(true);
child1->test_properties()->force_render_surface = true;
- child2->SetPosition(gfx::PointF(25, 25));
+ child2->test_properties()->position = gfx::PointF(25, 25);
child2->SetBounds(gfx::Size(25, 25));
child2->SetDrawsContent(true);
child2->test_properties()->force_render_surface = true;
@@ -1699,7 +1700,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) {
child->SetBounds(gfx::Size(20, 20));
child->SetMasksToBounds(true);
child->test_properties()->force_render_surface = true;
- grand_child->SetPosition(gfx::PointF(45.f, 45.f));
+ grand_child->test_properties()->position = gfx::PointF(45.f, 45.f);
grand_child->SetBounds(gfx::Size(10, 10));
great_grand_child->SetBounds(gfx::Size(10, 10));
leaf_node1->SetBounds(gfx::Size(500, 500));
@@ -1739,7 +1740,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
root->SetBounds(gfx::Size(100, 100));
child->SetBounds(gfx::Size(20, 20));
child->test_properties()->force_render_surface = true;
- grand_child->SetPosition(gfx::PointF(200.f, 200.f));
+ grand_child->test_properties()->position = gfx::PointF(200.f, 200.f);
grand_child->SetBounds(gfx::Size(10, 10));
grand_child->test_properties()->force_render_surface = true;
leaf_node->SetBounds(gfx::Size(10, 10));
@@ -1874,7 +1875,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) {
EXPECT_EQ(gfx::Rect(100, 100), child->clip_rect());
parent->SetMasksToBounds(true);
- child->SetPosition(gfx::PointF(100.f, 100.f));
+ child->test_properties()->position = gfx::PointF(100.f, 100.f);
host_impl()->active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
@@ -1910,17 +1911,17 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
child->SetMasksToBounds(true);
child->SetBounds(gfx::Size(20, 20));
child->test_properties()->force_render_surface = true;
- grand_child1->SetPosition(gfx::PointF(5.f, 5.f));
+ grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f);
grand_child1->SetBounds(gfx::Size(10, 10));
grand_child1->SetDrawsContent(true);
- grand_child2->SetPosition(gfx::PointF(15.f, 15.f));
+ grand_child2->test_properties()->position = gfx::PointF(15.f, 15.f);
grand_child2->SetBounds(gfx::Size(10, 10));
grand_child2->SetDrawsContent(true);
- grand_child3->SetPosition(gfx::PointF(15.f, 15.f));
+ grand_child3->test_properties()->position = gfx::PointF(15.f, 15.f);
grand_child3->SetMasksToBounds(true);
grand_child3->SetBounds(gfx::Size(10, 10));
grand_child3->SetDrawsContent(true);
- grand_child4->SetPosition(gfx::PointF(45.f, 45.f));
+ grand_child4->test_properties()->position = gfx::PointF(45.f, 45.f);
grand_child4->SetBounds(gfx::Size(10, 10));
grand_child4->SetDrawsContent(true);
ExecuteCalculateDrawProperties(parent);
@@ -1956,17 +1957,17 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
child->SetBounds(gfx::Size(20, 20));
child->SetMasksToBounds(true);
child->test_properties()->force_render_surface = true;
- grand_child1->SetPosition(gfx::PointF(5.f, 5.f));
+ grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f);
grand_child1->SetBounds(gfx::Size(10, 10));
grand_child1->test_properties()->force_render_surface = true;
- grand_child2->SetPosition(gfx::PointF(15.f, 15.f));
+ grand_child2->test_properties()->position = gfx::PointF(15.f, 15.f);
grand_child2->SetBounds(gfx::Size(10, 10));
grand_child2->test_properties()->force_render_surface = true;
- grand_child3->SetPosition(gfx::PointF(15.f, 15.f));
+ grand_child3->test_properties()->position = gfx::PointF(15.f, 15.f);
grand_child3->SetBounds(gfx::Size(10, 10));
grand_child3->SetMasksToBounds(true);
grand_child3->test_properties()->force_render_surface = true;
- grand_child4->SetPosition(gfx::PointF(45.f, 45.f));
+ grand_child4->test_properties()->position = gfx::PointF(45.f, 45.f);
grand_child4->SetBounds(gfx::Size(10, 10));
grand_child4->SetMasksToBounds(true);
grand_child4->test_properties()->force_render_surface = true;
@@ -2019,48 +2020,47 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
layer_transform.Translate(1.0, 1.0);
root->test_properties()->transform = layer_transform;
- root->SetPosition(gfx::PointF(2.5f, 0.f));
root->SetBounds(gfx::Size(10, 10));
root->test_properties()->transform_origin = gfx::Point3F(0.25f, 0.f, 0.f);
render_surface1->test_properties()->transform = layer_transform;
- render_surface1->SetPosition(gfx::PointF(2.5f, 0.f));
+ render_surface1->test_properties()->position = gfx::PointF(2.5f, 0.f);
render_surface1->SetBounds(gfx::Size(10, 10));
render_surface1->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
render_surface1->test_properties()->force_render_surface = true;
render_surface2->test_properties()->transform = layer_transform;
- render_surface2->SetPosition(gfx::PointF(2.5f, 0.f));
+ render_surface2->test_properties()->position = gfx::PointF(2.5f, 0.f);
render_surface2->SetBounds(gfx::Size(10, 10));
render_surface2->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
render_surface2->test_properties()->force_render_surface = true;
child_of_root->test_properties()->transform = layer_transform;
- child_of_root->SetPosition(gfx::PointF(2.5f, 0.f));
+ child_of_root->test_properties()->position = gfx::PointF(2.5f, 0.f);
child_of_root->SetBounds(gfx::Size(10, 10));
child_of_root->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
child_of_rs1->test_properties()->transform = layer_transform;
- child_of_rs1->SetPosition(gfx::PointF(2.5f, 0.f));
+ child_of_rs1->test_properties()->position = gfx::PointF(2.5f, 0.f);
child_of_rs1->SetBounds(gfx::Size(10, 10));
child_of_rs1->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
child_of_rs2->test_properties()->transform = layer_transform;
- child_of_rs2->SetPosition(gfx::PointF(2.5f, 0.f));
+ child_of_rs2->test_properties()->position = gfx::PointF(2.5f, 0.f);
child_of_rs2->SetBounds(gfx::Size(10, 10));
child_of_rs2->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
grand_child_of_root->test_properties()->transform = layer_transform;
- grand_child_of_root->SetPosition(gfx::PointF(2.5f, 0.f));
+ grand_child_of_root->test_properties()->position = gfx::PointF(2.5f, 0.f);
grand_child_of_root->SetBounds(gfx::Size(10, 10));
grand_child_of_root->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
grand_child_of_rs1->test_properties()->transform = layer_transform;
- grand_child_of_rs1->SetPosition(gfx::PointF(2.5f, 0.f));
+ grand_child_of_rs1->test_properties()->position = gfx::PointF(2.5f, 0.f);
grand_child_of_rs1->SetBounds(gfx::Size(10, 10));
grand_child_of_rs1->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
grand_child_of_rs2->test_properties()->transform = layer_transform;
- grand_child_of_rs2->SetPosition(gfx::PointF(2.5f, 0.f));
+ grand_child_of_rs2->test_properties()->position = gfx::PointF(2.5f, 0.f);
grand_child_of_rs2->SetBounds(gfx::Size(10, 10));
grand_child_of_rs2->test_properties()->transform_origin =
gfx::Point3F(0.25f, 0.f, 0.f);
@@ -2548,23 +2548,6 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) {
drawing_layer->drawable_content_rect());
}
-TEST_F(LayerTreeHostCommonTest,
- VisibleRectsForPositionedRootLayerClippedByViewport) {
- LayerImpl* root = root_layer_for_testing();
-
- root->SetPosition(gfx::PointF(60, 70));
- root->SetBounds(gfx::Size(100, 100));
- root->SetDrawsContent(true);
- ExecuteCalculateDrawProperties(root);
-
- EXPECT_EQ(gfx::RectF(100.f, 100.f),
- GetRenderSurface(root)->DrawableContentRect());
- // In target space, not clipped.
- EXPECT_EQ(gfx::Rect(60, 70, 100, 100), root->drawable_content_rect());
- // In layer space, clipped.
- EXPECT_EQ(gfx::Rect(40, 30), root->visible_layer_rect());
-}
-
TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* child1_layer = AddChildToRoot<LayerImpl>();
@@ -2574,10 +2557,10 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
root->SetBounds(gfx::Size(100, 100));
child1_layer->SetBounds(gfx::Size(50, 50));
child1_layer->SetDrawsContent(true);
- child2_layer->SetPosition(gfx::PointF(75.f, 75.f));
+ child2_layer->test_properties()->position = gfx::PointF(75.f, 75.f);
child2_layer->SetBounds(gfx::Size(50, 50));
child2_layer->SetDrawsContent(true);
- child3_layer->SetPosition(gfx::PointF(125.f, 125.f));
+ child3_layer->test_properties()->position = gfx::PointF(125.f, 125.f);
child3_layer->SetBounds(gfx::Size(50, 50));
child3_layer->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -2610,13 +2593,13 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(100, 100));
child->SetBounds(gfx::Size(100, 100));
child->SetMasksToBounds(true);
- grand_child1->SetPosition(gfx::PointF(5.f, 5.f));
+ grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f);
grand_child1->SetBounds(gfx::Size(50, 50));
grand_child1->SetDrawsContent(true);
- grand_child2->SetPosition(gfx::PointF(75.f, 75.f));
+ grand_child2->test_properties()->position = gfx::PointF(75.f, 75.f);
grand_child2->SetBounds(gfx::Size(50, 50));
grand_child2->SetDrawsContent(true);
- grand_child3->SetPosition(gfx::PointF(125.f, 125.f));
+ grand_child3->test_properties()->position = gfx::PointF(125.f, 125.f);
grand_child3->SetBounds(gfx::Size(50, 50));
grand_child3->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -2672,7 +2655,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) {
clip->SetBounds(gfx::Size(10, 10));
filter->test_properties()->force_render_surface = true;
filter_child->SetBounds(gfx::Size(2000, 2000));
- filter_child->SetPosition(gfx::PointF(-50, -50));
+ filter_child->test_properties()->position = gfx::PointF(-50, -50);
filter_child->SetDrawsContent(true);
clip->SetMasksToBounds(true);
@@ -2721,7 +2704,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) {
clip->SetBounds(gfx::Size(10, 10));
filter->test_properties()->force_render_surface = true;
filter_child->SetBounds(gfx::Size(2000, 2000));
- filter_child->SetPosition(gfx::PointF(-50, -50));
+ filter_child->test_properties()->position = gfx::PointF(-50, -50);
filter_child->SetDrawsContent(true);
clip->SetMasksToBounds(true);
@@ -2847,13 +2830,13 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(100, 100));
render_surface->SetBounds(gfx::Size(3, 4));
render_surface->test_properties()->force_render_surface = true;
- child1->SetPosition(gfx::PointF(5.f, 5.f));
+ child1->test_properties()->position = gfx::PointF(5.f, 5.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
- child2->SetPosition(gfx::PointF(75.f, 75.f));
+ child2->test_properties()->position = gfx::PointF(75.f, 75.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
- child3->SetPosition(gfx::PointF(125.f, 125.f));
+ child3->test_properties()->position = gfx::PointF(125.f, 125.f);
child3->SetBounds(gfx::Size(50, 50));
child3->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -2891,13 +2874,13 @@ TEST_F(LayerTreeHostCommonTest,
LayerImpl* child3 = AddChild<LayerImpl>(root);
root->SetBounds(gfx::Size(100, 100));
- child1->SetPosition(gfx::PointF(5.f, 5.f));
+ child1->test_properties()->position = gfx::PointF(5.f, 5.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
- child2->SetPosition(gfx::PointF(75.f, 75.f));
+ child2->test_properties()->position = gfx::PointF(75.f, 75.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
- child3->SetPosition(gfx::PointF(125.f, 125.f));
+ child3->test_properties()->position = gfx::PointF(125.f, 125.f);
child3->SetBounds(gfx::Size(50, 50));
child3->SetDrawsContent(true);
@@ -2928,7 +2911,7 @@ TEST_F(LayerTreeHostCommonTest,
LayerImpl* child = AddChildToRoot<LayerImpl>();
root->SetBounds(gfx::Size(100, 100));
- child->SetPosition(gfx::PointF(5.f, 5.f));
+ child->test_properties()->position = gfx::PointF(5.f, 5.f);
child->SetBounds(gfx::Size(50, 50));
child->SetDrawsContent(true);
@@ -2981,7 +2964,7 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(100, 100));
child->test_properties()->transform = perspective;
- child->SetPosition(gfx::PointF(10.f, 10.f));
+ child->test_properties()->position = gfx::PointF(10.f, 10.f);
child->SetBounds(gfx::Size(100, 100));
child->SetDrawsContent(true);
child->test_properties()->sorting_context_id = 1;
@@ -3145,7 +3128,7 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(1000, 1000));
child->test_properties()->transform = perspective;
- child->SetPosition(gfx::PointF(10.f, 10.f));
+ child->test_properties()->position = gfx::PointF(10.f, 10.f);
child->SetBounds(gfx::Size(300, 300));
child->test_properties()->should_flatten_transform = false;
child->test_properties()->sorting_context_id = 1;
@@ -3209,13 +3192,13 @@ TEST_F(LayerTreeHostCommonTest,
root->SetMasksToBounds(true);
render_surface->SetBounds(gfx::Size(3, 4));
render_surface->test_properties()->force_render_surface = true;
- child1->SetPosition(gfx::PointF(5.f, 5.f));
+ child1->test_properties()->position = gfx::PointF(5.f, 5.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
- child2->SetPosition(gfx::PointF(75.f, 75.f));
+ child2->test_properties()->position = gfx::PointF(75.f, 75.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
- child3->SetPosition(gfx::PointF(125.f, 125.f));
+ child3->test_properties()->position = gfx::PointF(125.f, 125.f);
child3->SetBounds(gfx::Size(50, 50));
child3->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -3262,13 +3245,13 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->test_properties()->force_render_surface = true;
render_surface2->SetBounds(gfx::Size(7, 13));
render_surface2->test_properties()->force_render_surface = true;
- child1->SetPosition(gfx::PointF(5.f, 5.f));
+ child1->test_properties()->position = gfx::PointF(5.f, 5.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
- child2->SetPosition(gfx::PointF(75.f, 75.f));
+ child2->test_properties()->position = gfx::PointF(75.f, 75.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
- child3->SetPosition(gfx::PointF(125.f, 125.f));
+ child3->test_properties()->position = gfx::PointF(125.f, 125.f);
child3->SetBounds(gfx::Size(50, 50));
child3->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -3378,7 +3361,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
root->SetBounds(gfx::Size(100, 100));
- clip_parent->SetPosition(gfx::PointF(2.f, 2.f));
+ clip_parent->test_properties()->position = gfx::PointF(2.f, 2.f);
clip_parent->SetBounds(gfx::Size(50, 50));
clip_parent->test_properties()->clip_children =
std::make_unique<std::set<LayerImpl*>>();
@@ -3530,7 +3513,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface->SetBounds(gfx::Size(3, 4));
render_surface->test_properties()->force_render_surface = true;
child1->test_properties()->transform = child_rotation;
- child1->SetPosition(gfx::PointF(25.f, 25.f));
+ child1->test_properties()->position = gfx::PointF(25.f, 25.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->test_properties()->transform_origin = gfx::Point3F(25.f, 25.f, 0.f);
@@ -3576,7 +3559,7 @@ TEST_F(LayerTreeHostCommonTest,
root->SetMasksToBounds(true);
render_surface->SetBounds(gfx::Size(3, 4));
render_surface->test_properties()->force_render_surface = true;
- child1->SetPosition(gfx::PointF(25.f, 25.f));
+ child1->test_properties()->position = gfx::PointF(25.f, 25.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->test_properties()->transform = child_rotation;
@@ -3622,21 +3605,21 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) {
root->SetBounds(gfx::Size(100, 100));
root->SetMasksToBounds(true);
render_surface1->SetBounds(gfx::Size(3, 4));
- render_surface1->SetPosition(gfx::PointF(5.f, 5.f));
+ render_surface1->test_properties()->position = gfx::PointF(5.f, 5.f);
render_surface1->SetDrawsContent(true);
render_surface1->test_properties()->force_render_surface = true;
render_surface2->SetBounds(gfx::Size(7, 13));
- render_surface2->SetPosition(gfx::PointF(5.f, 5.f));
+ render_surface2->test_properties()->position = gfx::PointF(5.f, 5.f);
render_surface2->SetDrawsContent(true);
render_surface2->test_properties()->force_render_surface = true;
child1->SetBounds(gfx::Size(50, 50));
- child1->SetPosition(gfx::PointF(5.f, 5.f));
+ child1->test_properties()->position = gfx::PointF(5.f, 5.f);
child1->SetDrawsContent(true);
child2->SetBounds(gfx::Size(50, 50));
- child2->SetPosition(gfx::PointF(75.f, 75.f));
+ child2->test_properties()->position = gfx::PointF(75.f, 75.f);
child2->SetDrawsContent(true);
child3->SetBounds(gfx::Size(50, 50));
- child3->SetPosition(gfx::PointF(125.f, 125.f));
+ child3->test_properties()->position = gfx::PointF(125.f, 125.f);
child3->SetDrawsContent(true);
float device_scale_factor = 2.f;
ExecuteCalculateDrawProperties(root, device_scale_factor);
@@ -4020,12 +4003,12 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) {
root->SetDrawsContent(true);
LayerImpl* child = AddChildToRoot<LayerImpl>();
- child->SetPosition(gfx::PointF(2.f, 2.f));
+ child->test_properties()->position = gfx::PointF(2.f, 2.f);
child->SetBounds(gfx::Size(10, 10));
child->SetDrawsContent(true);
LayerImpl* child2 = AddChildToRoot<LayerImpl>();
- child2->SetPosition(gfx::PointF(2.f, 2.f));
+ child2->test_properties()->position = gfx::PointF(2.f, 2.f);
child2->SetBounds(gfx::Size(5, 5));
child2->SetDrawsContent(true);
@@ -4062,8 +4045,8 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) {
// Verify child and child2 transforms. They should match.
gfx::Transform expected_child_transform;
expected_child_transform.Scale(device_scale_factor, device_scale_factor);
- expected_child_transform.Translate(child->position().x(),
- child->position().y());
+ expected_child_transform.Translate(child->test_properties()->position.x(),
+ child->test_properties()->position.y());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
child->DrawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
@@ -4087,7 +4070,7 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) {
gfx::RectF child2_screen_space_rect =
MathUtil::MapClippedRect(child2->ScreenSpaceTransform(), child_bounds);
- gfx::RectF expected_child_draw_rect(child->position(),
+ gfx::RectF expected_child_draw_rect(child->test_properties()->position,
gfx::SizeF(child->bounds()));
expected_child_draw_rect.Scale(device_scale_factor);
EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
@@ -4115,7 +4098,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) {
parent->SetDrawsContent(true);
LayerImpl* perspective_surface = AddChild<LayerImpl>(parent);
- perspective_surface->SetPosition(gfx::PointF(2.f, 2.f));
+ perspective_surface->test_properties()->position = gfx::PointF(2.f, 2.f);
perspective_surface->SetBounds(gfx::Size(10, 10));
perspective_surface->test_properties()->transform =
perspective_matrix * scale_small_matrix;
@@ -4123,7 +4106,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) {
perspective_surface->test_properties()->force_render_surface = true;
LayerImpl* scale_surface = AddChild<LayerImpl>(parent);
- scale_surface->SetPosition(gfx::PointF(2.f, 2.f));
+ scale_surface->test_properties()->position = gfx::PointF(2.f, 2.f);
scale_surface->SetBounds(gfx::Size(10, 10));
scale_surface->test_properties()->transform = scale_small_matrix;
scale_surface->SetDrawsContent(true);
@@ -4176,9 +4159,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) {
gfx::Transform expected_perspective_surface_draw_transform;
expected_perspective_surface_draw_transform.Translate(
device_scale_factor * page_scale_factor *
- perspective_surface->position().x(),
+ perspective_surface->test_properties()->position.x(),
device_scale_factor * page_scale_factor *
- perspective_surface->position().y());
+ perspective_surface->test_properties()->position.y());
expected_perspective_surface_draw_transform.PreconcatTransform(
perspective_matrix);
expected_perspective_surface_draw_transform.PreconcatTransform(
@@ -4213,7 +4196,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) {
parent->SetDrawsContent(true);
LayerImpl* child_scale = AddChild<LayerImpl>(parent);
- child_scale->SetPosition(gfx::PointF(2.f, 2.f));
+ child_scale->test_properties()->position = gfx::PointF(2.f, 2.f);
child_scale->SetBounds(gfx::Size(10, 10));
child_scale->test_properties()->transform = child_scale_matrix;
child_scale->SetDrawsContent(true);
@@ -4257,7 +4240,7 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) {
LayerImpl* child_scale = AddChild<LayerImpl>(parent);
child_scale->SetBounds(gfx::Size(10, 10));
- child_scale->SetPosition(gfx::PointF(2.f, 2.f));
+ child_scale->test_properties()->position = gfx::PointF(2.f, 2.f);
child_scale->test_properties()->transform = child_scale_matrix;
child_scale->SetDrawsContent(true);
@@ -4279,7 +4262,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
LayerImpl* child = AddChildToRoot<LayerImpl>();
child->SetBounds(gfx::Size(10, 10));
- child->SetPosition(gfx::PointF(2.f, 2.f));
+ child->test_properties()->position = gfx::PointF(2.f, 2.f);
child->SetDrawsContent(true);
child->test_properties()->force_render_surface = true;
@@ -4311,8 +4294,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
gfx::Transform expected_screen_space_transform;
expected_screen_space_transform.Scale(device_scale_factor,
device_scale_factor);
- expected_screen_space_transform.Translate(child->position().x(),
- child->position().y());
+ expected_screen_space_transform.Translate(
+ child->test_properties()->position.x(),
+ child->test_properties()->position.y());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
child->ScreenSpaceTransform());
@@ -4329,8 +4313,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
gfx::Transform expected_render_surface_draw_transform;
expected_render_surface_draw_transform.Translate(
- device_scale_factor * child->position().x(),
- device_scale_factor * child->position().y());
+ device_scale_factor * child->test_properties()->position.x(),
+ device_scale_factor * child->test_properties()->position.y());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform,
GetRenderSurface(child)->draw_transform());
@@ -5075,7 +5059,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) {
copy_layer->test_properties()->force_render_surface = true;
LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer);
- copy_child->SetPosition(gfx::PointF(40.f, 40.f));
+ copy_child->test_properties()->position = gfx::PointF(40.f, 40.f);
copy_child->SetBounds(gfx::Size(20, 20));
copy_child->SetDrawsContent(true);
@@ -5084,12 +5068,12 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) {
copy_clip->SetMasksToBounds(true);
LayerImpl* copy_clipped_child = AddChild<LayerImpl>(copy_clip);
- copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
+ copy_clipped_child->test_properties()->position = gfx::PointF(40.f, 40.f);
copy_clipped_child->SetBounds(gfx::Size(20, 20));
copy_clipped_child->SetDrawsContent(true);
LayerImpl* copy_surface = AddChild<LayerImpl>(copy_clip);
- copy_surface->SetPosition(gfx::PointF(45.f, 45.f));
+ copy_surface->test_properties()->position = gfx::PointF(45.f, 45.f);
copy_surface->SetBounds(gfx::Size(20, 20));
copy_surface->SetDrawsContent(true);
copy_surface->test_properties()->force_render_surface = true;
@@ -5172,11 +5156,11 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
render_surface->SetBounds(gfx::Size(10, 10));
render_surface->test_properties()->force_render_surface = true;
clip_parent->test_properties()->transform = scale_transform;
- clip_parent->SetPosition(gfx::PointF(1.f, 1.f));
+ clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f);
clip_parent->SetBounds(gfx::Size(10, 10));
- intervening->SetPosition(gfx::PointF(1.f, 1.f));
+ intervening->test_properties()->position = gfx::PointF(1.f, 1.f);
intervening->SetBounds(gfx::Size(5, 5));
- clip_child->SetPosition(gfx::PointF(1.f, 1.f));
+ clip_child->test_properties()->position = gfx::PointF(1.f, 1.f);
clip_child->SetBounds(gfx::Size(10, 10));
ExecuteCalculateDrawProperties(root);
@@ -5233,15 +5217,15 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
translation_transform.Translate(2, 2);
root->SetBounds(gfx::Size(50, 50));
- clip_parent->SetPosition(gfx::PointF(1.f, 1.f));
+ clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f);
clip_parent->SetBounds(gfx::Size(40, 40));
render_surface1->SetBounds(gfx::Size(10, 10));
render_surface1->test_properties()->force_render_surface = true;
- intervening->SetPosition(gfx::PointF(1.f, 1.f));
+ intervening->test_properties()->position = gfx::PointF(1.f, 1.f);
intervening->SetBounds(gfx::Size(5, 5));
render_surface2->SetBounds(gfx::Size(10, 10));
render_surface2->test_properties()->force_render_surface = true;
- clip_child->SetPosition(gfx::PointF(-10.f, -10.f));
+ clip_child->test_properties()->position = gfx::PointF(-10.f, -10.f);
clip_child->SetBounds(gfx::Size(60, 60));
ExecuteCalculateDrawProperties(root);
@@ -5319,15 +5303,15 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
root->SetBounds(gfx::Size(50, 50));
clip_parent->test_properties()->transform = translation_transform;
- clip_parent->SetPosition(gfx::PointF(1.f, 1.f));
+ clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f);
clip_parent->SetBounds(gfx::Size(40, 40));
render_surface1->SetBounds(gfx::Size(10, 10));
render_surface1->test_properties()->force_render_surface = true;
- intervening->SetPosition(gfx::PointF(1.f, 1.f));
+ intervening->test_properties()->position = gfx::PointF(1.f, 1.f);
intervening->SetBounds(gfx::Size(5, 5));
render_surface2->SetBounds(gfx::Size(10, 10));
render_surface2->test_properties()->force_render_surface = true;
- clip_child->SetPosition(gfx::PointF(-10.f, -10.f));
+ clip_child->test_properties()->position = gfx::PointF(-10.f, -10.f);
clip_child->SetBounds(gfx::Size(60, 60));
BuildPropertyTreesForTesting();
intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3));
@@ -5452,12 +5436,12 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(15, 15));
clip_parent->SetBounds(gfx::Size(10, 10));
clip_layer->SetBounds(gfx::Size(10, 10));
- render_surface1->SetPosition(gfx::PointF(5, 5));
+ render_surface1->test_properties()->position = gfx::PointF(5, 5);
render_surface1->SetBounds(gfx::Size(5, 5));
render_surface1->test_properties()->force_render_surface = true;
render_surface2->SetBounds(gfx::Size(5, 5));
render_surface2->test_properties()->force_render_surface = true;
- clip_child->SetPosition(gfx::PointF(-1, 1));
+ clip_child->test_properties()->position = gfx::PointF(-1, 1);
clip_child->SetBounds(gfx::Size(10, 10));
non_clip_child->SetBounds(gfx::Size(5, 5));
@@ -5744,7 +5728,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) {
scroll_child_target->SetBounds(gfx::Size(50, 50));
scroll_child_target->test_properties()->force_render_surface = true;
scroll_child->SetBounds(gfx::Size(50, 50));
- scroll_parent_target->SetPosition(gfx::PointF(10, 10));
+ scroll_parent_target->test_properties()->position = gfx::PointF(10, 10);
scroll_parent_target->SetBounds(gfx::Size(50, 50));
scroll_parent_target->SetMasksToBounds(true);
scroll_parent_target->test_properties()->force_render_surface = true;
@@ -6001,13 +5985,13 @@ TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) {
fixed->test_properties()->position_constraint = constraint;
root->SetBounds(gfx::Size(50, 50));
- render_surface->SetPosition(gfx::PointF(7.f, 9.f));
+ render_surface->test_properties()->position = gfx::PointF(7.f, 9.f);
render_surface->SetBounds(gfx::Size(50, 50));
render_surface->SetDrawsContent(true);
- fixed->SetPosition(gfx::PointF(10.f, 15.f));
+ fixed->test_properties()->position = gfx::PointF(10.f, 15.f);
fixed->SetBounds(gfx::Size(50, 50));
fixed->SetDrawsContent(true);
- child->SetPosition(gfx::PointF(1.f, 2.f));
+ child->test_properties()->position = gfx::PointF(1.f, 2.f);
child->SetBounds(gfx::Size(50, 50));
child->SetDrawsContent(true);
ExecuteCalculateDrawProperties(root);
@@ -8422,9 +8406,9 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) {
root->SetBounds(gfx::Size(50, 50));
root->SetMasksToBounds(true);
root->test_properties()->is_container_for_fixed_position_layers = true;
- child->SetPosition(gfx::PointF(1000, 1000));
+ child->test_properties()->position = gfx::PointF(1000, 1000);
child->SetBounds(gfx::Size(50, 50));
- grandchild->SetPosition(gfx::PointF(-1000, -1000));
+ grandchild->test_properties()->position = gfx::PointF(-1000, -1000);
grandchild->SetBounds(gfx::Size(50, 50));
grandchild->SetDrawsContent(true);
@@ -8450,10 +8434,10 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(50, 50));
root->SetMasksToBounds(true);
root->test_properties()->is_container_for_fixed_position_layers = true;
- child->SetPosition(gfx::PointF(1000, 1000));
+ child->test_properties()->position = gfx::PointF(1000, 1000);
child->SetBounds(gfx::Size(50, 50));
child->test_properties()->is_container_for_fixed_position_layers = true;
- grandchild->SetPosition(gfx::PointF(-1000, -1000));
+ grandchild->test_properties()->position = gfx::PointF(-1000, -1000);
grandchild->SetBounds(gfx::Size(50, 50));
grandchild->SetDrawsContent(true);
@@ -8476,7 +8460,7 @@ TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) {
root->SetBounds(gfx::Size(800, 800));
root->test_properties()->is_container_for_fixed_position_layers = true;
- frame_clip->SetPosition(gfx::PointF(500, 100));
+ frame_clip->test_properties()->position = gfx::PointF(500, 100);
frame_clip->SetBounds(gfx::Size(100, 100));
frame_clip->SetMasksToBounds(true);
@@ -8502,7 +8486,7 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
root->SetBounds(gfx::Size(800, 800));
root->SetDrawsContent(true);
root->test_properties()->is_container_for_fixed_position_layers = true;
- frame_clip->SetPosition(gfx::PointF(500, 100));
+ frame_clip->test_properties()->position = gfx::PointF(500, 100);
frame_clip->SetBounds(gfx::Size(100, 100));
frame_clip->SetMasksToBounds(true);
frame_clip->SetDrawsContent(true);
@@ -8511,7 +8495,7 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
scroller->SetScrollable(frame_clip->bounds());
scroller->SetDrawsContent(true);
- fixed->SetPosition(gfx::PointF(100, 100));
+ fixed->test_properties()->position = gfx::PointF(100, 100);
fixed->SetBounds(gfx::Size(50, 50));
fixed->SetMasksToBounds(true);
fixed->SetDrawsContent(true);
@@ -8599,7 +8583,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) {
ExecuteCalculateDrawProperties(root);
EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect());
- scroll_child->SetPosition(gfx::PointF(0, -10.f));
+ scroll_child->test_properties()->position = gfx::PointF(0, -10.f);
scroll_parent->SetCurrentScrollOffset(gfx::ScrollOffset(0.f, 10.f));
ExecuteCalculateDrawProperties(root);
EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect());
@@ -9569,7 +9553,7 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) {
root->SetMasksToBounds(true);
clip_layer->SetBounds(gfx::Size(30, 30));
clip_layer->SetMasksToBounds(true);
- render_surface1->SetPosition(gfx::PointF(10, 10));
+ render_surface1->test_properties()->position = gfx::PointF(10, 10);
render_surface1->SetBounds(gfx::Size(30, 30));
render_surface1->SetDrawsContent(true);
render_surface1->test_properties()->force_render_surface = true;
@@ -10031,7 +10015,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_parent2.element_id = parent2->element_id();
scroll_parent2.scrollable = true;
scroll_parent2.main_thread_scrolling_reasons =
- parent2->main_thread_scrolling_reasons();
+ parent2->GetMainThreadScrollingReasons();
scroll_parent2.container_bounds = root1->bounds();
scroll_parent2.bounds = parent2->bounds();
scroll_parent2.max_scroll_offset_affected_by_page_scale = true;
@@ -10045,7 +10029,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
ScrollNode scroll_child6;
scroll_child6.id = 3;
scroll_child6.main_thread_scrolling_reasons =
- child6->main_thread_scrolling_reasons();
+ child6->GetMainThreadScrollingReasons();
scroll_child6.should_flatten = true;
scroll_child6.user_scrollable_horizontal = true;
scroll_child6.user_scrollable_vertical = true;
@@ -10354,7 +10338,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCacheRenderSurface) {
copy_layer->test_properties()->force_render_surface = true;
LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer);
- copy_child->SetPosition(gfx::PointF(40.f, 40.f));
+ copy_child->test_properties()->position = gfx::PointF(40.f, 40.f);
copy_child->SetBounds(gfx::Size(20, 20));
copy_child->SetDrawsContent(true);
@@ -10363,12 +10347,12 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCacheRenderSurface) {
copy_clip->SetMasksToBounds(true);
LayerImpl* copy_clipped_child = AddChild<LayerImpl>(copy_clip);
- copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
+ copy_clipped_child->test_properties()->position = gfx::PointF(40.f, 40.f);
copy_clipped_child->SetBounds(gfx::Size(20, 20));
copy_clipped_child->SetDrawsContent(true);
LayerImpl* cache_surface = AddChild<LayerImpl>(copy_clip);
- cache_surface->SetPosition(gfx::PointF(45.f, 45.f));
+ cache_surface->test_properties()->position = gfx::PointF(45.f, 45.f);
cache_surface->SetBounds(gfx::Size(20, 20));
cache_surface->SetDrawsContent(true);
@@ -10495,7 +10479,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTrilinearFiltering) {
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->test_properties()->force_render_surface = true;
- child2->SetPosition(gfx::PointF(50, 50));
+ child2->test_properties()->position = gfx::PointF(50, 50);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
child2->test_properties()->force_render_surface = true;
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index dcfc217ced6..6a44080f309 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -50,6 +50,7 @@
#include "cc/layers/scrollbar_layer_impl_base.h"
#include "cc/layers/surface_layer_impl.h"
#include "cc/layers/viewport.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/raster/bitmap_raster_buffer_provider.h"
#include "cc/raster/gpu_raster_buffer_provider.h"
#include "cc/raster/one_copy_raster_buffer_provider.h"
@@ -86,7 +87,6 @@
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
-#include "components/viz/common/gpu/texture_allocation.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
@@ -97,11 +97,14 @@
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/platform_color.h"
+#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/common/traced_value.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gfx/geometry/point_conversions.h"
@@ -1066,12 +1069,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
active_tree()->property_trees()->effect_tree.HasCopyRequests();
bool have_missing_animated_tiles = false;
- int num_layers = 0;
- int num_mask_layers = 0;
- int num_rounded_corner_mask_layers = 0;
- int64_t visible_mask_layer_area = 0;
- int64_t visible_rounded_corner_mask_layer_area = 0;
-
for (EffectTreeLayerListIterator it(active_tree());
it.state() != EffectTreeLayerListIterator::State::END; ++it) {
auto target_render_pass_id = it.target_render_surface()->id();
@@ -1106,7 +1103,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
frame->may_contain_video = true;
layer->AppendQuads(target_render_pass, &append_quads_data);
- ++num_layers;
}
rendering_stats_instrumentation_->AddVisibleContentArea(
@@ -1146,12 +1142,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
}
frame->use_default_lower_bound_deadline |=
append_quads_data.use_default_lower_bound_deadline;
- num_mask_layers += append_quads_data.num_mask_layers;
- num_rounded_corner_mask_layers +=
- append_quads_data.num_rounded_corner_mask_layers;
- visible_mask_layer_area += append_quads_data.visible_mask_layer_area;
- visible_rounded_corner_mask_layer_area +=
- append_quads_data.visible_rounded_corner_mask_layer_area;
}
// If CommitToActiveTree() is true, then we wait to draw until
@@ -1231,34 +1221,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
checkerboarded_needs_raster_content_area);
}
- // Only record these umas on the first frame, and only in the renderer,
- // for which we use having a compositor thread as a proxy.
- if (!active_tree_->has_ever_been_drawn() && SupportsImplScrolling()) {
- int mask_layer_percent = static_cast<int>(
- num_mask_layers / static_cast<float>(num_layers) * 100);
- int rc_mask_layer_percent =
- static_cast<int>(num_rounded_corner_mask_layers /
- static_cast<float>(num_mask_layers) * 100);
- int rc_area_percent =
- static_cast<int>(visible_rounded_corner_mask_layer_area /
- static_cast<float>(total_visible_area) * 100);
-
- UMA_HISTOGRAM_PERCENTAGE(
- "Compositing.RenderPass.AppendQuadData.MaskLayerPercent",
- mask_layer_percent);
- if (num_mask_layers > 0) {
- UMA_HISTOGRAM_PERCENTAGE(
- "Compositing.RenderPass.AppendQuadData.RCMaskLayerPercent",
- rc_mask_layer_percent);
- UMA_HISTOGRAM_PERCENTAGE(
- "Compositing.RenderPass.AppendQuadData.RCMaskAreaPercent",
- rc_area_percent);
- UMA_HISTOGRAM_COUNTS_10M(
- "Compositing.RenderPass.AppendQuadData.RCMaskArea",
- visible_rounded_corner_mask_layer_area);
- }
- }
-
TRACE_EVENT_END2("cc,benchmark", "LayerTreeHostImpl::CalculateRenderPasses",
"draw_result", draw_result, "missing tiles",
num_missing_tiles);
@@ -1724,9 +1686,9 @@ void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
}
void LayerTreeHostImpl::SetTreeActivationCallback(
- const base::Closure& callback) {
+ base::RepeatingClosure callback) {
DCHECK(task_runner_provider_->IsImplThread());
- tree_activation_callback_ = callback;
+ tree_activation_callback_ = std::move(callback);
}
void LayerTreeHostImpl::SetManagedMemoryPolicy(
@@ -1916,10 +1878,7 @@ void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
viz::CompositorFrameMetadata metadata;
- metadata.frame_token = next_frame_token_++;
- if (!next_frame_token_)
- next_frame_token_ = 1u;
-
+ metadata.frame_token = ++next_frame_token_;
metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
active_tree_->device_scale_factor();
@@ -1928,9 +1887,7 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
metadata.root_background_color = active_tree_->background_color();
metadata.content_source_id = active_tree_->content_source_id();
- if (active_tree_->has_presentation_callbacks() ||
- settings_.always_request_presentation_time) {
- metadata.request_presentation_feedback = true;
+ if (active_tree_->has_presentation_callbacks()) {
frame_token_infos_.emplace_back(metadata.frame_token,
CurrentBeginFrameArgs().frame_time,
active_tree_->TakePresentationCallbacks());
@@ -2064,7 +2021,7 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
if (child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.IsValid()) {
if (allocate_new_local_surface_id)
- child_local_surface_id_allocator_.GenerateId();
+ AllocateLocalSurfaceId();
metadata.local_surface_id_allocation =
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
}
@@ -2086,9 +2043,13 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
return false;
}
+ layer_tree_frame_sink_->set_source_frame_number(
+ active_tree_->source_frame_number());
+
auto compositor_frame = GenerateCompositorFrame(frame);
layer_tree_frame_sink_->SubmitCompositorFrame(
- std::move(compositor_frame), debug_state_.show_hit_test_borders);
+ std::move(compositor_frame),
+ /*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders);
// Clears the list of swap promises after calling DidSwap on each of them to
// signal that the swap is over.
@@ -2174,7 +2135,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
metadata.activation_dependencies = std::move(frame->activation_dependencies);
active_tree()->FinishSwapPromises(&metadata);
// The swap-promises should not change the frame-token.
- DCHECK_EQ(metadata.frame_token + 1, next_frame_token_);
+ DCHECK_EQ(metadata.frame_token, *next_frame_token_);
if (render_frame_metadata_observer_) {
last_draw_render_frame_metadata_ = MakeRenderFrameMetadata(frame);
@@ -2654,7 +2615,7 @@ base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
Region overlapping_region;
for (const auto* layer : base::Reversed(*active_tree())) {
- if (!layer->should_hit_test())
+ if (!layer->ShouldHitTest())
continue;
if (layer->is_surface_layer()) {
@@ -2935,20 +2896,17 @@ void LayerTreeHostImpl::ActivateSyncTree() {
child_local_surface_id_allocator_.UpdateFromParent(
active_tree()->local_surface_id_allocation_from_parent());
if (active_tree()->TakeNewLocalSurfaceIdRequest())
- child_local_surface_id_allocator_.GenerateId();
+ AllocateLocalSurfaceId();
}
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host_impl=3
if (VLOG_IS_ON(3)) {
- std::string property_trees;
- base::JSONWriter::WriteWithOptions(
- *active_tree_->property_trees()->AsTracedValue()->ToBaseValue(),
- base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
VLOG(3) << "After activating sync tree, the active tree:"
<< "\nproperty_trees:\n"
- << property_trees << "\nlayers:\n"
- << LayerListAsJson();
+ << active_tree_->property_trees()->ToString() << "\n"
+ << "cc::LayerImpls:\n"
+ << active_tree_->LayerListAsJson();
}
}
@@ -3181,6 +3139,11 @@ void LayerTreeHostImpl::SetLayerTreeMutator(
mutator_host_->SetLayerTreeMutator(std::move(mutator));
}
+void LayerTreeHostImpl::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ tile_manager_.SetPaintWorkletLayerPainter(std::move(painter));
+}
+
LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() {
return viewport()->MainScrollLayer();
}
@@ -3201,8 +3164,8 @@ void LayerTreeHostImpl::QueueImageDecode(int request_id,
// Optimistically specify the current raster color space, since we assume that
// it won't change.
tile_manager_.decoded_image_tracker().QueueImageDecode(
- image, base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
- base::Unretained(this), request_id));
+ image, base::BindOnce(&LayerTreeHostImpl::ImageDecodeFinished,
+ base::Unretained(this), request_id));
tile_manager_.checker_image_tracker().DisallowCheckeringForImage(image);
}
@@ -3252,8 +3215,12 @@ void LayerTreeHostImpl::CleanUpTileManagerResources() {
// contexts. Flushing now helps ensure these are cleaned up quickly
// preventing driver cache growth. See crbug.com/643251
if (layer_tree_frame_sink_) {
- if (auto* compositor_context = layer_tree_frame_sink_->context_provider())
- compositor_context->ContextGL()->ShallowFlushCHROMIUM();
+ if (auto* compositor_context = layer_tree_frame_sink_->context_provider()) {
+ // TODO(ericrk): Remove ordering barrier once |compositor_context| no
+ // longer uses GL.
+ compositor_context->ContextGL()->OrderingBarrierCHROMIUM();
+ compositor_context->ContextSupport()->FlushPendingWork();
+ }
if (auto* worker_context =
layer_tree_frame_sink_->worker_context_provider()) {
viz::RasterContextProvider::ScopedRasterContextLock hold(worker_context);
@@ -3278,6 +3245,8 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
ClearUIResources();
if (layer_tree_frame_sink_->context_provider()) {
+ // TODO(ericrk): Remove this once all uses of ContextGL from LTFS are
+ // removed.
auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
gl->Finish();
}
@@ -3391,7 +3360,7 @@ bool LayerTreeHostImpl::InitializeFrameSink(
const viz::LocalSurfaceIdAllocation& local_surface_id_allocation =
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
if (local_surface_id_allocation.IsValid())
- child_local_surface_id_allocator_.GenerateId();
+ AllocateLocalSurfaceId();
} else {
layer_tree_frame_sink_->ForceAllocateNewId();
}
@@ -3470,8 +3439,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll(
// We may not find an associated layer for the root or secondary root node -
// that's fine, they're not associated with any elements on the page. We also
- // won't find a layer for the inner viewport (in SPv2) since it doesn't
- // require hit testing.
+ // won't find a layer for the inner viewport (in CompositeAfterPaint) since it
+ // doesn't require hit testing.
DCHECK(layer || scroll_node->id == ScrollTree::kRootNodeId ||
scroll_node->id == ScrollTree::kSecondaryRootNodeId ||
scroll_node->scrolls_inner_viewport);
@@ -4443,6 +4412,10 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
client_->SetNeedsCommitOnImplThread();
SetNeedsRedraw();
client_->RenewTreePriority();
+ } else {
+ overscroll_delta_for_main_thread_ +=
+ gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y());
+ client_->SetNeedsCommitOnImplThread();
}
// Scrolling along an axis resets accumulated root overscroll for that axis.
@@ -4630,6 +4603,10 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) {
scroll_gesture_did_end_ = true;
+ last_scroller_element_id_ = CurrentlyScrollingNode()
+ ? CurrentlyScrollingNode()->element_id
+ : ElementId();
+ client_->SetNeedsCommitOnImplThread();
if (should_snap && SnapAtScrollEnd())
return;
@@ -4813,6 +4790,23 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
scroll_info->scroll_gesture_did_end = scroll_gesture_did_end_;
has_scrolled_by_wheel_ = has_scrolled_by_touch_ = false;
+ // Record and reset overscroll delta.
+ scroll_info->overscroll_delta = overscroll_delta_for_main_thread_;
+ overscroll_delta_for_main_thread_ = gfx::Vector2dF();
+
+ if (scroll_gesture_did_end_) {
+ // When the scrolling has finished send the element id of the last node that
+ // has scrolled.
+ scroll_info->scroll_latched_element_id = last_scroller_element_id_;
+ last_scroller_element_id_ = ElementId();
+ } else {
+ // Send the element id of the currently scrolling node.
+ auto* node =
+ active_tree_->property_trees()->scroll_tree.CurrentlyScrollingNode();
+ scroll_info->scroll_latched_element_id =
+ node ? node->element_id : ElementId();
+ }
+
if (browser_controls_manager()) {
scroll_info->browser_controls_constraint =
browser_controls_manager()->PullConstraintForMainThread(
@@ -4931,28 +4925,6 @@ void LayerTreeHostImpl::ActivateAnimations() {
}
}
-std::string LayerTreeHostImpl::LayerListAsJson() const {
- auto list = std::make_unique<base::ListValue>();
- for (auto* layer : *active_tree_) {
- list->Append(layer->LayerAsJson());
- }
- std::string str;
- base::JSONWriter::WriteWithOptions(
- *list, base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
- return str;
-}
-
-std::string LayerTreeHostImpl::LayerTreeAsJson() const {
- std::string str;
- if (active_tree_->root_layer_for_testing()) {
- std::unique_ptr<base::Value> json(
- active_tree_->root_layer_for_testing()->LayerTreeAsJson());
- base::JSONWriter::WriteWithOptions(
- *json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
- }
- return str;
-}
-
void LayerTreeHostImpl::RegisterScrollbarAnimationController(
ElementId scroll_element_id,
float scrollbar_opacity) {
@@ -5008,9 +4980,9 @@ void LayerTreeHostImpl::FlashAllScrollbars(bool did_scroll) {
}
void LayerTreeHostImpl::PostDelayedScrollbarAnimationTask(
- const base::Closure& task,
+ base::OnceClosure task,
base::TimeDelta delay) {
- client_->PostDelayedAnimationTaskOnImplThread(task, delay);
+ client_->PostDelayedAnimationTaskOnImplThread(std::move(task), delay);
}
// TODO(danakj): Make this a return value from the Animate() call instead of an
@@ -5188,9 +5160,13 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
upload_size = gfx::ScaleToCeiledSize(source_size, scale, scale);
}
- // For gpu compositing, a texture will be allocated and the UIResource
- // will be uploaded into it.
- viz::TextureAllocation texture_alloc;
+ // For gpu compositing, a SharedImage mailbox will be allocated and the
+ // UIResource will be uploaded into it.
+ gpu::Mailbox mailbox;
+ uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY;
+ // For gpu compositing, we also calculate the GL texture target.
+ // TODO(ericrk): Remove references to GL from this code.
+ GLenum texture_target = GL_TEXTURE_2D;
// For software compositing, shared memory will be allocated and the
// UIResource will be copied into it.
std::unique_ptr<base::SharedMemory> shared_memory;
@@ -5199,10 +5175,16 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
if (layer_tree_frame_sink_->context_provider()) {
viz::ContextProvider* context_provider =
layer_tree_frame_sink_->context_provider();
- texture_alloc = viz::TextureAllocation::MakeTextureId(
- context_provider->ContextGL(), context_provider->ContextCapabilities(),
- format, settings_.resource_settings.use_gpu_memory_buffer_resources,
- /*for_framebuffer_attachment=*/false);
+ const auto& caps = context_provider->ContextCapabilities();
+ bool overlay_candidate =
+ settings_.resource_settings.use_gpu_memory_buffer_resources &&
+ caps.texture_storage_image &&
+ viz::IsGpuMemoryBufferFormatSupported(format);
+ if (overlay_candidate) {
+ shared_image_usage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ texture_target = gpu::GetBufferTextureTarget(gfx::BufferUsage::SCANOUT,
+ BufferFormat(format), caps);
+ }
} else {
shared_memory =
viz::bitmap_allocation::AllocateMappedBitmap(upload_size, format);
@@ -5213,10 +5195,15 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// If not scaled, we can copy the pixels 1:1 from the source bitmap to our
// destination backing of a texture or shared bitmap.
if (layer_tree_frame_sink_->context_provider()) {
- viz::TextureAllocation::UploadStorage(
- layer_tree_frame_sink_->context_provider()->ContextGL(),
- layer_tree_frame_sink_->context_provider()->ContextCapabilities(),
- format, upload_size, texture_alloc, color_space, bitmap.GetPixels());
+ viz::ContextProvider* context_provider =
+ layer_tree_frame_sink_->context_provider();
+ auto* sii = context_provider->SharedImageInterface();
+ size_t size_to_send =
+ viz::ResourceSizes::CheckedSizeInBytes<unsigned int>(upload_size,
+ format);
+ mailbox = sii->CreateSharedImage(
+ format, upload_size, color_space, shared_image_usage,
+ base::span<const uint8_t>(bitmap.GetPixels(), size_to_send));
} else {
DCHECK_EQ(bitmap.GetFormat(), UIResourceBitmap::RGBA8);
SkImageInfo src_info =
@@ -5275,10 +5262,14 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
if (layer_tree_frame_sink_->context_provider()) {
SkPixmap pixmap;
scaled_surface->peekPixels(&pixmap);
- viz::TextureAllocation::UploadStorage(
- layer_tree_frame_sink_->context_provider()->ContextGL(),
- layer_tree_frame_sink_->context_provider()->ContextCapabilities(),
- format, upload_size, texture_alloc, color_space, pixmap.addr());
+ viz::ContextProvider* context_provider =
+ layer_tree_frame_sink_->context_provider();
+ auto* sii = context_provider->SharedImageInterface();
+ mailbox = sii->CreateSharedImage(
+ format, upload_size, color_space, shared_image_usage,
+ base::span<const uint8_t>(
+ reinterpret_cast<const uint8_t*>(pixmap.addr()),
+ pixmap.computeByteSize()));
}
}
@@ -5291,16 +5282,12 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// allocated in this method above.
viz::TransferableResource transferable;
if (layer_tree_frame_sink_->context_provider()) {
- gpu::gles2::GLES2Interface* gl =
- layer_tree_frame_sink_->context_provider()->ContextGL();
- gpu::Mailbox mailbox;
- gl->ProduceTextureDirectCHROMIUM(texture_alloc.texture_id, mailbox.name);
- gpu::SyncToken sync_token =
- viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
+ gpu::SyncToken sync_token = layer_tree_frame_sink_->context_provider()
+ ->SharedImageInterface()
+ ->GenUnverifiedSyncToken();
transferable = viz::TransferableResource::MakeGLOverlay(
- mailbox, GL_LINEAR, texture_alloc.texture_target, sync_token,
- upload_size, texture_alloc.overlay_candidate);
+ mailbox, GL_LINEAR, texture_target, sync_token, upload_size, false);
transferable.format = format;
} else {
mojo::ScopedSharedBufferHandle memory_handle =
@@ -5326,7 +5313,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
data.format = format;
data.shared_bitmap_id = shared_bitmap_id;
data.shared_memory = std::move(shared_memory);
- data.texture_id = texture_alloc.texture_id;
+ data.mailbox = mailbox;
data.resource_id_for_export = id;
ui_resource_map_[uid] = std::move(data);
@@ -5353,15 +5340,13 @@ void LayerTreeHostImpl::DeleteUIResourceBacking(
UIResourceData data,
const gpu::SyncToken& sync_token) {
// Resources are either software or gpu backed, not both.
- DCHECK(!(data.shared_memory && data.texture_id));
+ DCHECK(!(data.shared_memory && !data.mailbox.IsZero()));
if (data.shared_memory)
layer_tree_frame_sink_->DidDeleteSharedBitmap(data.shared_bitmap_id);
- if (data.texture_id) {
- gpu::gles2::GLES2Interface* gl =
- layer_tree_frame_sink_->context_provider()->ContextGL();
- if (sync_token.HasData())
- gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
- gl->DeleteTextures(1, &data.texture_id);
+ if (!data.mailbox.IsZero()) {
+ auto* sii =
+ layer_tree_frame_sink_->context_provider()->SharedImageInterface();
+ sii->DestroySharedImage(sync_token, data.mailbox);
}
// |data| goes out of scope and deletes anything it owned.
}
@@ -5583,7 +5568,7 @@ void LayerTreeHostImpl::SetElementScrollOffsetMutated(
}
void LayerTreeHostImpl::ElementIsAnimatingChanged(
- ElementId element_id,
+ const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) {
@@ -5591,8 +5576,9 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged(
list_type == ElementListType::ACTIVE ? active_tree() : pending_tree();
// TODO(wkorman): Explore enabling DCHECK in ElementIsAnimatingChanged()
// below. Currently enabling causes batch of unit test failures.
- if (tree && tree->property_trees()->ElementIsAnimatingChanged(
- mutator_host(), element_id, list_type, mask, state, false))
+ if (tree &&
+ tree->property_trees()->ElementIsAnimatingChanged(
+ mutator_host(), element_id_map, list_type, mask, state, false))
tree->set_needs_update_draw_properties();
}
@@ -5702,4 +5688,10 @@ void LayerTreeHostImpl::SetActiveURL(const GURL& url) {
ukm_manager_->SetSourceURL(url);
}
+void LayerTreeHostImpl::AllocateLocalSurfaceId() {
+ child_local_surface_id_allocator_.GenerateId();
+ client_->DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation());
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index b932defe22e..04b75068704 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -74,6 +74,7 @@ class ImageAnimationController;
class LayerImpl;
class LayerTreeFrameSink;
class LayerTreeImpl;
+class PaintWorkletLayerPainter;
class MemoryHistory;
class MutatorEvents;
class MutatorHost;
@@ -93,8 +94,6 @@ class TaskGraphRunner;
class UIResourceBitmap;
class Viewport;
-using BeginFrameCallbackList = std::vector<base::Closure>;
-
enum class GpuRasterizationStatus {
ON,
ON_FORCED,
@@ -128,7 +127,7 @@ class LayerTreeHostImplClient {
std::unique_ptr<MutatorEvents> events) = 0;
virtual bool IsInsideDraw() = 0;
virtual void RenewTreePriority() = 0;
- virtual void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+ virtual void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) = 0;
virtual void DidActivateSyncTree() = 0;
virtual void WillPrepareTiles() = 0;
@@ -155,6 +154,9 @@ class LayerTreeHostImplClient {
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) = 0;
+ virtual void DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) = 0;
+
protected:
virtual ~LayerTreeHostImplClient() {}
};
@@ -183,8 +185,6 @@ class CC_EXPORT LayerTreeHostImpl
std::vector<viz::SurfaceId> activation_dependencies;
base::Optional<uint32_t> deadline_in_frames;
bool use_default_lower_bound_deadline = false;
- std::vector<gfx::Rect> occluding_screen_space_rects;
- std::vector<gfx::Rect> non_occluding_screen_space_rects;
viz::RenderPassList render_passes;
const RenderSurfaceList* render_surface_list = nullptr;
LayerImplList will_draw_layers;
@@ -211,7 +211,7 @@ class CC_EXPORT LayerTreeHostImpl
viz::SharedBitmapId shared_bitmap_id;
std::unique_ptr<base::SharedMemory> shared_memory;
// Backing for gpu compositing.
- uint32_t texture_id;
+ gpu::Mailbox mailbox;
// The name with which to refer to the resource in frames submitted to the
// display compositor.
@@ -355,7 +355,7 @@ class CC_EXPORT LayerTreeHostImpl
ElementId element_id,
ElementListType list_type,
const gfx::ScrollOffset& scroll_offset) override;
- void ElementIsAnimatingChanged(ElementId element_id,
+ void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) override;
@@ -421,7 +421,7 @@ class CC_EXPORT LayerTreeHostImpl
WhichTree tree) const override;
// ScrollbarAnimationControllerClient implementation.
- void PostDelayedScrollbarAnimationTask(const base::Closure& task,
+ void PostDelayedScrollbarAnimationTask(base::OnceClosure task,
base::TimeDelta delay) override;
void SetNeedsAnimateForScrollbarAnimation() override;
void SetNeedsRedrawForScrollbarAnimation() override;
@@ -447,8 +447,7 @@ class CC_EXPORT LayerTreeHostImpl
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override;
- void SetTreeActivationCallback(
- const base::RepeatingClosure& callback) override;
+ void SetTreeActivationCallback(base::RepeatingClosure callback) override;
void OnDraw(const gfx::Transform& transform,
const gfx::Rect& viewport,
bool resourceless_software_draw,
@@ -466,11 +465,6 @@ class CC_EXPORT LayerTreeHostImpl
int max_texture_size() const { return max_texture_size_; }
void ReleaseLayerTreeFrameSink();
- std::string LayerListAsJson() const;
- // TODO(pdr): This should be removed because there is no longer a tree
- // of layers, only a list.
- std::string LayerTreeAsJson() const;
-
int RequestedMSAASampleCount() const;
virtual bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink);
@@ -499,7 +493,7 @@ class CC_EXPORT LayerTreeHostImpl
return &image_animation_controller_;
}
- uint32_t next_frame_token() const { return next_frame_token_; }
+ uint32_t next_frame_token() const { return *next_frame_token_; }
virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args);
virtual void DidFinishImplFrame();
@@ -686,6 +680,8 @@ class CC_EXPORT LayerTreeHostImpl
base::TimeDelta delayed_by);
void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator);
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
// The viewport has two scroll nodes, corresponding to the visual and layout
// viewports. However, when we compute the scroll chain we include only one
@@ -884,6 +880,8 @@ class CC_EXPORT LayerTreeHostImpl
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel level);
+ void AllocateLocalSurfaceId();
+
const LayerTreeSettings settings_;
const bool is_synchronous_single_threaded_;
@@ -970,6 +968,10 @@ class CC_EXPORT LayerTreeHostImpl
gfx::Vector2dF accumulated_root_overscroll_;
+ // Unconsumed scroll delta sent to the main thread for firing overscroll DOM
+ // events. Resets after each commit.
+ gfx::Vector2dF overscroll_delta_for_main_thread_;
+
// True iff some of the delta has been consumed for the current scroll
// sequence on the specific axis.
bool did_scroll_x_for_scroll_gesture_;
@@ -1020,7 +1022,7 @@ class CC_EXPORT LayerTreeHostImpl
single_thread_synchronous_task_graph_runner_;
// Optional callback to notify of new tree activations.
- base::Closure tree_activation_callback_;
+ base::RepeatingClosure tree_activation_callback_;
TaskGraphRunner* task_graph_runner_;
int id_;
@@ -1074,7 +1076,7 @@ class CC_EXPORT LayerTreeHostImpl
// each CompositorFrame.
std::unique_ptr<RenderFrameMetadataObserver> render_frame_metadata_observer_;
- uint32_t next_frame_token_ = 1u;
+ viz::FrameTokenGenerator next_frame_token_;
viz::LocalSurfaceIdAllocation last_draw_local_surface_id_allocation_;
base::flat_set<viz::SurfaceRange> last_draw_referenced_surfaces_;
@@ -1116,6 +1118,10 @@ class CC_EXPORT LayerTreeHostImpl
// ended.
bool scroll_gesture_did_end_;
+ // Set in ScrollEnd before clearing the currently scrolling node. This is
+ // used to send the scrollend DOM event when scrolling has happened on CC.
+ ElementId last_scroller_element_id_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index a31b2fe9444..29e2776963f 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -187,9 +187,9 @@ class LayerTreeHostImplTest : public testing::Test,
std::unique_ptr<MutatorEvents> events) override {}
bool IsInsideDraw() override { return false; }
void RenewTreePriority() override {}
- void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+ void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override {
- animation_task_ = task;
+ animation_task_ = std::move(task);
requested_animation_delay_ = delay;
}
void DidActivateSyncTree() override {
@@ -224,6 +224,8 @@ class LayerTreeHostImplTest : public testing::Test,
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override {}
+ void DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) override {}
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
@@ -276,7 +278,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) {
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
@@ -359,7 +361,7 @@ class LayerTreeHostImplTest : public testing::Test,
std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
root->SetBounds(content_size);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->test_properties()->force_render_surface = true;
std::unique_ptr<LayerImpl> inner_scroll =
@@ -384,7 +386,7 @@ class LayerTreeHostImplTest : public testing::Test,
inner_scroll->SetElementId(
LayerIdToElementIdForTesting(inner_scroll->id()));
inner_scroll->SetBounds(content_size);
- inner_scroll->SetPosition(gfx::PointF());
+ inner_scroll->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> outer_clip =
LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
@@ -402,13 +404,13 @@ class LayerTreeHostImplTest : public testing::Test,
->scroll_tree.UpdateScrollOffsetBaseForTesting(
outer_scroll->element_id(), gfx::ScrollOffset());
outer_scroll->SetBounds(content_size);
- outer_scroll->SetPosition(gfx::PointF());
+ outer_scroll->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> contents =
LayerImpl::Create(layer_tree_impl, kContentLayerId);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetPosition(gfx::PointF());
+ contents->test_properties()->position = gfx::PointF();
outer_scroll->test_properties()->AddChild(std::move(contents));
outer_clip->test_properties()->AddChild(std::move(outer_scroll));
@@ -447,7 +449,7 @@ class LayerTreeHostImplTest : public testing::Test,
host_impl_->active_tree()->SetDeviceViewportSize(content_size);
std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
root->SetBounds(content_size);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
scroll->SetBounds(scroll_content_size);
@@ -459,14 +461,14 @@ class LayerTreeHostImplTest : public testing::Test,
SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10,
0, false, true);
scrollbar->SetBounds(scrollbar_size);
- scrollbar->SetPosition(gfx::PointF(345, 0));
+ scrollbar->test_properties()->position = gfx::PointF(345, 0);
scrollbar->SetScrollElementId(scroll->element_id());
scrollbar->SetDrawsContent(true);
scrollbar->test_properties()->opacity = 1.f;
std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
squash1->SetBounds(gfx::Size(140, 300));
- squash1->SetPosition(gfx::PointF(220, 0));
+ squash1->test_properties()->position = gfx::PointF(220, 0);
if (transparent_layer) {
squash1->test_properties()->opacity = 0.0f;
// The transparent layer should still participate in hit testing even
@@ -478,7 +480,7 @@ class LayerTreeHostImplTest : public testing::Test,
std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6);
squash2->SetBounds(gfx::Size(140, 300));
- squash2->SetPosition(gfx::PointF(220, 300));
+ squash2->test_properties()->position = gfx::PointF(220, 300);
squash2->SetDrawsContent(true);
scroll->test_properties()->AddChild(std::move(squash2));
@@ -653,7 +655,7 @@ class LayerTreeHostImplTest : public testing::Test,
LayerImpl::Create(host_impl_->active_tree(), 6);
LayerImpl* child = child_layer.get();
child_layer->SetDrawsContent(true);
- child_layer->SetPosition(gfx::PointF(0, 0));
+ child_layer->test_properties()->position = gfx::PointF(0, 0);
child_layer->SetBounds(gfx::Size(25, 25));
scroll->test_properties()->AddChild(std::move(child_layer));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -702,7 +704,7 @@ class LayerTreeHostImplTest : public testing::Test,
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(),
gfx::ScrollOffset());
- overflow->SetPosition(gfx::PointF(0, 0));
+ overflow->test_properties()->position = gfx::PointF(0, 0);
SnapContainerData container_data(
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
@@ -784,7 +786,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool did_complete_page_scale_animation_;
bool reduce_memory_result_;
bool did_request_impl_side_invalidation_;
- base::Closure animation_task_;
+ base::OnceClosure animation_task_;
base::TimeDelta requested_animation_delay_;
std::unique_ptr<TestFrameData> last_on_draw_frame_;
viz::RenderPassList last_on_draw_render_passes_;
@@ -1184,7 +1186,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
LayerImpl::Create(host_impl_->active_tree(), 6);
child = child_layer.get();
child_layer->SetDrawsContent(true);
- child_layer->SetPosition(gfx::PointF(0, 20));
+ child_layer->test_properties()->position = gfx::PointF(0, 20);
child_layer->SetBounds(gfx::Size(50, 50));
scroll->test_properties()->AddChild(std::move(child_layer));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -1231,8 +1233,8 @@ TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50));
LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
- root->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
+ root->test_properties()->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
host_impl_->active_tree()->BuildPropertyTreesForTesting();
DrawFrame();
@@ -1267,7 +1269,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
host_impl_->active_tree()->SetDeviceViewportSize(content_size);
std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
root->SetBounds(content_size);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
scroll->SetBounds(scroll_content_size);
@@ -1279,14 +1281,14 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0,
false, true);
drawn_scrollbar->SetBounds(scrollbar_size);
- drawn_scrollbar->SetPosition(gfx::PointF(345, 0));
+ drawn_scrollbar->test_properties()->position = gfx::PointF(345, 0);
drawn_scrollbar->SetScrollElementId(scroll->element_id());
drawn_scrollbar->SetDrawsContent(true);
drawn_scrollbar->test_properties()->opacity = 1.f;
std::unique_ptr<LayerImpl> squash = LayerImpl::Create(layer_tree_impl, 5);
squash->SetBounds(gfx::Size(140, 300));
- squash->SetPosition(gfx::PointF(220, 0));
+ squash->test_properties()->position = gfx::PointF(220, 0);
squash->SetDrawsContent(true);
scroll->test_properties()->AddChild(std::move(drawn_scrollbar));
@@ -1376,7 +1378,7 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
- outer_scroll->SetPosition(gfx::PointF(-25.f, 0.f));
+ outer_scroll->test_properties()->position = gfx::PointF(-25.f, 0.f);
outer_scroll->SetDrawsContent(true);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -1718,7 +1720,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(),
gfx::ScrollOffset());
- overflow->SetPosition(gfx::PointF(40, 40));
+ overflow->test_properties()->position = gfx::PointF(40, 40);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(30, 30));
@@ -1887,7 +1889,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(),
gfx::ScrollOffset());
- overflow->SetPosition(gfx::PointF());
+ overflow->test_properties()->position = gfx::PointF();
host_impl_->active_tree()->BuildPropertyTreesForTesting();
DrawFrame();
@@ -2687,7 +2689,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
std::unique_ptr<LayerImpl> scroll_child =
CreateScrollableLayer(9, gfx::Size(10, 10));
child = scroll_child.get();
- scroll_child->SetPosition(gfx::PointF(20.f, 20.f));
+ scroll_child->test_properties()->position = gfx::PointF(20.f, 20.f);
scroll_child_clip->test_properties()->AddChild(std::move(scroll_child));
child_clip = scroll_child_clip.get();
@@ -3614,13 +3616,13 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
// A task will be posted to fade the initial scrollbar.
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
requested_animation_delay_ = base::TimeDelta();
- animation_task_ = base::Closure();
+ animation_task_.Reset();
} else {
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
}
@@ -3631,7 +3633,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
// For Aura Overlay Scrollbar, if no scroll happened during a scroll
// gesture, shows scrollbars and schedules a delay fade out.
@@ -3644,12 +3646,12 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
if (animator == LayerTreeSettings::AURA_OVERLAY) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
requested_animation_delay_);
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
requested_animation_delay_ = base::TimeDelta();
- animation_task_ = base::Closure();
+ animation_task_.Reset();
} else {
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
}
// Before the scrollbar animation exists, we should not get redraws.
@@ -3662,7 +3664,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_FALSE(did_request_redraw_);
did_request_redraw_ = false;
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
host_impl_->DidFinishImplFrame();
// After a scroll, a scrollbar animation should be scheduled about 20ms from
@@ -3676,10 +3678,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
if (expecting_animations) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
requested_animation_delay_);
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
} else {
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
}
host_impl_->ScrollEnd(EndState().get());
@@ -3688,10 +3690,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
if (expecting_animations) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
requested_animation_delay_);
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
} else {
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
}
if (expecting_animations) {
@@ -3709,8 +3711,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
// Start the scrollbar animation.
fake_now += requested_animation_delay_;
requested_animation_delay_ = base::TimeDelta();
- animation_task_.Run();
- animation_task_ = base::Closure();
+ std::move(animation_task_).Run();
EXPECT_TRUE(did_request_next_frame_);
did_request_next_frame_ = false;
EXPECT_FALSE(did_request_redraw_);
@@ -3725,7 +3726,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_TRUE(did_request_redraw_);
did_request_redraw_ = false;
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
host_impl_->DidFinishImplFrame();
}
@@ -3741,7 +3742,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
// Changing page scale triggers scrollbar animation.
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
@@ -3751,12 +3752,12 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
if (expecting_animations) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
requested_animation_delay_);
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
requested_animation_delay_ = base::TimeDelta();
- animation_task_ = base::Closure();
+ animation_task_.Reset();
} else {
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
}
}
};
@@ -3797,7 +3798,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
host_impl_->pending_tree()->InnerViewportContainerLayer();
scrollbar->SetScrollElementId(scroll->element_id());
scrollbar->SetBounds(gfx::Size(10, 100));
- scrollbar->SetPosition(gfx::PointF(90, 0));
+ scrollbar->test_properties()->position = gfx::PointF(90, 0);
scrollbar->SetNeedsPushProperties();
container->test_properties()->AddChild(std::move(scrollbar));
@@ -3912,7 +3913,7 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1));
scrollbar_1->SetTouchActionRegion(touch_action_region);
scrollbar_1->SetCurrentPos(0);
- scrollbar_1->SetPosition(gfx::PointF(0, 0));
+ scrollbar_1->test_properties()->position = gfx::PointF(0, 0);
host_impl_->active_tree()
->InnerViewportContainerLayer()
->test_properties()
@@ -3926,7 +3927,7 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
scrollbar_2_ = scrollbar_2.get();
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
- child->SetPosition(gfx::PointF(50, 50));
+ child->test_properties()->position = gfx::PointF(50, 50);
child->SetBounds(child_layer_size);
child->SetDrawsContent(true);
child->SetScrollable(gfx::Size(100, 100));
@@ -3937,7 +3938,7 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
scrollbar_2->SetDrawsContent(true);
scrollbar_2->SetBounds(scrollbar_size_2);
scrollbar_2->SetCurrentPos(0);
- scrollbar_2->SetPosition(gfx::PointF(0, 0));
+ scrollbar_2->test_properties()->position = gfx::PointF(0, 0);
child->test_properties()->AddChild(std::move(scrollbar_2));
root_scroll->test_properties()->AddChild(std::move(child));
@@ -3956,7 +3957,7 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
if (is_aura_scrollbar_)
- animation_task_ = base::Closure();
+ animation_task_.Reset();
}
bool is_aura_scrollbar_;
@@ -3987,7 +3988,7 @@ TEST_F(LayerTreeHostImplTestMultiScrollable,
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_TRUE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
ResetScrollbars();
// Scroll on child should flash all scrollbars.
@@ -3998,7 +3999,7 @@ TEST_F(LayerTreeHostImplTestMultiScrollable,
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_TRUE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
}
TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollbarFlashWhenMouseEnter) {
@@ -4018,13 +4019,13 @@ TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollbarFlashWhenMouseEnter) {
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_FALSE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
host_impl_->MouseMoveAt(gfx::Point(51, 51));
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_TRUE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
}
TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollHitTestOnScrollbar) {
@@ -4089,7 +4090,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
host_impl_->pending_tree()->InnerViewportContainerLayer();
scrollbar->SetScrollElementId(scroll->element_id());
scrollbar->SetBounds(gfx::Size(10, 100));
- scrollbar->SetPosition(gfx::PointF(90, 0));
+ scrollbar->test_properties()->position = gfx::PointF(90, 0);
scrollbar->SetNeedsPushProperties();
container->test_properties()->AddChild(std::move(scrollbar));
@@ -4104,9 +4105,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
// Scrollbars will flash shown but we should have a fade out animation
// queued. Run it and fade out the scrollbars.
{
- ASSERT_FALSE(animation_task_.Equals(base::Closure()));
+ ASSERT_FALSE(animation_task_.is_null());
ASSERT_FALSE(animation_task_.IsCancelled());
- animation_task_.Run();
+ std::move(animation_task_).Run();
base::TimeTicks fake_now = base::TimeTicks::Now();
scrollbar_controller->Animate(fake_now);
@@ -4119,9 +4120,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
// Move the mouse over the scrollbar region. This should post a delayed fade
// in task. Execute it to fade in the scrollbars.
{
- animation_task_ = base::Closure();
+ animation_task_.Reset();
scrollbar_controller->DidMouseMove(gfx::PointF(90, 0));
- ASSERT_FALSE(animation_task_.Equals(base::Closure()));
+ ASSERT_FALSE(animation_task_.is_null());
ASSERT_FALSE(animation_task_.IsCancelled());
}
@@ -4131,7 +4132,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
did_request_redraw_ = false;
did_request_commit_ = false;
ASSERT_TRUE(scrollbar_controller->ScrollbarsHidden());
- animation_task_.Run();
+ std::move(animation_task_).Run();
base::TimeTicks fake_now = base::TimeTicks::Now();
scrollbar_controller->Animate(fake_now);
@@ -4246,12 +4247,12 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
root_scroll->element_id()));
// Scrolling the viewport should result in a scrollbar animation update.
- animation_task_ = base::Closure();
+ animation_task_.Reset();
host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(10, 10)).get());
host_impl_->ScrollEnd(EndState().get());
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
- animation_task_ = base::Closure();
+ EXPECT_FALSE(animation_task_.is_null());
+ animation_task_.Reset();
// Check scrollbar registration on a sublayer.
child->SetScrollable(viewport_size);
@@ -4272,13 +4273,13 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
// Changing one of the child layers should result in a scrollbar animation
// update.
- animation_task_ = base::Closure();
+ animation_task_.Reset();
child_ptr->SetBounds(gfx::Size(200, 200));
child_ptr->set_needs_show_scrollbars(true);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain();
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
- animation_task_ = base::Closure();
+ EXPECT_FALSE(animation_task_.is_null());
+ animation_task_.Reset();
// Check scrollbar unregistration.
container->test_properties()->RemoveChild(vert_1_scrollbar);
@@ -4303,9 +4304,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
// Changing scroll offset should no longer trigger any animation.
host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset(
gfx::ScrollOffset(20, 20));
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20));
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
}
TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) {
@@ -4330,7 +4331,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) {
vert_scrollbar->SetScrollElementId(root_scroll->element_id());
vert_scrollbar->SetBounds(gfx::Size(10, 200));
- vert_scrollbar->SetPosition(gfx::PointF(300, 0));
+ vert_scrollbar->test_properties()->position = gfx::PointF(300, 0);
vert_scrollbar->test_properties()->opacity_can_animate = true;
vert_scrollbar->SetCurrentPos(0);
@@ -4488,7 +4489,7 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) {
for (size_t i = 0; i < primary_surfaces.size(); ++i) {
std::unique_ptr<SurfaceLayerImpl> child =
SurfaceLayerImpl::Create(host_impl_->active_tree(), i + 6);
- child->SetPosition(gfx::PointF(25.f * i, 0.f));
+ child->test_properties()->position = gfx::PointF(25.f * i, 0.f);
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
child->SetRange(
@@ -4930,7 +4931,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
auto* layer =
static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
// Ensure visible_layer_rect for layer is empty.
- layer->SetPosition(gfx::PointF(100.f, 100.f));
+ layer->test_properties()->position = gfx::PointF(100.f, 100.f);
layer->SetBounds(gfx::Size(10, 10));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -4949,7 +4950,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_TRUE(layer->visible_layer_rect().IsEmpty());
// Ensure visible_layer_rect for layer is not empty
- layer->SetPosition(gfx::PointF());
+ layer->test_properties()->position = gfx::PointF();
layer->NoteLayerPropertyChanged();
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -5548,7 +5549,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size));
scrollbar->SetTouchActionRegion(touch_action_region);
scrollbar->SetCurrentPos(0);
- scrollbar->SetPosition(gfx::PointF(0, 35));
+ scrollbar->test_properties()->position = gfx::PointF(0, 35);
host_impl_->active_tree()
->InnerViewportContainerLayer()
->test_properties()
@@ -5816,27 +5817,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsPushUnsentRatio) {
ASSERT_EQ(0, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
}
-// Test that if only the browser controls are scrolled, we shouldn't request a
-// commit.
-TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsDontTriggerCommit) {
- SetupBrowserControlsAndScrollLayerWithVirtualViewport(
- gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
- DrawFrame();
-
- // Show browser controls
- EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
-
- // Scroll 25px to hide browser controls
- gfx::Vector2dF scroll_delta(0.f, 25.f);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
- host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- EXPECT_FALSE(did_request_commit_);
-}
-
// Test that if a scrollable sublayer doesn't consume the scroll,
// browser controls should hide when scrolling down.
TEST_F(LayerTreeHostImplBrowserControlsTest,
@@ -5859,7 +5839,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
child->SetScrollable(sub_content_layer_size);
child->SetElementId(LayerIdToElementIdForTesting(child->id()));
child->SetBounds(sub_content_size);
- child->SetPosition(gfx::PointF());
+ child->test_properties()->position = gfx::PointF();
child->SetDrawsContent(true);
child->test_properties()->is_container_for_fixed_position_layers = true;
@@ -6402,7 +6382,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
std::unique_ptr<LayerImpl> content_layer =
LayerImpl::Create(host_impl_->active_tree(), 11);
content_layer->SetDrawsContent(true);
- content_layer->SetPosition(gfx::PointF());
+ content_layer->test_properties()->position = gfx::PointF();
content_layer->SetBounds(contents_size);
LayerImpl* scroll_container_layer =
@@ -6413,7 +6393,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
scroll_layer->SetScrollable(surface_size);
scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
scroll_layer->SetBounds(contents_size);
- scroll_layer->SetPosition(gfx::PointF());
+ scroll_layer->test_properties()->position = gfx::PointF();
scroll_layer->test_properties()->AddChild(std::move(content_layer));
scroll_container_layer->test_properties()->AddChild(std::move(scroll_layer));
@@ -6518,8 +6498,8 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
gfx::Size surface_size(10, 10);
std::unique_ptr<LayerImpl> content_layer =
CreateScrollableLayer(1, surface_size);
- content_layer->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
+ content_layer->test_properties()->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
// Note: we can use the same clip layer for both since both calls to
// CreateScrollableLayer() use the same surface size.
@@ -8134,12 +8114,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
host_impl_->active_tree()
->InnerViewportScrollLayer()
- ->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kThreadedScrollingDisabled);
+ ->test_properties()
+ ->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kThreadedScrollingDisabled;
host_impl_->active_tree()
->OuterViewportScrollLayer()
- ->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kThreadedScrollingDisabled);
+ ->test_properties()
+ ->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kThreadedScrollingDisabled;
host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -8196,8 +8178,10 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) {
inner_scroll_layer->test_properties()->AddChild(std::move(scroll));
// Move the outer viewport layer away so that scrolls won't target it.
- host_impl_->active_tree()->OuterViewportContainerLayer()->SetPosition(
- gfx::PointF(400, 400));
+ host_impl_->active_tree()
+ ->OuterViewportContainerLayer()
+ ->test_properties()
+ ->position = gfx::PointF(400, 400);
layer_tree_impl->BuildPropertyTreesForTesting();
@@ -8557,8 +8541,11 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) {
// By default, no main thread scrolling reasons should exist.
LayerImpl* scroll_layer =
host_impl_->active_tree()->InnerViewportScrollLayer();
+ ScrollNode* scroll_node =
+ host_impl_->active_tree()->property_trees()->scroll_tree.Node(
+ scroll_layer->scroll_tree_index());
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
- scroll_layer->main_thread_scrolling_reasons());
+ scroll_node->main_thread_scrolling_reasons);
DrawFrame();
@@ -8678,7 +8665,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
host_impl_->active_tree(), 2, host_impl_->resource_provider()));
auto* layer1 =
static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]);
- layer1->SetPosition(gfx::PointF(2.f, 2.f));
+ layer1->test_properties()->position = gfx::PointF(2.f, 2.f);
TestFrameData frame;
@@ -8731,7 +8718,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
host_impl_->active_tree(), 3, host_impl_->resource_provider()));
auto* layer2 = static_cast<BlendStateCheckLayer*>(
layer1->test_properties()->children[0]);
- layer2->SetPosition(gfx::PointF(4.f, 4.f));
+ layer2->test_properties()->position = gfx::PointF(4.f, 4.f);
// 2 opaque layers, drawn without blending.
layer1->SetContentsOpaque(true);
@@ -8958,10 +8945,10 @@ TEST_F(LayerTreeHostImplTest, MayContainVideo) {
EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
// Move the video layer so it goes beyond the root.
- video_layer->SetPosition(gfx::PointF(100.f, 100.f));
+ video_layer->test_properties()->position = gfx::PointF(100.f, 100.f);
EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
- video_layer->SetPosition(gfx::PointF(0.f, 0.f));
+ video_layer->test_properties()->position = gfx::PointF(0.f, 0.f);
video_layer->NoteLayerPropertyChanged();
EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
}
@@ -9005,7 +8992,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
// Expect no gutter rects.
void TestLayerCoversFullViewport() {
gfx::Rect layer_rect(viewport_size_);
- child_->SetPosition(gfx::PointF(layer_rect.origin()));
+ child_->test_properties()->position = gfx::PointF(layer_rect.origin());
child_->SetBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -9026,7 +9013,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
// Expect fullscreen gutter rect.
void SetUpEmptylayer() {
gfx::Rect layer_rect(0, 0, 0, 0);
- child_->SetPosition(gfx::PointF(layer_rect.origin()));
+ child_->test_properties()->position = gfx::PointF(layer_rect.origin());
child_->SetBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -9063,7 +9050,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
// Expect four surrounding gutter rects.
void SetUpLayerInMiddleOfViewport() {
gfx::Rect layer_rect(500, 500, 200, 200);
- child_->SetPosition(gfx::PointF(layer_rect.origin()));
+ child_->test_properties()->position = gfx::PointF(layer_rect.origin());
child_->SetBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -9101,7 +9088,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
void SetUpLayerIsLargerThanViewport() {
gfx::Rect layer_rect(viewport_size_.width() + 10,
viewport_size_.height() + 10);
- child_->SetPosition(gfx::PointF(layer_rect.origin()));
+ child_->test_properties()->position = gfx::PointF(layer_rect.origin());
child_->SetBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -9315,7 +9302,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
root->test_properties()->force_render_surface = true;
std::unique_ptr<LayerImpl> child =
FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
- child->SetPosition(gfx::PointF(12.f, 13.f));
+ child->test_properties()->position = gfx::PointF(12.f, 13.f);
child->SetBounds(gfx::Size(14, 15));
child->SetDrawsContent(true);
root->SetBounds(gfx::Size(500, 500));
@@ -9344,7 +9331,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
->root_layer_for_testing()
->test_properties()
->children[0]
- ->SetPosition(gfx::PointF());
+ ->test_properties()
+ ->position = gfx::PointF();
layer_tree_host_impl->active_tree()
->root_layer_for_testing()
->test_properties()
@@ -9425,10 +9413,11 @@ class FakeLayerWithQuads : public LayerImpl {
};
TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
- auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
- viz::TestGLES2Interface* gl = gl_owned.get();
+ scoped_refptr<viz::TestContextProvider> context_provider =
+ viz::TestContextProvider::Create();
+ viz::TestSharedImageInterface* sii = context_provider->SharedImageInterface();
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink(
- FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
+ FakeLayerTreeFrameSink::Create3d(context_provider));
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
std::unique_ptr<LayerImpl> root_layer =
@@ -9449,19 +9438,19 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
- EXPECT_GT(gl->NumTextures(), 0u);
+ EXPECT_GT(sii->shared_image_count(), 0u);
// Kill the layer tree.
host_impl_->active_tree()->DetachLayers();
// There should be no textures left in use after.
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
}
@@ -9561,7 +9550,7 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest {
TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
std::unique_ptr<SolidColorLayerImpl> root =
SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetBackgroundColor(SK_ColorRED);
@@ -9570,7 +9559,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
// Child layer is in the bottom right corner.
std::unique_ptr<SolidColorLayerImpl> child =
SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
- child->SetPosition(gfx::PointF(9.f, 9.f));
+ child->test_properties()->position = gfx::PointF(9.f, 9.f);
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
child->SetBackgroundColor(SK_ColorRED);
@@ -9949,58 +9938,56 @@ TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) {
}
TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
- auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
- viz::TestGLES2Interface* gl = gl_owned.get();
-
- std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink =
- FakeLayerTreeFrameSink::Create3d(std::move(gl_owned));
- CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
+ auto test_context_provider = viz::TestContextProvider::Create();
+ viz::TestSharedImageInterface* sii =
+ test_context_provider->SharedImageInterface();
+ CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::Create3d(
+ std::move(test_context_provider)));
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
UIResourceId ui_resource_id = 1;
bool is_opaque = false;
UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, gl->NumTextures());
+ EXPECT_EQ(1u, sii->shared_image_count());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
// Multiple requests with the same id is allowed. The previous texture is
// deleted.
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, gl->NumTextures());
+ EXPECT_EQ(1u, sii->shared_image_count());
viz::ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id2);
EXPECT_NE(id1, id2);
// Deleting invalid UIResourceId is allowed and does not change state.
host_impl_->DeleteUIResource(-1);
- EXPECT_EQ(1u, gl->NumTextures());
+ EXPECT_EQ(1u, sii->shared_image_count());
// Should return zero for invalid UIResourceId. Number of textures should
// not change.
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
- EXPECT_EQ(1u, gl->NumTextures());
+ EXPECT_EQ(1u, sii->shared_image_count());
host_impl_->DeleteUIResource(ui_resource_id);
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
// Should not change state for multiple deletion on one UIResourceId
host_impl_->DeleteUIResource(ui_resource_id);
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
}
TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
- auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
- gl_owned->set_support_compressed_texture_etc1(true);
- viz::TestGLES2Interface* gl = gl_owned.get();
-
- CreateHostImpl(DefaultSettings(),
- FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
+ auto test_context_provider = viz::TestContextProvider::Create();
+ viz::TestSharedImageInterface* sii =
+ test_context_provider->SharedImageInterface();
+ CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::Create3d(
+ std::move(test_context_provider)));
- EXPECT_EQ(0u, gl->NumTextures());
+ EXPECT_EQ(0u, sii->shared_image_count());
gfx::Size size(4, 4);
// SkImageInfo has no support for ETC1. The |info| below contains the right
@@ -10013,7 +10000,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
UIResourceBitmap bitmap(std::move(pixel_ref), size);
UIResourceId ui_resource_id = 1;
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, gl->NumTextures());
+ EXPECT_EQ(1u, sii->shared_image_count());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
}
@@ -10155,7 +10142,7 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
occluder_layer->SetDrawsContent(true);
occluder_layer->SetBounds(content_size);
- occluder_layer->SetPosition(gfx::PointF());
+ occluder_layer->test_properties()->position = gfx::PointF();
// The parent of the occluder is *above* the scroller.
page_scale_layer->test_properties()->AddChild(std::move(occluder_layer));
@@ -10187,7 +10174,7 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
occluder_layer->SetDrawsContent(true);
occluder_layer->SetBounds(content_size);
- occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f));
+ occluder_layer->test_properties()->position = gfx::PointF(-10.f, -10.f);
int child_scroll_clip_layer_id = 7;
std::unique_ptr<LayerImpl> child_scroll_clip =
@@ -10197,7 +10184,7 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
std::unique_ptr<LayerImpl> child_scroll =
CreateScrollableLayer(child_scroll_layer_id, content_size);
- child_scroll->SetPosition(gfx::PointF(10.f, 10.f));
+ child_scroll->test_properties()->position = gfx::PointF(10.f, 10.f);
child_scroll->test_properties()->AddChild(std::move(occluder_layer));
child_scroll_clip->test_properties()->AddChild(std::move(child_scroll));
@@ -10253,7 +10240,7 @@ class LayerTreeHostImplLatencyInfoTest : public LayerTreeHostImplTest {
std::unique_ptr<SolidColorLayerImpl> root =
SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
@@ -10378,7 +10365,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
int root_layer_id = 1;
std::unique_ptr<SolidColorLayerImpl> root =
SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
@@ -10426,7 +10413,7 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) {
int root_layer_id = 1;
std::unique_ptr<SolidColorLayerImpl> root =
SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
@@ -10827,7 +10814,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation());
EXPECT_TRUE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
- EXPECT_FALSE(did_request_commit_);
+ EXPECT_TRUE(did_request_commit_);
// The browser controls should properly animate until finished, despite the
// scroll offset being at the origin.
@@ -10913,7 +10900,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation());
EXPECT_TRUE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
- EXPECT_FALSE(did_request_commit_);
+ EXPECT_TRUE(did_request_commit_);
// Animate the browser controls to the limit.
viz::BeginFrameArgs begin_frame_args = viz::CreateBeginFrameArgsForTesting(
@@ -11049,7 +11036,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
{
std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
clip->SetBounds(root_layer_size);
- clip->SetPosition(gfx::PointF());
+ clip->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
scroll->SetBounds(scroll_content_size);
@@ -11125,7 +11112,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
inner_scroll->SetElementId(
LayerIdToElementIdForTesting(inner_scroll->id()));
inner_scroll->SetBounds(outer_viewport);
- inner_scroll->SetPosition(gfx::PointF());
+ inner_scroll->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> outer_clip =
LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
@@ -11143,12 +11130,12 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
->scroll_tree.UpdateScrollOffsetBaseForTesting(
outer_scroll->element_id(), gfx::ScrollOffset());
outer_scroll->SetBounds(content_size);
- outer_scroll->SetPosition(gfx::PointF());
+ outer_scroll->test_properties()->position = gfx::PointF();
std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetPosition(gfx::PointF());
+ contents->test_properties()->position = gfx::PointF();
outer_scroll->test_properties()->AddChild(std::move(contents));
outer_clip->test_properties()->AddChild(std::move(outer_scroll));
@@ -13224,8 +13211,8 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
host_impl_->active_tree()->OuterViewportScrollLayer();
if (main_thread_scrolling) {
- root_scroll->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
+ root_scroll->test_properties()->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
}
// scrollbar_1 on root scroll.
@@ -13240,7 +13227,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1));
scrollbar_1->SetTouchActionRegion(touch_action_region);
scrollbar_1->SetCurrentPos(0);
- scrollbar_1->SetPosition(gfx::PointF(0, 0));
+ scrollbar_1->test_properties()->position = gfx::PointF(0, 0);
host_impl_->active_tree()
->InnerViewportContainerLayer()
->test_properties()
@@ -13331,7 +13318,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
true, true);
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
- child->SetPosition(gfx::PointF(50, 50));
+ child->test_properties()->position = gfx::PointF(50, 50);
child->SetBounds(child_layer_size);
child->SetDrawsContent(true);
child->SetScrollable(gfx::Size(100, 100));
@@ -13339,15 +13326,15 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
ElementId child_element_id = child->element_id();
if (main_thread_scrolling) {
- child->set_main_thread_scrolling_reasons(
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
+ child->test_properties()->main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
}
scrollbar_2->SetScrollElementId(child_element_id);
scrollbar_2->SetDrawsContent(true);
scrollbar_2->SetBounds(scrollbar_size_2);
scrollbar_2->SetCurrentPos(0);
- scrollbar_2->SetPosition(gfx::PointF(0, 0));
+ scrollbar_2->test_properties()->position = gfx::PointF(0, 0);
child->test_properties()->AddChild(std::move(scrollbar_2));
root_scroll->test_properties()->AddChild(std::move(child));
@@ -13417,22 +13404,22 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
// Capture scrollbar_1, then move mouse to scrollbar_2's layer, should post an
// event to fade out scrollbar_1.
scrollbar_1_animation_controller->DidScrollUpdate();
- animation_task_ = base::Closure();
+ animation_task_.Reset();
host_impl_->MouseDown();
host_impl_->MouseMoveAt(gfx::Point(60, 50));
host_impl_->MouseUp();
- EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ EXPECT_FALSE(animation_task_.is_null());
// Near scrollbar_1, then mouse down and up, should not post an event to fade
// out scrollbar_1.
host_impl_->MouseMoveAt(gfx::Point(40, 150));
- animation_task_ = base::Closure();
+ animation_task_.Reset();
host_impl_->MouseDown();
host_impl_->MouseUp();
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.is_null());
// Near scrollbar_1, then mouse down and unregister
// scrollbar_2_animation_controller, then mouse up should not cause crash.
@@ -13804,7 +13791,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
const int root_layer_id = 1;
std::unique_ptr<SolidColorLayerImpl> root =
SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
- root->SetPosition(gfx::PointF());
+ root->test_properties()->position = gfx::PointF();
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
@@ -13941,7 +13928,7 @@ TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) {
std::unique_ptr<SurfaceLayerImpl> surface_child =
SurfaceLayerImpl::Create(host_impl_->active_tree(), 3);
- surface_child->SetPosition(gfx::PointF(50, 50));
+ surface_child->test_properties()->position = gfx::PointF(50, 50);
surface_child->SetBounds(gfx::Size(100, 100));
surface_child->SetDrawsContent(true);
surface_child->SetSurfaceHitTestable(true);
@@ -13980,10 +13967,10 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) {
host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768));
- intermediate_layer->SetPosition(gfx::PointF(200, 300));
+ intermediate_layer->test_properties()->position = gfx::PointF(200, 300);
intermediate_layer->SetBounds(gfx::Size(200, 200));
- surface_child1->SetPosition(gfx::PointF(50, 50));
+ surface_child1->test_properties()->position = gfx::PointF(50, 50);
surface_child1->SetBounds(gfx::Size(100, 100));
gfx::Transform rotate;
rotate.Rotate(45);
@@ -13991,12 +13978,12 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) {
surface_child1->SetDrawsContent(true);
surface_child1->SetSurfaceHitTestable(true);
- surface_child2->SetPosition(gfx::PointF(450, 300));
+ surface_child2->test_properties()->position = gfx::PointF(450, 300);
surface_child2->SetBounds(gfx::Size(100, 100));
surface_child2->SetDrawsContent(true);
surface_child2->SetSurfaceHitTestable(true);
- overlapping_layer->SetPosition(gfx::PointF(500, 350));
+ overlapping_layer->test_properties()->position = gfx::PointF(500, 350);
overlapping_layer->SetBounds(gfx::Size(200, 200));
overlapping_layer->SetDrawsContent(true);
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 9c800d93374..954455ffa50 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -319,7 +319,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest
gpu_mailbox.SetName(
reinterpret_cast<const int8_t*>(name_stream.str().c_str()));
std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
+ viz::SingleReleaseCallback::Create(base::BindOnce(
&BrowserCompositorInvalidateLayerTreePerfTest::ReleaseMailbox,
base::Unretained(this)));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index 39499795006..ae1fb7651df 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -4,6 +4,7 @@
#include <stdint.h>
+#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/layers/picture_image_layer.h"
#include "cc/layers/solid_color_layer.h"
@@ -55,7 +56,7 @@ SkColor kCSSTestColors[] = {
0x00000000 // transparent
};
-const int kCSSTestColorsCount = arraysize(kCSSTestColors);
+const int kCSSTestColorsCount = base::size(kCSSTestColors);
using RenderPassOptions = uint32_t;
const uint32_t kUseMasks = 1 << 0;
@@ -310,7 +311,9 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
background->AddChild(green_lane);
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
+ gfx::RectF backdrop_filter_bounds;
green_lane->SetBackdropFilters(filters);
+ green_lane->SetBackdropFilterBounds(backdrop_filter_bounds);
green_lane->SetBlendMode(current_blend_mode());
SkBitmap expected;
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 67e3b25aefc..22c12b0c521 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -36,6 +36,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlur) {
filters.Append(FilterOperation::CreateBlurFilter(
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackdropFilters(filters);
+ gfx::RectF backdrop_filter_bounds(gfx::SizeF(blur->bounds()));
+ blur->SetBackdropFilterBounds(backdrop_filter_bounds);
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
// Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
@@ -77,6 +79,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) {
filters.Append(FilterOperation::CreateBlurFilter(
5.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackdropFilters(filters);
+ gfx::RectF backdrop_filter_bounds(gfx::SizeF(blur->bounds()));
+ blur->SetBackdropFilterBounds(backdrop_filter_bounds);
#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
@@ -143,6 +147,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOffAxis) {
filters.Append(FilterOperation::CreateBlurFilter(
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackdropFilters(filters);
+ // TODO(916311): Fix clipping for 3D transformed elements.
+ blur->SetBackdropFilterBounds(gfx::RectF());
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -420,6 +426,7 @@ class ImageScaledBackdropFilter : public LayerTreeHostFiltersPixelTest {
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
filter->SetBackdropFilters(filters);
+ filter->SetBackdropFilterBounds(gfx::RectF());
#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -481,22 +488,27 @@ class ImageBackdropFilter : public LayerTreeHostFiltersPixelTest {
background->AddChild(layer);
// Add a slightly transparent blue layer.
- scoped_refptr<SolidColorLayer> filter =
- CreateSolidColorLayer(gfx::Rect(100, 0, 100, 200), SK_ColorBLUE);
- filter->SetOpacity(0.137f);
+ SkColor transparent_blue = SkColorSetARGB(0x23, 0x00, 0x00, 0xFF);
+ scoped_refptr<SolidColorLayer> filter_layer =
+ CreateSolidColorLayer(gfx::Rect(100, 0, 100, 200), transparent_blue);
// Add some rotation so that we can see that it blurs only under the layer.
gfx::Transform transform_filter;
transform_filter.RotateAboutZAxis(10.0);
- filter->SetTransform(transform_filter);
-
- background->AddChild(filter);
+ filter_layer->SetTransform(transform_filter);
// Add a blur filter to the blue layer.
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(
5.0f, SkBlurImageFilter::kClamp_TileMode));
- filter->SetBackdropFilters(filters);
+ filter_layer->SetBackdropFilters(filters);
+ // TODO(916311): Adding filter bounds here should work, but it clips
+ // the corner of the red box.
+ // gfx::RectF backdrop_filter_bounds(gfx::SizeF(filter_layer->bounds()));
+ gfx::RectF backdrop_filter_bounds;
+ filter_layer->SetBackdropFilterBounds(backdrop_filter_bounds);
+
+ background->AddChild(filter_layer);
// Allow some fuzziness so that this doesn't fail when Skia makes minor
// changes to blur or rectangle rendering.
@@ -613,6 +625,8 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
border_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
border_edge_zoom->SetBackdropFilters(border_filters);
+ gfx::RectF border_filter_bounds(gfx::SizeF(border_edge_zoom->bounds()));
+ border_edge_zoom->SetBackdropFilterBounds(border_filter_bounds);
root->AddChild(border_edge_zoom);
// Test a zoom that extends past the edge of the screen.
@@ -622,6 +636,8 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
top_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
top_edge_zoom->SetBackdropFilters(top_filters);
+ gfx::RectF top_filter_bounds(gfx::SizeF(top_edge_zoom->bounds()));
+ top_edge_zoom->SetBackdropFilterBounds(top_filter_bounds);
root->AddChild(top_edge_zoom);
// Test a zoom that is fully within the screen.
@@ -631,6 +647,8 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
mid_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
contained_zoom->SetBackdropFilters(mid_filters);
+ gfx::RectF mid_filter_bounds(gfx::SizeF(contained_zoom->bounds()));
+ contained_zoom->SetBackdropFilterBounds(mid_filter_bounds);
root->AddChild(contained_zoom);
#if defined(OS_WIN)
@@ -1074,6 +1092,7 @@ class BackdropFilterWithDeviceScaleFactorTest
filters.Append(FilterOperation::CreateReferenceFilter(
sk_make_sp<OffsetPaintFilter>(0, 80, nullptr)));
filtered->SetBackdropFilters(filters);
+ filtered->SetBackdropFilterBounds(gfx::RectF());
root->AddChild(filtered);
// This should appear as a grid of 4 100x100 squares which are:
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 4639cb3cd2e..36726cc817e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -4,6 +4,7 @@
#include <stddef.h>
+#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_image_layer.h"
@@ -296,7 +297,9 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
+ gfx::RectF backdrop_filter_bounds;
blur->SetBackdropFilters(filters);
+ blur->SetBackdropFilterBounds(backdrop_filter_bounds);
gfx::Size mask_bounds(100, 100);
CircleContentLayerClient mask_client(mask_bounds);
@@ -493,7 +496,7 @@ class LayerTreeHostMaskAsBlendingPixelTest
for (int j = 0; j < (bounds.height() + grid_size - 1) / grid_size; j++) {
for (int i = 0; i < (bounds.width() + grid_size - 1) / grid_size; i++) {
PaintFlags flags;
- flags.setColor(test_colors[(i + j * 3) % arraysize(test_colors)]);
+ flags.setColor(test_colors[(i + j * 3) % base::size(test_colors)]);
display_list->push<DrawRectOp>(
SkRect::MakeXYWH(i * grid_size, j * grid_size, grid_size,
grid_size),
@@ -756,6 +759,8 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
picture_horizontal->SetBackdropFilters(filters);
+ gfx::RectF backdrop_filter_bounds;
+ picture_horizontal->SetBackdropFilterBounds(backdrop_filter_bounds);
background->AddChild(picture_vertical);
background->AddChild(picture_horizontal);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index 17484e50c76..d6e39e34b3e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -125,12 +125,13 @@ class LayerTreeHostReadbackPixelTest
gpu::Mailbox mailbox = result->GetTextureResult()->mailbox;
gpu::SyncToken sync_token = result->GetTextureResult()->sync_token;
+ gfx::ColorSpace color_space = result->GetTextureResult()->color_space;
EXPECT_EQ(result->GetTextureResult()->color_space, output_color_space_);
std::unique_ptr<viz::SingleReleaseCallback> release_callback =
result->TakeTextureOwnership();
const SkBitmap bitmap =
- CopyMailboxToBitmap(result->size(), mailbox, sync_token);
+ CopyMailboxToBitmap(result->size(), mailbox, sync_token, color_space);
release_callback->Run(gpu::SyncToken(), false);
ReadbackResultAsBitmap(std::make_unique<viz::CopyOutputSkBitmapResult>(
diff --git a/chromium/cc/trees/layer_tree_host_single_thread_client.h b/chromium/cc/trees/layer_tree_host_single_thread_client.h
index a648ed5a45e..f2ce8e18597 100644
--- a/chromium/cc/trees/layer_tree_host_single_thread_client.h
+++ b/chromium/cc/trees/layer_tree_host_single_thread_client.h
@@ -11,11 +11,9 @@ namespace cc {
class LayerTreeHostSingleThreadClient {
public:
- // Request that the client schedule a composite.
+ // Request that the client schedule a composite. For tests using single thread
+ // without a scheduler.
virtual void RequestScheduleComposite() {}
- // Request that the client schedule a composite now, and calculate appropriate
- // delay for potential future frame.
- virtual void RequestScheduleAnimation() {}
// Called whenever the begin frame interval changes. This interval can be used
// for animations.
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 97e682c6c82..fedcb0baaf3 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -230,7 +230,7 @@ class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest {
void NextStep() {
// The MainFrame request is cleared once a MainFrame happens.
- EXPECT_FALSE(layer_tree_host()->RequestedMainFramePending());
+ EXPECT_FALSE(layer_tree_host()->RequestedMainFramePendingForTesting());
switch (layer_tree_host()->SourceFrameNumber()) {
case 0:
ADD_FAILURE()
@@ -250,7 +250,7 @@ class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest {
return;
}
// SetNeeds{Animate,UpdateLayers,Commit}() will mean a MainFrame is pending.
- EXPECT_TRUE(layer_tree_host()->RequestedMainFramePending());
+ EXPECT_TRUE(layer_tree_host()->RequestedMainFramePendingForTesting());
}
void AfterTest() override {}
@@ -3412,10 +3412,6 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
impl->active_tree()->LayerById(child_layer_->id()));
- // Positions remain in layout pixels.
- EXPECT_EQ(gfx::PointF(), root->position());
- EXPECT_EQ(gfx::PointF(2.f, 2.f), child->position());
-
// Compute all the layer transforms for the frame.
LayerTreeHostImpl::FrameData frame_data;
impl->PrepareToDraw(&frame_data);
@@ -4114,7 +4110,7 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
base::SingleThreadTaskRunner* task_runner,
bool synchronous_composite,
double refresh_rate,
- base::Closure invalidate_callback)
+ base::RepeatingClosure invalidate_callback)
: TestLayerTreeFrameSink(std::move(compositor_context_provider),
std::move(worker_context_provider),
gpu_memory_buffer_manager,
@@ -4135,7 +4131,7 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
}
private:
- const base::Closure invalidate_callback_;
+ const base::RepeatingClosure invalidate_callback_;
};
class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
@@ -4152,7 +4148,7 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider)
override {
- auto on_draw_callback = base::Bind(
+ auto on_draw_callback = base::BindRepeating(
&LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
CallOnDraw,
base::Unretained(this));
@@ -4300,32 +4296,32 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest {
}
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- auto* context = static_cast<viz::TestContextProvider*>(
- impl->layer_tree_frame_sink()->context_provider())
- ->TestContextGL();
+ auto* sii = static_cast<viz::TestContextProvider*>(
+ impl->layer_tree_frame_sink()->context_provider())
+ ->SharedImageInterface();
int frame = impl->active_tree()->source_frame_number();
switch (frame) {
case 0:
- ASSERT_EQ(0u, context->NumTextures());
+ ASSERT_EQ(0u, sii->shared_image_count());
break;
case 1:
// Created two textures.
- ASSERT_EQ(2u, context->NumTextures());
+ ASSERT_EQ(2u, sii->shared_image_count());
break;
case 2:
// One texture left after one deletion.
- ASSERT_EQ(1u, context->NumTextures());
+ ASSERT_EQ(1u, sii->shared_image_count());
break;
case 3:
// Resource manager state should not change when delete is called on an
// invalid id.
- ASSERT_EQ(1u, context->NumTextures());
+ ASSERT_EQ(1u, sii->shared_image_count());
break;
case 4:
// Creation after deletion: two more creates should total up to
// three textures.
- ASSERT_EQ(3u, context->NumTextures());
+ ASSERT_EQ(3u, sii->shared_image_count());
break;
}
}
@@ -5352,10 +5348,10 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
host_impl->SetTreeActivationCallback(
enable
- ? base::Bind(
+ ? base::BindRepeating(
&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
base::Unretained(this))
- : base::Closure());
+ : base::RepeatingClosure());
}
void ActivationCallback() { ++callback_count_; }
@@ -5899,10 +5895,10 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest {
void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
host_impl->SetTreeActivationCallback(
- enable
- ? base::Bind(&LayerTreeHostTestKeepSwapPromise::ActivationCallback,
- base::Unretained(this))
- : base::Closure());
+ enable ? base::BindRepeating(
+ &LayerTreeHostTestKeepSwapPromise::ActivationCallback,
+ base::Unretained(this))
+ : base::RepeatingClosure());
}
void DisplayDidDrawAndSwapOnThread() override {
@@ -6016,10 +6012,10 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest {
void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
host_impl->SetTreeActivationCallback(
- enable ? base::Bind(
+ enable ? base::BindRepeating(
&LayerTreeHostTestKeepSwapPromiseMFBA::ActivationCallback,
base::Unretained(this))
- : base::Closure());
+ : base::RepeatingClosure());
}
void DisplayDidDrawAndSwapOnThread() override {
@@ -7849,55 +7845,15 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
-// Makes sure that presentation-time requests are correctly propagated to the
-// frame's metadata.
-class LayerTreeHostTestPresentationTimeRequest : public LayerTreeHostTest {
+// Tests that a presentation-timestamps are received for a frame.
+class LayerTreeHostTestPresentationTime : public LayerTreeHostTest {
protected:
void BeginTest() override {
- layer_tree_host()->RequestPresentationTimeForNextFrame(base::DoNothing());
PostSetNeedsCommitToMainThread();
}
void DisplayReceivedCompositorFrameOnThread(
const viz::CompositorFrame& frame) override {
- EXPECT_TRUE(frame.metadata.request_presentation_feedback);
- EndTest();
- }
-
- void AfterTest() override {}
-};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTimeRequest);
-
-// A SwapPromise that turns on |request_presentation_feedback| during
-// WillSwap().
-class RequestPresentationFeedbackSwapPromise : public SwapPromise {
- public:
- RequestPresentationFeedbackSwapPromise() = default;
- ~RequestPresentationFeedbackSwapPromise() override = default;
-
- // SwapPromise:
- void DidActivate() override {}
- void WillSwap(viz::CompositorFrameMetadata* metadata) override {
- metadata->request_presentation_feedback = true;
- }
- void DidSwap() override {}
- void DidNotSwap(DidNotSwapReason reason) override {}
- int64_t TraceId() const override { return 0; }
-};
-
-// Tests that a presentation-token can be requested during swap.
-class LayerTreeHostTestPresentationTimeRequestDuringSwap
- : public LayerTreeHostTest {
- protected:
- void BeginTest() override {
- layer_tree_host()->QueueSwapPromise(
- std::make_unique<RequestPresentationFeedbackSwapPromise>());
- PostSetNeedsCommitToMainThread();
- }
-
- void DisplayReceivedCompositorFrameOnThread(
- const viz::CompositorFrame& frame) override {
- EXPECT_TRUE(frame.metadata.request_presentation_feedback);
frame_token_ = frame.metadata.frame_token;
}
@@ -7914,8 +7870,7 @@ class LayerTreeHostTestPresentationTimeRequestDuringSwap
private:
uint32_t frame_token_ = 0;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostTestPresentationTimeRequestDuringSwap);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTime);
// Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink.
class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
@@ -7970,15 +7925,8 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest {
allocator_.GetCurrentLocalSurfaceIdAllocation();
EXPECT_TRUE(child_allocator_.UpdateFromParent(
allocator_.GetCurrentLocalSurfaceIdAllocation()));
- child_allocator_.GenerateId();
- child_local_surface_id_allocation_ =
- child_allocator_.GetCurrentLocalSurfaceIdAllocation();
- EXPECT_NE(expected_local_surface_id_allocation_,
- child_local_surface_id_allocation_);
PostSetLocalSurfaceIdAllocationToMainThread(
expected_local_surface_id_allocation_);
- PostSetLocalSurfaceIdAllocationToMainThread(
- child_local_surface_id_allocation_);
}
DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
@@ -7989,6 +7937,26 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest {
EXPECT_EQ(
expected_local_surface_id_allocation_,
host_impl->active_tree()->local_surface_id_allocation_from_parent());
+
+ // This initial test setup triggers a commit and subsequent draw. Upon the
+ // first draw, enqueue the second portion of the test. The newly pushed id,
+ // with an advanced child sequence number, but no change in parent sequence,
+ // should not trigger a commit. If it does, then PrepareToDrawOnThread will
+ // be called a second time, and the expectation upon viz::LocalSurfaceId
+ // will fail. We do not assert on frame number, as that interferes with
+ // returning from this method. We do not just have an expectation either,
+ // as then we would continuously increment that child sequence until the
+ // test times out.
+ if (!host_impl->active_tree()->source_frame_number()) {
+ child_allocator_.GenerateId();
+ child_local_surface_id_allocation_ =
+ child_allocator_.GetCurrentLocalSurfaceIdAllocation();
+ EXPECT_NE(expected_local_surface_id_allocation_,
+ child_local_surface_id_allocation_);
+ PostSetLocalSurfaceIdAllocationToMainThread(
+ child_local_surface_id_allocation_);
+ }
+
return draw_result;
}
@@ -8344,9 +8312,9 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)),
SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
SkMatrix::I(), PaintImage::kDefaultFrameIndex);
- auto callback =
- base::Bind(&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
- base::Unretained(this));
+ auto callback = base::BindRepeating(
+ &LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
+ base::Unretained(this));
// Schedule the decode twice for the same image.
layer_tree_host()->QueueImageDecode(image_.paint_image(), callback);
layer_tree_host()->QueueImageDecode(image_.paint_image(), callback);
@@ -8401,10 +8369,10 @@ class LayerTreeHostTestQueueImageDecodeNonLazy : public LayerTreeHostTest {
.set_image(SkImage::MakeFromBitmap(bitmap_),
PaintImage::GetNextContentId())
.TakePaintImage();
- auto callback = base::Bind(
+ auto callback = base::BindOnce(
&LayerTreeHostTestQueueImageDecodeNonLazy::ImageDecodeFinished,
base::Unretained(this));
- layer_tree_host()->QueueImageDecode(image, callback);
+ layer_tree_host()->QueueImageDecode(image, std::move(callback));
}
void ImageDecodeFinished(bool decode_succeeded) {
@@ -8476,9 +8444,9 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest {
// that WillReceiveCompositorFrameAck which we PostTask below will be called
// before DidReceiveCompositorFrameAck.
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostTestDiscardAckAfterRelease::
- WillReceiveCompositorFrameAck,
- base::Unretained(this)));
+ FROM_HERE, base::BindOnce(&LayerTreeHostTestDiscardAckAfterRelease::
+ WillReceiveCompositorFrameAck,
+ base::Unretained(this)));
}
void WillReceiveCompositorFrameAck() {
@@ -8505,8 +8473,8 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest {
// before we are in CheckFrameAck.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTestDiscardAckAfterRelease::CheckFrameAck,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostTestDiscardAckAfterRelease::CheckFrameAck,
+ base::Unretained(this)));
}
void DidReceiveCompositorFrameAck() override { received_ack_ = true; }
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index d50a4cce305..dd854fb5e02 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1061,8 +1061,7 @@ class LayerTreeHostPresentationDuringAnimation
void DisplayReceivedCompositorFrameOnThread(
const viz::CompositorFrame& frame) override {
- if (frame.metadata.request_presentation_feedback)
- received_token_ = frame.metadata.frame_token;
+ received_token_ = frame.metadata.frame_token;
}
void AfterTest() override {
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index a871ac9d1a9..aa7781a0e12 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/layer_impl.h"
@@ -107,6 +108,8 @@ class LayerTreeHostContextTest : public LayerTreeTest {
GL_INNOCENT_CONTEXT_RESET_ARB);
}
+ sii_ = provider->SharedImageInterface();
+
return LayerTreeTest::CreateLayerTreeFrameSink(
renderer_settings, refresh_rate, std::move(provider),
std::move(worker_context_provider));
@@ -162,6 +165,7 @@ class LayerTreeHostContextTest : public LayerTreeTest {
// CreateDisplayLayerTreeFrameSink can both use it on different threads.
base::Lock gl_lock_;
viz::TestGLES2Interface* gl_ = nullptr;
+ viz::TestSharedImageInterface* sii_ = nullptr;
int times_to_fail_create_;
int times_to_lose_during_commit_;
@@ -325,7 +329,7 @@ class LayerTreeHostContextTestLostContextSucceeds
},
};
- if (test_case_ >= arraysize(kTests))
+ if (test_case_ >= base::size(kTests))
return false;
// Make sure that we lost our context at least once in the last test run so
// the test did something.
@@ -932,9 +936,9 @@ class LayerTreeHostContextTestDontUseLostResources
auto resource = viz::TransferableResource::MakeGL(
mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
texture->SetTransferableResource(
- resource, viz::SingleReleaseCallback::Create(
- base::Bind(&LayerTreeHostContextTestDontUseLostResources::
- EmptyReleaseCallback)));
+ resource, viz::SingleReleaseCallback::Create(base::BindOnce(
+ &LayerTreeHostContextTestDontUseLostResources::
+ EmptyReleaseCallback)));
root->AddChild(texture);
scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_);
@@ -1494,7 +1498,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, bool visible) override {
if (!visible) {
// All resources should have been evicted.
- ASSERT_EQ(0u, gl_->NumTextures());
+ ASSERT_EQ(0u, sii_->shared_image_count());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource3_->id()));
@@ -1514,7 +1518,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 1:
// The first two resources should have been created on LTHI after the
// commit.
- ASSERT_EQ(2u, gl_->NumTextures());
+ ASSERT_EQ(2u, sii_->shared_image_count());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1522,7 +1526,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
EXPECT_TRUE(impl->CanDraw());
// Evict all UI resources. This will trigger a commit.
impl->EvictAllUIResources();
- ASSERT_EQ(0u, gl_->NumTextures());
+ ASSERT_EQ(0u, sii_->shared_image_count());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1531,7 +1535,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
break;
case 2:
// The first two resources should have been recreated.
- ASSERT_EQ(2u, gl_->NumTextures());
+ ASSERT_EQ(2u, sii_->shared_image_count());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(2, ui_resource_->resource_create_count);
EXPECT_EQ(1, ui_resource_->lost_resource_count);
@@ -1543,7 +1547,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 3:
// The first resource should have been recreated after visibility was
// restored.
- ASSERT_EQ(2u, gl_->NumTextures());
+ ASSERT_EQ(2u, sii_->shared_image_count());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(3, ui_resource_->resource_create_count);
EXPECT_EQ(2, ui_resource_->lost_resource_count);
@@ -1585,7 +1589,7 @@ class UIResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
case 0:
// The UIResource has been created and a gpu resource made for it.
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
- EXPECT_EQ(1u, gl_->NumTextures());
+ EXPECT_EQ(1u, sii_->shared_image_count());
// Lose the LayerTreeFrameSink connection. The UI resource should
// be replaced and the old texture should be destroyed.
impl->DidLoseLayerTreeFrameSink();
@@ -1594,7 +1598,7 @@ class UIResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
// The UIResource has been recreated, the old texture is not kept
// around.
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
- EXPECT_EQ(1u, gl_->NumTextures());
+ EXPECT_EQ(1u, sii_->shared_image_count());
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(
diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
index b918f70e69a..9fa460e05f9 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -255,11 +255,11 @@ class LayerTreeHostProxyTestCommitWaitsForActivation
switch (impl->sync_tree()->source_frame_number()) {
case 0: {
// This is for case 1 in DidCommit.
- auto unblock = base::Bind(
+ auto unblock = base::BindOnce(
&LayerTreeHostProxyTestCommitWaitsForActivation::UnblockActivation,
base::Unretained(this), impl);
ImplThreadTaskRunner()->PostDelayedTask(
- FROM_HERE, unblock,
+ FROM_HERE, std::move(unblock),
// Use a delay to allow the main frame to start if it would. This
// should cause failures (or flakiness) if we fail to wait for the
// activation before starting the main frame.
@@ -348,13 +348,13 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA
// This is the main frame with SetNextCommitWaitsForActivation().
// Activation is currently blocked for the previous main frame (from the
// case above). We unblock activate to allow this main frame to commit.
- auto unblock =
- base::Bind(&LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting,
- base::Unretained(impl), false);
+ auto unblock = base::BindOnce(
+ &LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting,
+ base::Unretained(impl), false);
// 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.
- ImplThreadTaskRunner()->PostTask(FROM_HERE, unblock);
+ ImplThreadTaskRunner()->PostTask(FROM_HERE, std::move(unblock));
// Once activation completes, we'll begin the commit for frame 1.
break;
}
@@ -376,11 +376,12 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA
// failures (or flakiness) if we fail to wait for the activation before
// starting the main frame.
auto unblock =
- base::Bind(&LayerTreeHostProxyTestCommitWaitsForActivationMFBA::
- UnblockActivation,
- base::Unretained(this), impl);
+ base::BindOnce(&LayerTreeHostProxyTestCommitWaitsForActivationMFBA::
+ UnblockActivation,
+ base::Unretained(this), impl);
ImplThreadTaskRunner()->PostDelayedTask(
- FROM_HERE, unblock, base::TimeDelta::FromMilliseconds(16 * 4));
+ FROM_HERE, std::move(unblock),
+ base::TimeDelta::FromMilliseconds(16 * 4));
}
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index cef1be4927f..f2d96d8bbd5 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -100,8 +100,9 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
initial_scroll_);
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport,
- base::Unretained(this)));
+ base::BindRepeating(
+ &LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport,
+ base::Unretained(this)));
PostSetNeedsCommitToMainThread();
}
@@ -171,7 +172,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
void BeginTest() override {
scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer();
scroll_layer_->SetScrollOffset(initial_scroll_);
- scroll_layer_->set_did_scroll_callback(base::Bind(
+ scroll_layer_->set_did_scroll_callback(base::BindRepeating(
&LayerTreeHostScrollTestScrollMultipleRedraw::DidScrollOuterViewport,
base::Unretained(this)));
PostSetNeedsCommitToMainThread();
@@ -259,7 +260,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
initial_scroll_);
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(
+ base::BindRepeating(
&LayerTreeHostScrollTestScrollAbortedCommit::DidScrollOuterViewport,
base::Unretained(this)));
PostSetNeedsCommitToMainThread();
@@ -579,8 +580,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
child_layer_->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
- base::Unretained(this)));
+ base::BindRepeating(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
+ base::Unretained(this)));
child_layer_->SetElementId(
LayerIdToElementIdForTesting(child_layer_->id()));
child_layer_->SetBounds(gfx::Size(110, 110));
@@ -617,7 +618,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
fake_content_layer_client_.set_bounds(root_layer->bounds());
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(
+ base::BindRepeating(
&LayerTreeHostScrollTestCaseWithChild::DidScrollOuterViewport,
base::Unretained(this)));
}
@@ -695,9 +696,9 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
case 0: {
// GESTURE scroll on impl thread. Also tests that the last scrolled
// layer id is stored even after the scrolling ends.
- gfx::Point scroll_point =
- gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
- gfx::Vector2dF(0.5f, 0.5f));
+ gfx::Point scroll_point = gfx::ToCeiledPoint(
+ expected_scroll_layer_impl->test_properties()->position -
+ gfx::Vector2dF(0.5f, 0.5f));
InputHandler::ScrollStatus status = impl->ScrollBegin(
BeginState(scroll_point).get(), InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
@@ -720,9 +721,9 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
}
case 1: {
// WHEEL scroll on impl thread.
- gfx::Point scroll_point =
- gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
- gfx::Vector2dF(0.5f, 0.5f));
+ gfx::Point scroll_point = gfx::ToCeiledPoint(
+ expected_scroll_layer_impl->test_properties()->position +
+ gfx::Vector2dF(0.5f, 0.5f));
InputHandler::ScrollStatus status = impl->ScrollBegin(
BeginState(scroll_point).get(), InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
@@ -840,8 +841,9 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest {
layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
initial_scroll_);
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestSimple::DidScrollOuterViewport,
- base::Unretained(this)));
+ base::BindRepeating(
+ &LayerTreeHostScrollTestSimple::DidScrollOuterViewport,
+ base::Unretained(this)));
PostSetNeedsCommitToMainThread();
}
@@ -1412,7 +1414,7 @@ class LayerTreeHostScrollTestLayerStructureChange
LayerIdToElementIdForTesting(scroll_layer->id()));
scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
parent->bounds().height() + 100));
- scroll_layer->set_did_scroll_callback(base::Bind(
+ scroll_layer->set_did_scroll_callback(base::BindRepeating(
&FakeLayerScrollClient::DidScroll, base::Unretained(client)));
client->owner_ = this;
client->layer_ = scroll_layer.get();
@@ -1471,8 +1473,9 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest {
layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
initial_scroll_);
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport,
- base::Unretained(this)));
+ base::BindRepeating(
+ &LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport,
+ base::Unretained(this)));
PostSetNeedsCommitToMainThread();
}
@@ -1601,9 +1604,9 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA
layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
initial_scroll_);
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestScrollAbortedCommitMFBA::
- DidScrollOuterViewport,
- base::Unretained(this)));
+ base::BindRepeating(&LayerTreeHostScrollTestScrollAbortedCommitMFBA::
+ DidScrollOuterViewport,
+ base::Unretained(this)));
PostSetNeedsCommitToMainThread();
}
@@ -2050,9 +2053,9 @@ class LayerTreeHostScrollTestImplSideInvalidation
: public LayerTreeHostScrollTest {
void BeginTest() override {
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&LayerTreeHostScrollTestImplSideInvalidation::
- DidScrollOuterViewport,
- base::Unretained(this)));
+ base::BindRepeating(&LayerTreeHostScrollTestImplSideInvalidation::
+ DidScrollOuterViewport,
+ base::Unretained(this)));
PostSetNeedsCommitToMainThread();
}
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index db91dda80b5..034dc7e2959 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -15,6 +15,7 @@
#include "base/containers/adapters.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
+#include "base/json/json_writer.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -472,6 +473,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
// The page scale factor update can affect scrolling which requires that
// these ids are set, so this must be before PushPageScaleFactorAndLimits.
target_tree->SetViewportLayersFromIds(viewport_layer_ids_);
+ target_tree->set_viewport_property_ids(viewport_property_ids_);
// Active tree already shares the page_scale_factor object with pending
// tree so only the limits need to be provided.
@@ -680,7 +682,8 @@ void LayerTreeImpl::SetTransformMutated(ElementId element_id,
const gfx::Transform& transform) {
DCHECK_EQ(1u, property_trees()->element_id_to_transform_node_index.count(
element_id));
- element_id_to_transform_animations_[element_id] = transform;
+ if (IsSyncTree() || IsRecycleTree())
+ element_id_to_transform_animations_[element_id] = transform;
if (property_trees()->transform_tree.OnTransformAnimated(element_id,
transform))
set_needs_update_draw_properties();
@@ -689,7 +692,8 @@ void LayerTreeImpl::SetTransformMutated(ElementId element_id,
void LayerTreeImpl::SetOpacityMutated(ElementId element_id, float opacity) {
DCHECK_EQ(
1u, property_trees()->element_id_to_effect_node_index.count(element_id));
- element_id_to_opacity_animations_[element_id] = opacity;
+ if (IsSyncTree() || IsRecycleTree())
+ element_id_to_opacity_animations_[element_id] = opacity;
if (property_trees()->effect_tree.OnOpacityAnimated(element_id, opacity))
set_needs_update_draw_properties();
}
@@ -698,7 +702,8 @@ void LayerTreeImpl::SetFilterMutated(ElementId element_id,
const FilterOperations& filters) {
DCHECK_EQ(
1u, property_trees()->element_id_to_effect_node_index.count(element_id));
- element_id_to_filter_animations_[element_id] = filters;
+ if (IsSyncTree() || IsRecycleTree())
+ element_id_to_filter_animations_[element_id] = filters;
if (property_trees()->effect_tree.OnFilterAnimated(element_id, filters))
set_needs_update_draw_properties();
}
@@ -772,6 +777,10 @@ void LayerTreeImpl::UpdatePropertyTreeAnimationFromMainThread() {
// respective tree. This can be the case if the layer associated
// with that element id has been removed.
+ // This code is assumed to only run on the sync tree; the node updates are
+ // then synced when the tree is activated. See http://crbug.com/916512
+ DCHECK(IsSyncTree());
+
auto element_id_to_opacity = element_id_to_opacity_animations_.begin();
while (element_id_to_opacity != element_id_to_opacity_animations_.end()) {
const ElementId id = element_id_to_opacity->first;
@@ -1184,9 +1193,13 @@ void LayerTreeImpl::ClearViewportLayers() {
const ScrollNode* LayerTreeImpl::InnerViewportScrollNode() const {
auto* inner_scroll = InnerViewportScrollLayer();
- if (!inner_scroll)
- return nullptr;
-
+ if (!inner_scroll) {
+ // TODO(crbug.com/909750): Check all other callers of
+ // InnerViewportScrollLayer() and switch to
+ // viewport_property_ids_.inner_scroll if needed.
+ return property_trees()->scroll_tree.Node(
+ viewport_property_ids_.inner_scroll);
+ }
return property_trees()->scroll_tree.Node(inner_scroll->scroll_tree_index());
}
@@ -2141,7 +2154,7 @@ LayerImpl* LayerTreeImpl::FindFirstScrollingLayerOrScrollbarThatIsHitByPoint(
struct HitTestVisibleScrollableOrTouchableFunctor {
bool operator()(LayerImpl* layer) const {
- return layer->scrollable() || layer->should_hit_test() ||
+ return layer->scrollable() || layer->ShouldHitTest() ||
!layer->touch_action_region().region().IsEmpty();
}
};
@@ -2336,4 +2349,31 @@ void LayerTreeImpl::ResetAllChangeTracking() {
property_trees_.ResetAllChangeTracking();
}
+std::string LayerTreeImpl::LayerListAsJson() const {
+ auto list = std::make_unique<base::ListValue>();
+ for (auto* layer : *this)
+ list->Append(layer->LayerAsJson());
+ std::string str;
+ base::JSONWriter::WriteWithOptions(
+ *list,
+ base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &str);
+ return str;
+}
+
+std::string LayerTreeImpl::LayerTreeAsJson() const {
+ std::string str;
+ if (root_layer_for_testing_) {
+ std::unique_ptr<base::Value> json(
+ root_layer_for_testing_->LayerTreeAsJson());
+ base::JSONWriter::WriteWithOptions(
+ *json,
+ base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &str);
+ }
+ return str;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index a7a3674f440..b21d9442540 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -199,6 +199,19 @@ class CC_EXPORT LayerTreeImpl {
void SetOpacityMutated(ElementId element_id, float opacity);
void SetFilterMutated(ElementId element_id, const FilterOperations& filters);
+ const std::unordered_map<ElementId, float, ElementIdHash>&
+ element_id_to_opacity_animations_for_testing() const {
+ return element_id_to_opacity_animations_;
+ }
+ const std::unordered_map<ElementId, gfx::Transform, ElementIdHash>&
+ element_id_to_transform_animations_for_testing() const {
+ return element_id_to_transform_animations_;
+ }
+ const std::unordered_map<ElementId, FilterOperations, ElementIdHash>&
+ element_id_to_filter_animations_for_testing() const {
+ return element_id_to_filter_animations_;
+ }
+
int source_frame_number() const { return source_frame_number_; }
void set_source_frame_number(int frame_number) {
source_frame_number_ = frame_number;
@@ -622,6 +635,11 @@ class CC_EXPORT LayerTreeImpl {
return elements_in_property_trees_;
}
+ std::string LayerListAsJson() const;
+ // TODO(pdr): This should be removed because there is no longer a tree
+ // of layers, only a list.
+ std::string LayerTreeAsJson() const;
+
protected:
float ClampPageScaleFactorToLimits(float page_scale_factor) const;
void PushPageScaleFactorAndLimits(const float* page_scale_factor,
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index 1c35945d640..5c8054c72d7 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -28,7 +28,9 @@ class LayerTreeImplTestSettings : public LayerTreeSettings {
class LayerTreeImplTest : public testing::Test {
public:
- LayerTreeImplTest() : impl_test_(LayerTreeImplTestSettings()) {}
+ LayerTreeImplTest(
+ const LayerTreeSettings& settings = LayerTreeImplTestSettings())
+ : impl_test_(settings) {}
FakeLayerTreeHostImpl& host_impl() const { return *impl_test_.host_impl(); }
@@ -288,17 +290,22 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) {
TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) {
// This layer is positioned, and hit testing should correctly know where the
// layer is located.
- LayerImpl* root = root_layer();
- root->SetPosition(gfx::PointF(50.f, 50.f));
- root->SetBounds(gfx::Size(100, 100));
- root->SetDrawsContent(true);
+ {
+ std::unique_ptr<LayerImpl> test_layer =
+ LayerImpl::Create(host_impl().active_tree(), 12345);
+ test_layer->test_properties()->position = gfx::PointF(50.f, 50.f);
+ test_layer->SetBounds(gfx::Size(100, 100));
+ test_layer->SetDrawsContent(true);
+ root_layer()->test_properties()->AddChild(std::move(test_layer));
+ }
- host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
+ LayerImpl* test_layer = root_layer()->test_properties()->children[0];
+ host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds());
host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
// Sanity check the scenario we just created.
ASSERT_EQ(1u, GetRenderSurfaceList().size());
- ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
+ ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());
// Hit testing for a point outside the layer should return a null pointer.
gfx::PointF test_point(49.f, 49.f);
@@ -318,13 +325,13 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) {
result_layer =
host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
ASSERT_TRUE(result_layer);
- EXPECT_EQ(root->id(), result_layer->id());
+ EXPECT_EQ(test_layer->id(), result_layer->id());
test_point = gfx::PointF(99.f, 99.f);
result_layer =
host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
ASSERT_TRUE(result_layer);
- EXPECT_EQ(root->id(), result_layer->id());
+ EXPECT_EQ(test_layer->id(), result_layer->id());
}
TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) {
@@ -520,13 +527,13 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) {
LayerImpl::Create(host_impl().active_tree(), 123);
// this layer is positioned, and hit testing should correctly know where the
// layer is located.
- clipping_layer->SetPosition(gfx::PointF(25.f, 25.f));
+ clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
clipping_layer->SetBounds(gfx::Size(50, 50));
clipping_layer->SetMasksToBounds(true);
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl().active_tree(), 456);
- child->SetPosition(gfx::PointF(-50.f, -50.f));
+ child->test_properties()->position = gfx::PointF(-50.f, -50.f);
child->SetBounds(gfx::Size(300, 300));
child->SetDrawsContent(true);
clipping_layer->test_properties()->AddChild(std::move(child));
@@ -597,7 +604,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
std::unique_ptr<LayerImpl> rotated_leaf =
LayerImpl::Create(host_impl().active_tree(), 2468);
- child->SetPosition(gfx::PointF(10.f, 10.f));
+ child->test_properties()->position = gfx::PointF(10.f, 10.f);
child->SetBounds(gfx::Size(80, 80));
child->SetMasksToBounds(true);
@@ -691,7 +698,7 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) {
LayerImpl::Create(host_impl().active_tree(), 123);
// this layer is positioned, and hit testing should correctly know where the
// layer is located.
- intermediate_layer->SetPosition(gfx::PointF(10.f, 10.f));
+ intermediate_layer->test_properties()->position = gfx::PointF(10.f, 10.f);
intermediate_layer->SetBounds(gfx::Size(50, 50));
// Sanity check the intermediate layer should not clip.
ASSERT_FALSE(intermediate_layer->masks_to_bounds());
@@ -702,7 +709,8 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) {
// would not be able to hit it successfully.
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl().active_tree(), 456);
- child->SetPosition(gfx::PointF(60.f, 60.f)); // 70, 70 in screen space
+ child->test_properties()->position =
+ gfx::PointF(60.f, 60.f); // 70, 70 in screen spae
child->SetBounds(gfx::Size(20, 20));
child->SetDrawsContent(true);
intermediate_layer->test_properties()->AddChild(std::move(child));
@@ -761,18 +769,18 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) {
std::unique_ptr<LayerImpl> grand_child1 =
LayerImpl::Create(host_impl().active_tree(), 4);
- child1->SetPosition(gfx::PointF(10.f, 10.f));
+ child1->test_properties()->position = gfx::PointF(10.f, 10.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
- child2->SetPosition(gfx::PointF(50.f, 10.f));
+ child2->test_properties()->position = gfx::PointF(50.f, 10.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
// Remember that grand_child is positioned with respect to its parent (i.e.
// child1). In screen space, the intended position is (10, 50), with size
// 100 x 50.
- grand_child1->SetPosition(gfx::PointF(0.f, 40.f));
+ grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
grand_child1->SetBounds(gfx::Size(100, 50));
grand_child1->SetDrawsContent(true);
@@ -907,13 +915,13 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) {
std::unique_ptr<LayerImpl> grand_child1 =
LayerImpl::Create(host_impl().active_tree(), 4);
- child1->SetPosition(gfx::PointF(10.f, 10.f));
+ child1->test_properties()->position = gfx::PointF(10.f, 10.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->test_properties()->should_flatten_transform = false;
child1->test_properties()->sorting_context_id = 1;
- child2->SetPosition(gfx::PointF(50.f, 10.f));
+ child2->test_properties()->position = gfx::PointF(50.f, 10.f);
child2->SetBounds(gfx::Size(50, 50));
gfx::Transform translate_z;
translate_z.Translate3d(0, 0, 10.f);
@@ -925,7 +933,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) {
// Remember that grand_child is positioned with respect to its parent (i.e.
// child1). In screen space, the intended position is (10, 50), with size
// 100 x 50.
- grand_child1->SetPosition(gfx::PointF(0.f, 40.f));
+ grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
grand_child1->SetBounds(gfx::Size(100, 50));
grand_child1->SetDrawsContent(true);
grand_child1->test_properties()->should_flatten_transform = false;
@@ -1007,12 +1015,12 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) {
std::unique_ptr<LayerImpl> grand_child =
LayerImpl::Create(host_impl().active_tree(), 4);
- child->SetPosition(gfx::PointF(10.f, 10.f));
+ child->test_properties()->position = gfx::PointF(10.f, 10.f);
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
child->SetMasksToBounds(true);
- grand_child->SetPosition(gfx::PointF(0.f, 40.f));
+ grand_child->test_properties()->position = gfx::PointF(0.f, 40.f);
grand_child->SetBounds(gfx::Size(100, 50));
grand_child->SetDrawsContent(true);
grand_child->test_properties()->force_render_surface = true;
@@ -1050,7 +1058,7 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) {
std::unique_ptr<LayerImpl> grand_child =
LayerImpl::Create(host_impl().active_tree(), 4);
- child->SetPosition(gfx::PointF(10.f, 10.f));
+ child->test_properties()->position = gfx::PointF(10.f, 10.f);
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
child->SetMasksToBounds(true);
@@ -1104,12 +1112,12 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) {
std::unique_ptr<LayerImpl> grand_child1 =
LayerImpl::Create(host_impl().active_tree(), 4);
- child1->SetPosition(gfx::PointF(10.f, 10.f));
+ child1->test_properties()->position = gfx::PointF(10.f, 10.f);
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->test_properties()->force_render_surface = true;
- child2->SetPosition(gfx::PointF(50.f, 10.f));
+ child2->test_properties()->position = gfx::PointF(50.f, 10.f);
child2->SetBounds(gfx::Size(50, 50));
child2->SetDrawsContent(true);
child2->test_properties()->force_render_surface = true;
@@ -1117,7 +1125,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) {
// Remember that grand_child is positioned with respect to its parent (i.e.
// child1). In screen space, the intended position is (10, 50), with size
// 100 x 50.
- grand_child1->SetPosition(gfx::PointF(0.f, 40.f));
+ grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
grand_child1->SetBounds(gfx::Size(100, 50));
grand_child1->SetDrawsContent(true);
grand_child1->test_properties()->force_render_surface = true;
@@ -1352,18 +1360,23 @@ TEST_F(LayerTreeImplTest,
// This layer is positioned, and hit testing should correctly know where the
// layer is located.
- LayerImpl* root = root_layer();
- root->SetPosition(gfx::PointF(50.f, 50.f));
- root->SetBounds(gfx::Size(100, 100));
- root->SetDrawsContent(true);
- root->SetTouchActionRegion(touch_action_region);
+ {
+ std::unique_ptr<LayerImpl> test_layer =
+ LayerImpl::Create(host_impl().active_tree(), 12345);
+ test_layer->test_properties()->position = gfx::PointF(50.f, 50.f);
+ test_layer->SetBounds(gfx::Size(100, 100));
+ test_layer->SetDrawsContent(true);
+ test_layer->SetTouchActionRegion(touch_action_region);
+ root_layer()->test_properties()->AddChild(std::move(test_layer));
+ }
- host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
+ LayerImpl* test_layer = root_layer()->test_properties()->children[0];
+ host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds());
host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
// Sanity check the scenario we just created.
ASSERT_EQ(1u, GetRenderSurfaceList().size());
- ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
+ ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());
// Hit checking for a point outside the layer should return a null pointer.
gfx::PointF test_point(49.f, 49.f);
@@ -1389,20 +1402,20 @@ TEST_F(LayerTreeImplTest,
EXPECT_FALSE(result_layer);
// Hit checking for a point inside the touch event handler region should
- // return the root layer.
+ // return the test layer.
test_point = gfx::PointF(61.f, 61.f);
result_layer =
host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
test_point);
ASSERT_TRUE(result_layer);
- EXPECT_EQ(root->id(), result_layer->id());
+ EXPECT_EQ(test_layer->id(), result_layer->id());
test_point = gfx::PointF(99.f, 99.f);
result_layer =
host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
test_point);
ASSERT_TRUE(result_layer);
- EXPECT_EQ(root->id(), result_layer->id());
+ EXPECT_EQ(test_layer->id(), result_layer->id());
}
TEST_F(LayerTreeImplTest,
@@ -1419,7 +1432,7 @@ TEST_F(LayerTreeImplTest,
touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30));
std::unique_ptr<LayerImpl> test_layer =
LayerImpl::Create(host_impl().active_tree(), 12345);
- test_layer->SetPosition(gfx::PointF(25.f, 25.f));
+ test_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
test_layer->SetBounds(gfx::Size(50, 50));
test_layer->SetDrawsContent(true);
test_layer->SetTouchActionRegion(touch_action_region);
@@ -1555,7 +1568,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
LayerImpl::Create(host_impl().active_tree(), 123);
// this layer is positioned, and hit testing should correctly know where the
// layer is located.
- clipping_layer->SetPosition(gfx::PointF(25.f, 25.f));
+ clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
clipping_layer->SetBounds(gfx::Size(50, 50));
clipping_layer->SetMasksToBounds(true);
@@ -1564,7 +1577,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl().active_tree(), 456);
- child->SetPosition(gfx::PointF(-50.f, -50.f));
+ child->test_properties()->position = gfx::PointF(-50.f, -50.f);
child->SetBounds(gfx::Size(300, 300));
child->SetDrawsContent(true);
child->SetTouchActionRegion(touch_action_region);
@@ -1639,7 +1652,7 @@ TEST_F(LayerTreeImplTest,
LayerImpl::Create(host_impl().active_tree(), 123);
// This layer is positioned, and hit testing should correctly know where the
// layer is located.
- clipping_layer->SetPosition(gfx::PointF(25.f, 20.f));
+ clipping_layer->test_properties()->position = gfx::PointF(25.f, 20.f);
clipping_layer->SetBounds(gfx::Size(50, 50));
clipping_layer->SetMasksToBounds(true);
@@ -1648,7 +1661,7 @@ TEST_F(LayerTreeImplTest,
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl().active_tree(), 456);
- child->SetPosition(gfx::PointF(-50.f, -50.f));
+ child->test_properties()->position = gfx::PointF(-50.f, -50.f);
child->SetBounds(gfx::Size(300, 300));
child->SetDrawsContent(true);
child->SetTouchActionRegion(touch_action_region);
@@ -1722,7 +1735,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) {
LayerImpl::Create(host_impl().active_tree(), 1234);
// this layer is positioned, and hit testing should correctly know where the
// layer is located.
- notouch_layer->SetPosition(gfx::PointF(0, 25));
+ notouch_layer->test_properties()->position = gfx::PointF(0, 25);
notouch_layer->SetBounds(gfx::Size(50, 50));
notouch_layer->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(notouch_layer));
@@ -1802,7 +1815,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) {
// hit testing (becuase the point is inside test_layer with respect to the old
// screen space transform).
gfx::PointF test_point(24.f, 24.f);
- test_layer->SetPosition(gfx::PointF(25.f, 25.f));
+ test_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
gfx::Transform expected_screen_space_transform;
expected_screen_space_transform.Translate(25.f, 25.f);
@@ -1822,7 +1835,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) {
// We change the position of the test layer such that the test point is now
// inside the test_layer.
test_layer = root->test_properties()->children[0];
- test_layer->SetPosition(gfx::PointF(10.f, 10.f));
+ test_layer->test_properties()->position = gfx::PointF(10.f, 10.f);
test_layer->NoteLayerPropertyChanged();
expected_screen_space_transform.MakeIdentity();
expected_screen_space_transform.Translate(10.f, 10.f);
@@ -1916,7 +1929,8 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) {
std::unique_ptr<LayerImpl> clipping_layer =
LayerImpl::Create(host_impl().active_tree(), clip_layer_id);
// The clipping layer should occlude the right selection bound.
- clipping_layer->SetPosition(gfx::PointF() + clipping_offset);
+ clipping_layer->test_properties()->position =
+ gfx::PointF() + clipping_offset;
clipping_layer->SetBounds(gfx::Size(50, 50));
clipping_layer->SetMasksToBounds(true);
@@ -1999,7 +2013,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
{
std::unique_ptr<LayerImpl> sub_layer =
LayerImpl::Create(host_impl().active_tree(), sub_layer_id);
- sub_layer->SetPosition(gfx::PointF() + sub_layer_offset);
+ sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset;
sub_layer->SetBounds(gfx::Size(50, 50));
sub_layer->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(sub_layer));
@@ -2077,7 +2091,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) {
{
std::unique_ptr<LayerImpl> sub_layer =
LayerImpl::Create(host_impl().active_tree(), sub_layer_id);
- sub_layer->SetPosition(gfx::PointF() + sub_layer_offset);
+ sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset;
sub_layer->SetBounds(gfx::Size(50, 50));
sub_layer->SetDrawsContent(true);
root->test_properties()->AddChild(std::move(sub_layer));
@@ -2351,5 +2365,141 @@ TEST_F(LayerTreeImplTest, StubSwapPromisesAreDroppedWhenSwapFails) {
}
}
+namespace {
+class CommitToPendingTreeLayerTreeImplTestSettings : public LayerTreeSettings {
+ public:
+ CommitToPendingTreeLayerTreeImplTestSettings() {
+ commit_to_active_tree = false;
+ }
+};
+
+class CommitToPendingTreeLayerTreeImplTest : public LayerTreeImplTest {
+ public:
+ CommitToPendingTreeLayerTreeImplTest()
+ : LayerTreeImplTest(CommitToPendingTreeLayerTreeImplTestSettings()) {}
+};
+} // namespace
+
+TEST_F(CommitToPendingTreeLayerTreeImplTest,
+ ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
+ ASSERT_FALSE(host_impl().CommitToActiveTree());
+
+ // When we have a pending tree (e.g. commit_to_active_tree is false), the
+ // various ElementId to animation maps should not track anything for the
+ // active tree (as they are only used on the sync tree).
+ LayerTreeImpl* active_tree = host_impl().active_tree();
+ active_tree->BuildPropertyTreesForTesting();
+ LayerImpl* active_root = active_tree->root_layer_for_testing();
+
+ auto& active_opacity_map =
+ active_tree->element_id_to_opacity_animations_for_testing();
+ ASSERT_EQ(active_opacity_map.size(), 0u);
+ active_tree->SetOpacityMutated(active_root->element_id(), 0.5f);
+ EXPECT_EQ(active_opacity_map.size(), 0u);
+
+ auto& active_transform_map =
+ active_tree->element_id_to_transform_animations_for_testing();
+ ASSERT_EQ(active_transform_map.size(), 0u);
+ active_tree->SetTransformMutated(active_root->element_id(), gfx::Transform());
+ EXPECT_EQ(active_transform_map.size(), 0u);
+
+ auto& active_filter_map =
+ active_tree->element_id_to_filter_animations_for_testing();
+ ASSERT_EQ(active_filter_map.size(), 0u);
+ active_tree->SetFilterMutated(active_root->element_id(), FilterOperations());
+ EXPECT_EQ(active_filter_map.size(), 0u);
+
+ // The pending/recycle tree however should track them. Here we need two nodes
+ // (the root and a child) as we will be adding entries for both the pending
+ // and recycle tree cases.
+ host_impl().CreatePendingTree();
+ LayerTreeImpl* pending_tree = host_impl().pending_tree();
+ std::unique_ptr<LayerImpl> pending_root_ptr =
+ LayerImpl::Create(pending_tree, 2);
+ LayerImpl* pending_root = pending_root_ptr.get();
+ pending_tree->SetRootLayerForTesting(std::move(pending_root_ptr));
+
+ std::unique_ptr<LayerImpl> child_ptr =
+ LayerImpl::Create(host_impl().pending_tree(), 3);
+ // The easiest way to force the child to have a TransformNode is to make it
+ // fixed position. Similarly a non-one opacity forces an EffectNode.
+ child_ptr->test_properties()->position_constraint.set_is_fixed_position(true);
+ child_ptr->test_properties()->opacity = 0.9f;
+ LayerImpl* child = child_ptr.get();
+ pending_root->test_properties()->AddChild(std::move(child_ptr));
+ pending_tree->BuildPropertyTreesForTesting();
+
+ auto& pending_opacity_map =
+ pending_tree->element_id_to_opacity_animations_for_testing();
+ ASSERT_EQ(pending_opacity_map.size(), 0u);
+ pending_tree->SetOpacityMutated(pending_root->element_id(), 0.5f);
+ EXPECT_EQ(pending_opacity_map.size(), 1u);
+
+ auto& pending_transform_map =
+ pending_tree->element_id_to_transform_animations_for_testing();
+ ASSERT_EQ(pending_transform_map.size(), 0u);
+ pending_tree->SetTransformMutated(pending_root->element_id(),
+ gfx::Transform());
+ EXPECT_EQ(pending_transform_map.size(), 1u);
+
+ auto& pending_filter_map =
+ pending_tree->element_id_to_filter_animations_for_testing();
+ ASSERT_EQ(pending_filter_map.size(), 0u);
+ pending_tree->SetFilterMutated(pending_root->element_id(),
+ FilterOperations());
+ EXPECT_EQ(pending_filter_map.size(), 1u);
+
+ // Finally, check the recycle tree - this should still track them.
+ host_impl().ActivateSyncTree();
+ LayerTreeImpl* recycle_tree = host_impl().recycle_tree();
+ ASSERT_TRUE(recycle_tree);
+
+ auto& recycle_opacity_map =
+ recycle_tree->element_id_to_opacity_animations_for_testing();
+ ASSERT_EQ(recycle_opacity_map.size(), 1u);
+ recycle_tree->SetOpacityMutated(child->element_id(), 0.5f);
+ EXPECT_EQ(recycle_opacity_map.size(), 2u);
+
+ auto& recycle_transform_map =
+ recycle_tree->element_id_to_transform_animations_for_testing();
+ ASSERT_EQ(recycle_transform_map.size(), 1u);
+ recycle_tree->SetTransformMutated(child->element_id(), gfx::Transform());
+ EXPECT_EQ(recycle_transform_map.size(), 2u);
+
+ auto& recycle_filter_map =
+ recycle_tree->element_id_to_filter_animations_for_testing();
+ ASSERT_EQ(recycle_filter_map.size(), 1u);
+ recycle_tree->SetFilterMutated(child->element_id(), FilterOperations());
+ EXPECT_EQ(recycle_filter_map.size(), 2u);
+}
+
+TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
+ ASSERT_TRUE(host_impl().CommitToActiveTree());
+
+ // When we are commiting directly to the active tree, the various ElementId to
+ // animation maps should track on the active tree (as it is the sync tree, and
+ // they are used on the sync tree).
+ LayerTreeImpl* active_tree = host_impl().active_tree();
+ active_tree->BuildPropertyTreesForTesting();
+ LayerImpl* root = active_tree->root_layer_for_testing();
+
+ auto& opacity_map =
+ active_tree->element_id_to_opacity_animations_for_testing();
+ ASSERT_EQ(opacity_map.size(), 0u);
+ active_tree->SetOpacityMutated(root->element_id(), 0.5f);
+ EXPECT_EQ(opacity_map.size(), 1u);
+
+ auto& transform_map =
+ active_tree->element_id_to_transform_animations_for_testing();
+ ASSERT_EQ(transform_map.size(), 0u);
+ active_tree->SetTransformMutated(root->element_id(), gfx::Transform());
+ EXPECT_EQ(transform_map.size(), 1u);
+
+ auto& filter_map = active_tree->element_id_to_filter_animations_for_testing();
+ ASSERT_EQ(filter_map.size(), 0u);
+ active_tree->SetFilterMutated(root->element_id(), FilterOperations());
+ EXPECT_EQ(filter_map.size(), 1u);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_mutator.cc b/chromium/cc/trees/layer_tree_mutator.cc
index 491eec54fa7..15d2b6aebb2 100644
--- a/chromium/cc/trees/layer_tree_mutator.cc
+++ b/chromium/cc/trees/layer_tree_mutator.cc
@@ -24,21 +24,22 @@ AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState(
AnimationWorkletInput::AddAndUpdateState::~AddAndUpdateState() = default;
#if DCHECK_IS_ON()
-bool AnimationWorkletInput::ValidateScope(int scope_id) const {
+bool AnimationWorkletInput::ValidateId(int worklet_id) const {
return std::all_of(added_and_updated_animations.cbegin(),
added_and_updated_animations.cend(),
- [scope_id](auto& it) {
- return it.worklet_animation_id.scope_id == scope_id;
+ [worklet_id](auto& it) {
+ return it.worklet_animation_id.worklet_id == worklet_id;
}) &&
std::all_of(updated_animations.cbegin(), updated_animations.cend(),
- [scope_id](auto& it) {
- return it.worklet_animation_id.scope_id == scope_id;
+ [worklet_id](auto& it) {
+ return it.worklet_animation_id.worklet_id == worklet_id;
}) &&
std::all_of(
removed_animations.cbegin(), removed_animations.cend(),
- [scope_id](auto& it) { return it.scope_id == scope_id; }) &&
- std::all_of(peeked_animations.cbegin(), peeked_animations.cend(),
- [scope_id](auto& it) { return it.scope_id == scope_id; });
+ [worklet_id](auto& it) { return it.worklet_id == worklet_id; }) &&
+ std::all_of(
+ peeked_animations.cbegin(), peeked_animations.cend(),
+ [worklet_id](auto& it) { return it.worklet_id == worklet_id; });
}
#endif
@@ -65,29 +66,29 @@ AnimationWorkletInput& MutatorInputState::EnsureWorkletEntry(int id) {
void MutatorInputState::Add(AnimationWorkletInput::AddAndUpdateState&& state) {
AnimationWorkletInput& worklet_input =
- EnsureWorkletEntry(state.worklet_animation_id.scope_id);
+ EnsureWorkletEntry(state.worklet_animation_id.worklet_id);
worklet_input.added_and_updated_animations.push_back(std::move(state));
}
void MutatorInputState::Update(AnimationWorkletInput::UpdateState&& state) {
AnimationWorkletInput& worklet_input =
- EnsureWorkletEntry(state.worklet_animation_id.scope_id);
+ EnsureWorkletEntry(state.worklet_animation_id.worklet_id);
worklet_input.updated_animations.push_back(std::move(state));
}
void MutatorInputState::Remove(WorkletAnimationId worklet_animation_id) {
AnimationWorkletInput& worklet_input =
- EnsureWorkletEntry(worklet_animation_id.scope_id);
+ EnsureWorkletEntry(worklet_animation_id.worklet_id);
worklet_input.removed_animations.push_back(worklet_animation_id);
}
void MutatorInputState::Peek(WorkletAnimationId worklet_animation_id) {
AnimationWorkletInput& worklet_input =
- EnsureWorkletEntry(worklet_animation_id.scope_id);
+ EnsureWorkletEntry(worklet_animation_id.worklet_id);
worklet_input.peeked_animations.push_back(worklet_animation_id);
}
std::unique_ptr<AnimationWorkletInput> MutatorInputState::TakeWorkletState(
- int scope_id) {
- auto it = inputs_.find(scope_id);
+ int worklet_id) {
+ auto it = inputs_.find(worklet_id);
if (it == inputs_.end())
return nullptr;
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index 42cc317740e..c3d6fbe899d 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -21,13 +21,13 @@ namespace cc {
struct CC_EXPORT WorkletAnimationId {
// Uniquely identifies the animation worklet with which this animation is
// associated.
- int scope_id;
+ int worklet_id;
// Uniquely identifies the animation within its animation worklet. Note that
// animation_id is only guaranteed to be unique per animation worklet.
int animation_id;
inline bool operator==(const WorkletAnimationId& rhs) const {
- return (this->scope_id == rhs.scope_id) &&
+ return (this->worklet_id == rhs.worklet_id) &&
(this->animation_id == rhs.animation_id);
}
};
@@ -68,8 +68,8 @@ struct CC_EXPORT AnimationWorkletInput {
~AnimationWorkletInput();
#if DCHECK_IS_ON()
- // Verifies all animation states have the expected scope id.
- bool ValidateScope(int scope_id) const;
+ // Verifies all animation states have the expected worklet id.
+ bool ValidateId(int worklet_id) const;
#endif
DISALLOW_COPY_AND_ASSIGN(AnimationWorkletInput);
};
diff --git a/chromium/cc/trees/layer_tree_painter.h b/chromium/cc/trees/layer_tree_painter.h
deleted file mode 100644
index f85707460d5..00000000000
--- a/chromium/cc/trees/layer_tree_painter.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TREES_LAYER_TREE_PAINTER_H_
-#define CC_TREES_LAYER_TREE_PAINTER_H_
-
-#include "cc/cc_export.h"
-
-namespace cc {
-
-class PaintWorkletInput {
- public:
- virtual ~PaintWorkletInput() {}
-};
-
-class CC_EXPORT LayerTreePainter {
- public:
- virtual ~LayerTreePainter() {}
-
- // TODO(xidachen) add a PaintWorkletPaint function.
-};
-
-} // namespace cc
-
-#endif // CC_TREES_LAYER_TREE_PAINTER_H_
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 7f074dd977e..9de6c5f5f45 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -145,10 +145,6 @@ class CC_EXPORT LayerTreeSettings {
// Whether to use edge anti-aliasing for all layer types that supports it.
bool enable_edge_anti_aliasing = true;
- // Whether to request presentation time regardless if existence of
- // presentation time callbacks.
- bool always_request_presentation_time = false;
-
// Whether SetViewportSizeAndScale should update the painted scale factor or
// the device scale factor.
bool use_painted_device_scale_factor = false;
diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h
index d3a3e0e7683..f070e673edb 100644
--- a/chromium/cc/trees/mutator_host_client.h
+++ b/chromium/cc/trees/mutator_host_client.h
@@ -44,7 +44,7 @@ class MutatorHostClient {
// Allows to change IsAnimating value for a set of properties.
virtual void ElementIsAnimatingChanged(
- ElementId element_id,
+ const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) = 0;
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index 0ba135b2fae..aca25d83853 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -287,7 +287,7 @@ class OcclusionTrackerTest : public testing::Test {
const gfx::PointF& position,
const gfx::Size& bounds) {
layer->test_properties()->transform = transform;
- layer->SetPosition(position);
+ layer->test_properties()->position = position;
layer->SetBounds(bounds);
}
diff --git a/chromium/cc/trees/occlusion_unittest.cc b/chromium/cc/trees/occlusion_unittest.cc
index da2f6fd0b6e..e5b31e41193 100644
--- a/chromium/cc/trees/occlusion_unittest.cc
+++ b/chromium/cc/trees/occlusion_unittest.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -36,8 +37,8 @@ TEST(OcclusionTest, HasOcclusion) {
#define EXPECT_OCCLUSION(occlusion, rects, ...) \
{ \
bool expected[] = {__VA_ARGS__}; \
- ASSERT_EQ(arraysize(rects), arraysize(expected)); \
- for (size_t i = 0; i < arraysize(rects); ++i) \
+ ASSERT_EQ(base::size(rects), base::size(expected)); \
+ for (size_t i = 0; i < base::size(rects); ++i) \
EXPECT_EQ(expected[i], occlusion.IsOccluded(rects[i])) \
<< "Test failed for index " << i << "."; \
}
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index b3fff07a268..15c783cba29 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -7,6 +7,7 @@
#include <set>
#include <vector>
+#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/checked_math.h"
@@ -634,8 +635,7 @@ void TransformTree::UpdateNodeAndAncestorsAreAnimatedOrInvertible(
void TransformTree::SetRootTransformsAndScales(
float device_scale_factor,
float page_scale_factor_for_root,
- const gfx::Transform& device_transform,
- gfx::PointF root_position) {
+ const gfx::Transform& device_transform) {
gfx::Vector2dF device_transform_scale_components =
MathUtil::ComputeTransform2dScaleComponents(device_transform, 1.f);
@@ -644,17 +644,14 @@ void TransformTree::SetRootTransformsAndScales(
std::max(device_transform_scale_components.x(),
device_transform_scale_components.y());
- // If DT is the device transform, DSF is the matrix scaled by (device scale
- // factor * page scale factor for root), RP is the matrix translated by root's
- // position,
- // Let Screen Space Scale(SSS) = scale component of DT*DSF*RP,
- // then the screen space transform of the root transform node is set to SSS
- // and the post local transform of the contents root node is set to
- // SSS^-1*DT*DSF*RP.
+ // Let DT be the device transform and DSF be the matrix scaled by (device
+ // scale factor * page scale factor for root). Let Screen Space Scale(SSS) =
+ // scale component of DT*DSF. The screen space transform of the root
+ // transform node is set to SSS and the post local transform of the contents
+ // root node is set to SSS^-1*DT*DSF.
gfx::Transform transform = device_transform;
transform.Scale(device_scale_factor * page_scale_factor_for_root,
device_scale_factor * page_scale_factor_for_root);
- transform.Translate(root_position.x(), root_position.y());
float fallback_value = device_scale_factor * page_scale_factor_for_root;
gfx::Vector2dF screen_space_scale =
MathUtil::ComputeTransform2dScaleComponents(transform, fallback_value);
@@ -779,6 +776,12 @@ void EffectTree::UpdateOpacities(EffectNode* node, EffectNode* parent_node) {
node->screen_space_opacity *= parent_node->screen_space_opacity;
}
+void EffectTree::UpdateSubtreeHidden(EffectNode* node,
+ EffectNode* parent_node) {
+ if (parent_node)
+ node->subtree_hidden |= parent_node->subtree_hidden;
+}
+
void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) {
// Nodes that have screen space opacity 0 are hidden. So they are not drawn.
// Exceptions:
@@ -903,6 +906,7 @@ void EffectTree::UpdateEffects(int id) {
EffectNode* parent_node = parent(node);
UpdateOpacities(node, parent_node);
+ UpdateSubtreeHidden(node, parent_node);
UpdateIsDrawn(node, parent_node);
UpdateEffectChanged(node, parent_node);
UpdateBackfaceVisibility(node, parent_node);
@@ -1840,7 +1844,7 @@ void PropertyTrees::SetOuterViewportContainerBoundsDelta(
bool PropertyTrees::ElementIsAnimatingChanged(
const MutatorHost* mutator_host,
- ElementId element_id,
+ const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state,
@@ -1852,6 +1856,19 @@ bool PropertyTrees::ElementIsAnimatingChanged(
!mask.potentially_animating[property])
continue;
+ // The mask represents which properties have had their state changed. This
+ // can include properties for which there are no longer any animations, in
+ // which case there will not be an entry in the map.
+ //
+ // It is unclear whether this is desirable; it may be that we are missing
+ // updates to property nodes here because we no longer have the required
+ // ElementId to look them up. See http://crbug.com/912574 for context around
+ // why this code was rewritten.
+ auto it = element_id_map.find(static_cast<TargetProperty::Type>(property));
+ if (it == element_id_map.end())
+ continue;
+
+ const ElementId element_id = it->second;
switch (property) {
case TargetProperty::TRANSFORM:
if (TransformNode* transform_node =
@@ -1996,6 +2013,16 @@ std::unique_ptr<base::trace_event::TracedValue> PropertyTrees::AsTracedValue()
return value;
}
+std::string PropertyTrees::ToString() const {
+ std::string str;
+ base::JSONWriter::WriteWithOptions(
+ *AsTracedValue()->ToBaseValue(),
+ base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &str);
+ return str;
+}
+
CombinedAnimationScale PropertyTrees::GetAnimationScales(
int transform_node_id,
LayerTreeImpl* layer_tree_impl) {
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 89118ace357..6b9ef88fb10 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -189,8 +189,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
void SetRootTransformsAndScales(float device_scale_factor,
float page_scale_factor_for_root,
- const gfx::Transform& device_transform,
- gfx::PointF root_position);
+ const gfx::Transform& device_transform);
float device_transform_scale_factor() const {
return device_transform_scale_factor_;
}
@@ -375,6 +374,7 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
private:
void UpdateOpacities(EffectNode* node, EffectNode* parent_node);
+ void UpdateSubtreeHidden(EffectNode* node, EffectNode* parent_node);
void UpdateIsDrawn(EffectNode* node, EffectNode* parent_node);
void UpdateBackfaceVisibility(EffectNode* node, EffectNode* parent_node);
void UpdateHasMaskingChild(EffectNode* node, EffectNode* parent_node);
@@ -625,8 +625,8 @@ class CC_EXPORT PropertyTrees final {
// respective property node. This will eventually allow simplifying logic in
// various places that today has to map from element id to layer id, and then
// from layer id to the respective property node. Completing that work is
- // pending the launch of Slimming Paint v2 and reworking UI compositor logic
- // to produce cc property trees and these maps.
+ // pending the launch of BlinkGenPropertyTrees and reworking UI compositor
+ // logic to produce cc property trees and these maps.
base::flat_map<ElementId, int> element_id_to_effect_node_index;
base::flat_map<ElementId, int> element_id_to_scroll_node_index;
base::flat_map<ElementId, int> element_id_to_transform_node_index;
@@ -658,7 +658,7 @@ class CC_EXPORT PropertyTrees final {
// this property tree. Returns whether a draw property update is
// needed.
bool ElementIsAnimatingChanged(const MutatorHost* mutator_host,
- ElementId element_id,
+ const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state,
@@ -683,6 +683,7 @@ class CC_EXPORT PropertyTrees final {
}
std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
+ std::string ToString() const;
CombinedAnimationScale GetAnimationScales(int transform_node_id,
LayerTreeImpl* layer_tree_impl);
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index 674b121c370..a8765e687e8 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -202,6 +202,14 @@ static const gfx::Transform& Transform(LayerImpl* layer) {
return layer->test_properties()->transform;
}
+static const gfx::PointF& Position(Layer* layer) {
+ return layer->position();
+}
+
+static const gfx::PointF& Position(LayerImpl* layer) {
+ return layer->test_properties()->position;
+}
+
// Methods to query state from the AnimationHost ----------------------
template <typename LayerType>
bool OpacityIsAnimating(const MutatorHost& host, LayerType* layer) {
@@ -472,8 +480,8 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded(
if (!requires_node) {
data_for_children->should_flatten |= ShouldFlattenTransform(layer);
- gfx::Vector2dF local_offset = layer->position().OffsetFromOrigin() +
- Transform(layer).To2dTranslation();
+ gfx::Vector2dF local_offset =
+ Position(layer).OffsetFromOrigin() + Transform(layer).To2dTranslation();
gfx::Vector2dF source_to_parent;
if (source_index != parent_index) {
gfx::Transform to_parent;
@@ -537,13 +545,15 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded(
if (is_root) {
float page_scale_factor_for_root =
is_page_scale_layer ? page_scale_factor_ : 1.f;
+ // SetRootTransformsAndScales will be incorrect if the root layer has
+ // non-zero position, so ensure it is zero.
+ DCHECK(Position(layer).IsOrigin());
transform_tree_.SetRootTransformsAndScales(
transform_tree_.device_scale_factor(), page_scale_factor_for_root,
- device_transform_, layer->position());
+ device_transform_);
} else {
node->source_offset = source_offset;
- node->update_post_local_transform(layer->position(),
- TransformOrigin(layer));
+ node->update_post_local_transform(Position(layer), TransformOrigin(layer));
}
if (is_overscroll_elasticity_layer) {
@@ -748,6 +758,14 @@ static inline const FilterOperations& BackdropFilters(LayerImpl* layer) {
return layer->test_properties()->backdrop_filters;
}
+static inline const gfx::RectF& BackdropFilterBounds(Layer* layer) {
+ return layer->backdrop_filter_bounds();
+}
+
+static inline const gfx::RectF& BackdropFilterBounds(LayerImpl* layer) {
+ return layer->test_properties()->backdrop_filter_bounds;
+}
+
static inline float BackdropFilterQuality(Layer* layer) {
return layer->backdrop_filter_quality();
}
@@ -970,7 +988,8 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
bool requires_node =
is_root || has_transparency || has_potential_opacity_animation ||
- has_non_axis_aligned_clip || should_create_render_surface;
+ has_potential_filter_animation || has_non_axis_aligned_clip ||
+ should_create_render_surface;
int parent_id = data_from_ancestor.effect_tree_parent;
@@ -992,6 +1011,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
node->has_copy_request = HasCopyRequest(layer);
node->filters = Filters(layer);
node->backdrop_filters = BackdropFilters(layer);
+ node->backdrop_filter_bounds = BackdropFilterBounds(layer);
node->backdrop_filter_quality = BackdropFilterQuality(layer);
node->filters_origin = FiltersOrigin(layer);
node->trilinear_filtering = TrilinearFiltering(layer);
@@ -1070,7 +1090,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
}
static inline bool UserScrollableHorizontal(Layer* layer) {
- return layer->user_scrollable_horizontal();
+ return layer->GetUserScrollableHorizontal();
}
static inline bool UserScrollableHorizontal(LayerImpl* layer) {
@@ -1078,7 +1098,7 @@ static inline bool UserScrollableHorizontal(LayerImpl* layer) {
}
static inline bool UserScrollableVertical(Layer* layer) {
- return layer->user_scrollable_vertical();
+ return layer->GetUserScrollableVertical();
}
static inline bool UserScrollableVertical(LayerImpl* layer) {
@@ -1103,6 +1123,14 @@ static inline const base::Optional<SnapContainerData>& GetSnapContainerData(
return layer->test_properties()->snap_container_data;
}
+static inline uint32_t MainThreadScrollingReasons(Layer* layer) {
+ return layer->GetMainThreadScrollingReasons();
+}
+
+static inline uint32_t MainThreadScrollingReasons(LayerImpl* layer) {
+ return layer->test_properties()->main_thread_scrolling_reasons;
+}
+
template <typename LayerType>
void SetHasTransformNode(LayerType* layer, bool val) {
layer->SetHasTransformNode(val);
@@ -1119,8 +1147,7 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded(
bool scrollable = layer->scrollable();
bool contains_non_fast_scrollable_region =
!layer->non_fast_scrollable_region().IsEmpty();
- uint32_t main_thread_scrolling_reasons =
- layer->main_thread_scrolling_reasons();
+ uint32_t main_thread_scrolling_reasons = MainThreadScrollingReasons(layer);
bool scroll_node_uninheritable_criteria =
is_root || scrollable || contains_non_fast_scrollable_region;
@@ -1347,9 +1374,11 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees(
clip_tree_.SetViewportClip(gfx::RectF(viewport));
float page_scale_factor_for_root =
page_scale_is_root_layer ? page_scale_factor_ : 1.f;
+ // SetRootTransformsAndScales will be incorrect if the root layer has
+ // non-zero position, so ensure it is zero.
+ DCHECK(Position(root_layer_).IsOrigin());
transform_tree_.SetRootTransformsAndScales(
- device_scale_factor, page_scale_factor_for_root, device_transform_,
- root_layer_->position());
+ device_scale_factor, page_scale_factor_for_root, device_transform_);
return;
}
diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc
index 7935b599b40..1e0a02ae142 100644
--- a/chromium/cc/trees/property_tree_unittest.cc
+++ b/chromium/cc/trees/property_tree_unittest.cc
@@ -48,10 +48,10 @@ TEST(PropertyTreeTest, SetNeedsUpdate) {
contents_root.id = tree.Insert(contents_root, 0);
EXPECT_FALSE(tree.needs_update());
- tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform(), gfx::PointF());
+ tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform());
EXPECT_TRUE(tree.needs_update());
tree.set_needs_update(false);
- tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform(), gfx::PointF());
+ tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform());
EXPECT_FALSE(tree.needs_update());
}
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index b9bb0318420..70d28901b25 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -27,6 +27,7 @@ class Rect;
namespace cc {
class LayerTreeFrameSink;
class LayerTreeMutator;
+class PaintWorkletLayerPainter;
class RenderFrameMetadataObserver;
// Abstract interface responsible for proxying commands from the main-thread
@@ -72,6 +73,9 @@ class CC_EXPORT Proxy {
virtual void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) = 0;
+ virtual void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) = 0;
+
virtual bool SupportsImplScrolling() const = 0;
virtual void UpdateBrowserControlsState(BrowserControlsState constraints,
diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h
index 4b2e2c02dc3..e4de8308fa4 100644
--- a/chromium/cc/trees/proxy_common.h
+++ b/chromium/cc/trees/proxy_common.h
@@ -14,8 +14,6 @@
namespace cc {
-using BeginFrameCallbackList = std::vector<base::Closure>;
-
struct CC_EXPORT BeginMainFrameAndCommitState {
BeginMainFrameAndCommitState();
~BeginMainFrameAndCommitState();
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index d3fc4b7ab4b..8e3a50966cf 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -15,6 +15,7 @@
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/scheduler/compositor_timing_history.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host.h"
@@ -62,7 +63,8 @@ ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
task_runner_provider_(task_runner_provider),
smoothness_priority_expiration_notifier_(
task_runner_provider->ImplThreadTaskRunner(),
- base::Bind(&ProxyImpl::RenewTreePriority, base::Unretained(this)),
+ base::BindRepeating(&ProxyImpl::RenewTreePriority,
+ base::Unretained(this)),
base::TimeDelta::FromSecondsD(
kSmoothnessTakesPriorityExpirationDelay)),
rendering_stats_instrumentation_(
@@ -129,6 +131,13 @@ void ProxyImpl::InitializeMutatorOnImpl(
host_impl_->SetLayerTreeMutator(std::move(mutator));
}
+void ProxyImpl::InitializePaintWorkletLayerPainterOnImpl(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ TRACE_EVENT0("cc", "ProxyImpl::InitializePaintWorkletLayerPainterOnImpl");
+ DCHECK(IsImplThread());
+ host_impl_->SetPaintWorkletLayerPainter(std::move(painter));
+}
+
void ProxyImpl::UpdateBrowserControlsStateOnImpl(
BrowserControlsState constraints,
BrowserControlsState current,
@@ -436,11 +445,11 @@ void ProxyImpl::RenewTreePriority() {
scroll_handler_state);
}
-void ProxyImpl::PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+void ProxyImpl::PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) {
DCHECK(IsImplThread());
- task_runner_provider_->ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE,
- task, delay);
+ task_runner_provider_->ImplThreadTaskRunner()->PostDelayedTask(
+ FROM_HERE, std::move(task), delay);
}
void ProxyImpl::DidActivateSyncTree() {
@@ -498,6 +507,13 @@ void ProxyImpl::DidPresentCompositorFrameOnImplThread(
std::move(callbacks), feedback));
}
+void ProxyImpl::DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) {
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&ProxyMain::DidGenerateLocalSurfaceIdAllocation,
+ proxy_main_weak_ptr_, allocation));
+}
+
bool ProxyImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
DCHECK(IsImplThread());
return host_impl_->WillBeginImplFrame(args);
@@ -647,8 +663,8 @@ void ProxyImpl::ScheduledActionBeginMainFrameNotExpectedUntil(
base::TimeTicks time) {
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::BeginMainFrameNotExpectedUntil,
- proxy_main_weak_ptr_, time));
+ FROM_HERE, base::BindOnce(&ProxyMain::BeginMainFrameNotExpectedUntil,
+ proxy_main_weak_ptr_, time));
}
DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 038d3752605..5f1ff436eb1 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -40,6 +40,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
LayerTreeFrameSink* layer_tree_frame_sink,
base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr);
void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator);
+ void InitializePaintWorkletLayerPainterOnImpl(
+ std::unique_ptr<PaintWorkletLayerPainter> painter);
void SetInputThrottledUntilCommitOnImpl(bool is_throttled);
void SetDeferMainFrameUpdateOnImpl(bool defer_main_frame_update) const;
void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect);
@@ -92,7 +94,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
std::unique_ptr<MutatorEvents> events) override;
bool IsInsideDraw() override;
void RenewTreePriority() override;
- void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+ void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override;
void DidActivateSyncTree() override;
void WillPrepareTiles() override;
@@ -106,6 +108,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override;
+ void DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) override;
// SchedulerClient implementation
bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 9bee3eff2c2..85bf14a0357 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -12,6 +12,7 @@
#include "cc/base/completion_event.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/trees/latency_info_swap_promise.h"
#include "cc/trees/layer_tree_frame_sink.h"
@@ -347,6 +348,11 @@ void ProxyMain::DidPresentCompositorFrame(
feedback);
}
+void ProxyMain::DidGenerateLocalSurfaceIdAllocation(
+ const viz::LocalSurfaceIdAllocation& allocation) {
+ layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
+}
+
bool ProxyMain::IsStarted() const {
DCHECK(IsMainThread());
return started_;
@@ -518,6 +524,16 @@ void ProxyMain::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
base::Passed(std::move(mutator))));
}
+void ProxyMain::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ TRACE_EVENT0("cc", "ThreadProxy::SetPaintWorkletLayerPainter");
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::InitializePaintWorkletLayerPainterOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ base::Passed(std::move(painter))));
+}
+
bool ProxyMain::SupportsImplScrolling() const {
return true;
}
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index 0005a6e1bfe..7fbff9efc35 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -11,6 +11,10 @@
#include "cc/trees/proxy.h"
#include "cc/trees/proxy_common.h"
+namespace viz {
+class LocalSurfaceIdAllocation;
+}
+
namespace cc {
class MutatorEvents;
@@ -18,6 +22,7 @@ class CompletionEvent;
class LayerTreeFrameSink;
class LayerTreeHost;
class LayerTreeMutator;
+class PaintWorkletLayerPainter;
class ProxyImpl;
class RenderFrameMetadataObserver;
@@ -56,6 +61,8 @@ class CC_EXPORT ProxyMain : public Proxy {
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback);
+ void DidGenerateLocalSurfaceIdAllocation(
+ const viz::LocalSurfaceIdAllocation& allocation);
CommitPipelineStage max_requested_pipeline_stage() const {
return max_requested_pipeline_stage_;
@@ -87,6 +94,8 @@ class CC_EXPORT ProxyMain : public Proxy {
void Stop() override;
bool SupportsImplScrolling() const override;
void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override;
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) override;
bool MainFrameWillHappenForTesting() override;
void ReleaseLayerTreeFrameSink() override;
void UpdateBrowserControlsState(BrowserControlsState constraints,
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 2e3b7c613c1..b15148dd561 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -10,6 +10,7 @@
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
+#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/compositor_timing_history.h"
@@ -164,7 +165,6 @@ void SingleThreadProxy::SetLayerTreeFrameSink(
void SingleThreadProxy::SetNeedsAnimate() {
TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
DCHECK(task_runner_provider_->IsMainThread());
- single_thread_client_->RequestScheduleAnimation();
if (animate_requested_)
return;
animate_requested_ = true;
@@ -316,6 +316,11 @@ void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
host_impl_->SetLayerTreeMutator(std::move(mutator));
}
+void SingleThreadProxy::SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) {
+ NOTREACHED();
+}
+
void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
TRACE_EVENT1("cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw",
can_draw);
@@ -453,8 +458,9 @@ void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() {
// TextureLayer) is PostTasked and we want to make sure ack is received
// after resources are returned.
task_runner_provider_->MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&SingleThreadProxy::DidReceiveCompositorFrameAck,
- frame_sink_bound_weak_ptr_));
+ FROM_HERE,
+ base::BindOnce(&SingleThreadProxy::DidReceiveCompositorFrameAck,
+ frame_sink_bound_weak_ptr_));
}
}
@@ -493,6 +499,11 @@ void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
feedback);
}
+void SingleThreadProxy::DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) {
+ layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
+}
+
void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
if (scheduler_on_impl_thread_) {
scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
@@ -589,8 +600,8 @@ void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() {
if (layer_tree_frame_sink_creation_callback_.IsCancelled() &&
!layer_tree_frame_sink_creation_requested_) {
layer_tree_frame_sink_creation_callback_.Reset(
- base::Bind(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
+ weak_factory_.GetWeakPtr()));
task_runner_provider_->MainThreadTaskRunner()->PostTask(
FROM_HERE, layer_tree_frame_sink_creation_callback_.callback());
}
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index ca922056575..565af3d2925 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -56,6 +56,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void Start() override;
void Stop() override;
void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override;
+ void SetPaintWorkletLayerPainter(
+ std::unique_ptr<PaintWorkletLayerPainter> painter) override;
bool SupportsImplScrolling() const override;
bool MainFrameWillHappenForTesting() override;
void SetURLForUkm(const GURL& url) override {
@@ -111,7 +113,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
std::unique_ptr<MutatorEvents> events) override;
bool IsInsideDraw() override;
void RenewTreePriority() override {}
- void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+ void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override {}
void DidActivateSyncTree() override;
void WillPrepareTiles() override;
@@ -126,6 +128,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override;
+ void DidGenerateLocalSurfaceIdAllocationOnImplThread(
+ const viz::LocalSurfaceIdAllocation& allocation) override;
void RequestNewLayerTreeFrameSink();
@@ -188,7 +192,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
bool layer_tree_frame_sink_lost_;
// This is the callback for the scheduled RequestNewLayerTreeFrameSink.
- base::CancelableClosure layer_tree_frame_sink_creation_callback_;
+ base::CancelableOnceClosure layer_tree_frame_sink_creation_callback_;
base::WeakPtr<SingleThreadProxy> frame_sink_bound_weak_ptr_;
diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h
index 93fa839bd82..f28649ce203 100644
--- a/chromium/cc/trees/target_property.h
+++ b/chromium/cc/trees/target_property.h
@@ -7,6 +7,8 @@
#include <bitset>
+#include "base/containers/flat_map.h"
+
namespace cc {
static constexpr size_t kMaxTargetPropertyIndex = 32u;
@@ -32,6 +34,13 @@ enum Type {
// A set of target properties.
using TargetProperties = std::bitset<kMaxTargetPropertyIndex>;
+// A map of target property to ElementId.
+// flat_map was chosen because there are expected to be relatively few entries
+// in the map. For low number of entries, flat_map is known to perform better
+// than other map implementations.
+struct ElementId;
+using PropertyToElementIdMap = base::flat_map<TargetProperty::Type, ElementId>;
+
} // namespace cc
#endif // CC_TREES_TARGET_PROPERTY_H_
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index c31289f46cf..80b912a1b8d 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -9,6 +9,8 @@
#include <set>
#include "base/containers/flat_set.h"
+#include "base/debug/crash_logging.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
@@ -154,6 +156,50 @@ void TreeSynchronizer::SynchronizeTrees(LayerTreeImpl* pending_tree,
template <typename Iterator>
static void PushLayerPropertiesInternal(Iterator source_layers_begin,
Iterator source_layers_end,
+ LayerTreeHost* host_tree,
+ LayerTreeImpl* target_impl_tree) {
+ for (Iterator it = source_layers_begin; it != source_layers_end; ++it) {
+ auto* source_layer = *it;
+ LayerImpl* target_layer = target_impl_tree->LayerById(source_layer->id());
+ DCHECK(target_layer);
+ // TODO(enne): http://crbug.com/918126 debugging
+ if (!target_layer) {
+ bool host_set_on_source = source_layer->layer_tree_host() == host_tree;
+
+ bool source_found_by_iterator = false;
+ for (auto it = host_tree->begin(); it != host_tree->end(); ++it) {
+ if (*it == source_layer) {
+ source_found_by_iterator = true;
+ break;
+ }
+ }
+
+ bool root_layer_valid = !!host_tree->root_layer();
+ bool found_root = false;
+ Layer* layer = source_layer;
+ while (layer) {
+ if (layer == host_tree->root_layer()) {
+ found_root = true;
+ break;
+ }
+ layer = layer->parent();
+ }
+
+ auto str = base::StringPrintf(
+ "hs: %d, sf: %d, rlv: %d, fr: %d", host_set_on_source,
+ source_found_by_iterator, root_layer_valid, found_root);
+ static auto* crash_key = base::debug::AllocateCrashKeyString(
+ "cc_null_layer_sync", base::debug::CrashKeySize::Size32);
+ base::debug::SetCrashKeyString(crash_key, str);
+ base::debug::DumpWithoutCrashing();
+ }
+ source_layer->PushPropertiesTo(target_layer);
+ }
+}
+
+template <typename Iterator>
+static void PushLayerPropertiesInternal(Iterator source_layers_begin,
+ Iterator source_layers_end,
LayerTreeImpl* target_impl_tree) {
for (Iterator it = source_layers_begin; it != source_layers_end; ++it) {
auto* source_layer = *it;
@@ -183,7 +229,8 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeHost* host_tree,
auto layers = host_tree->LayersThatShouldPushProperties();
TRACE_EVENT1("cc", "TreeSynchronizer::PushLayerPropertiesTo.Main",
"layer_count", layers.size());
- PushLayerPropertiesInternal(layers.begin(), layers.end(), impl_tree);
+ PushLayerPropertiesInternal(layers.begin(), layers.end(), host_tree,
+ impl_tree);
// When using layer lists, we may not have layers for all property tree
// node ids and need to synchronize the registered id list.
if (host_tree->IsUsingLayerLists())
diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc
index 547dccae6ef..99b8819cb7c 100644
--- a/chromium/cc/trees/tree_synchronizer_unittest.cc
+++ b/chromium/cc/trees/tree_synchronizer_unittest.cc
@@ -380,8 +380,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
// Pick some random properties to set. The values are not important, we're
// just testing that at least some properties are making it through.
- gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
- layer_tree_root->SetPosition(root_position);
+ gfx::Size root_bounds = gfx::Size(10, 12);
+ layer_tree_root->SetBounds(root_bounds);
gfx::Size second_child_bounds = gfx::Size(25, 53);
layer_tree_root->children()[1]->SetBounds(second_child_bounds);
@@ -400,9 +400,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
// Check that the property values we set on the Layer tree are reflected in
// the LayerImpl tree.
- gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
- EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
- EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
+ EXPECT_EQ(root_bounds, layer_impl_tree_root->bounds());
gfx::Size second_layer_impl_child_bounds =
layer_impl_tree_root->layer_tree_impl()