summaryrefslogtreecommitdiffstats
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 15:05:36 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:33:47 +0000
commite684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch)
treed55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/cc
parent2b94bfe47ccb6c08047959d1c26e392919550e86 (diff)
BASELINE: Update Chromium to 72.0.3626.110 and Ninja to 1.9.0
Change-Id: Ic57220b00ecc929a893c91f5cc552f5d3e99e922 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn5
-rw-r--r--chromium/cc/OWNERS1
-rw-r--r--chromium/cc/PRESUBMIT.py14
-rw-r--r--chromium/cc/animation/animation_host.cc2
-rw-r--r--chromium/cc/animation/animation_host_unittest.cc10
-rw-r--r--chromium/cc/animation/element_animations.cc66
-rw-r--r--chromium/cc/animation/element_animations.h13
-rw-r--r--chromium/cc/animation/keyframe_effect.h4
-rw-r--r--chromium/cc/animation/keyframe_model.cc4
-rw-r--r--chromium/cc/animation/keyframe_model.h8
-rw-r--r--chromium/cc/animation/scroll_offset_animations_impl.cc2
-rw-r--r--chromium/cc/animation/scroll_timeline.cc80
-rw-r--r--chromium/cc/animation/scroll_timeline.h30
-rw-r--r--chromium/cc/animation/scroll_timeline_unittest.cc113
-rw-r--r--chromium/cc/animation/worklet_animation.cc24
-rw-r--r--chromium/cc/animation/worklet_animation.h9
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc16
-rw-r--r--chromium/cc/base/completion_event.h6
-rw-r--r--chromium/cc/base/devtools_instrumentation.cc12
-rw-r--r--chromium/cc/base/devtools_instrumentation.h72
-rw-r--r--chromium/cc/base/math_util.cc2
-rw-r--r--chromium/cc/base/region.cc2
-rw-r--r--chromium/cc/base/rtree.h19
-rw-r--r--chromium/cc/base/rtree_perftest.cc4
-rw-r--r--chromium/cc/base/rtree_unittest.cc27
-rw-r--r--chromium/cc/base/switches.cc3
-rw-r--r--chromium/cc/base/switches.h1
-rw-r--r--chromium/cc/benchmarks/benchmark_instrumentation.h10
-rw-r--r--chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc4
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.cc4
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.h2
-rw-r--r--chromium/cc/debug/rendering_stats.h2
-rw-r--r--chromium/cc/input/browser_controls_offset_manager.cc41
-rw-r--r--chromium/cc/input/browser_controls_offset_manager.h10
-rw-r--r--chromium/cc/input/browser_controls_offset_manager_client.h1
-rw-r--r--chromium/cc/input/browser_controls_offset_manager_unittest.cc71
-rw-r--r--chromium/cc/input/browser_controls_state.h3
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.cc4
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.h6
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason_unittest.cc5
-rw-r--r--chromium/cc/input/scroll_snap_data.cc172
-rw-r--r--chromium/cc/input/scroll_snap_data.h38
-rw-r--r--chromium/cc/input/scroll_snap_data_unittest.cc81
-rw-r--r--chromium/cc/input/snap_fling_controller.h4
-rw-r--r--chromium/cc/input/snap_selection_strategy.cc151
-rw-r--r--chromium/cc/input/snap_selection_strategy.h170
-rw-r--r--chromium/cc/layers/heads_up_display_layer.cc27
-rw-r--r--chromium/cc/layers/heads_up_display_layer.h3
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc540
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.h47
-rw-r--r--chromium/cc/layers/heads_up_display_unittest.cc19
-rw-r--r--chromium/cc/layers/layer.cc8
-rw-r--r--chromium/cc/layers/layer.h8
-rw-r--r--chromium/cc/layers/layer_impl.cc4
-rw-r--r--chromium/cc/layers/layer_impl_test_properties.h2
-rw-r--r--chromium/cc/layers/layer_unittest.cc2
-rw-r--r--chromium/cc/layers/nine_patch_generator.cc4
-rw-r--r--chromium/cc/layers/painted_overlay_scrollbar_layer_impl.cc10
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.cc6
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc30
-rw-r--r--chromium/cc/layers/recording_source_unittest.cc23
-rw-r--r--chromium/cc/layers/render_surface_impl.cc6
-rw-r--r--chromium/cc/layers/render_surface_impl.h2
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc4
-rw-r--r--chromium/cc/layers/surface_layer.cc13
-rw-r--r--chromium/cc/layers/surface_layer.h12
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc10
-rw-r--r--chromium/cc/layers/surface_layer_unittest.cc52
-rw-r--r--chromium/cc/layers/texture_layer_impl.cc3
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc12
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl.cc2
-rw-r--r--chromium/cc/layers/video_layer_impl.cc13
-rw-r--r--chromium/cc/layers/video_layer_impl_unittest.cc3
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc36
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h11
-rw-r--r--chromium/cc/paint/BUILD.gn25
-rw-r--r--chromium/cc/paint/DEPS3
-rw-r--r--chromium/cc/paint/decoded_draw_image.h5
-rw-r--r--chromium/cc/paint/discardable_image_map.cc4
-rw-r--r--chromium/cc/paint/discardable_image_map_unittest.cc12
-rw-r--r--chromium/cc/paint/display_item_list.cc7
-rw-r--r--chromium/cc/paint/display_item_list_unittest.cc2
-rw-r--r--chromium/cc/paint/draw_image.cc15
-rw-r--r--chromium/cc/paint/draw_image.h21
-rw-r--r--chromium/cc/paint/filter_operation.cc2
-rw-r--r--chromium/cc/paint/filter_operations.cc2
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc4
-rw-r--r--chromium/cc/paint/oop_pixeltest.cc287
-rw-r--r--chromium/cc/paint/paint_cache.cc126
-rw-r--r--chromium/cc/paint/paint_cache.h119
-rw-r--r--chromium/cc/paint/paint_cache_unittest.cc131
-rw-r--r--chromium/cc/paint/paint_canvas.h26
-rw-r--r--chromium/cc/paint/paint_filter.cc2
-rw-r--r--chromium/cc/paint/paint_filter_unittest.cc2
-rw-r--r--chromium/cc/paint/paint_flags.cc23
-rw-r--r--chromium/cc/paint/paint_flags.h20
-rw-r--r--chromium/cc/paint/paint_font.cc64
-rw-r--r--chromium/cc/paint/paint_font.h45
-rw-r--r--chromium/cc/paint/paint_image.h21
-rw-r--r--chromium/cc/paint/paint_image_generator.h25
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc89
-rw-r--r--chromium/cc/paint/paint_op_buffer.h39
-rw-r--r--chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc124
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc15
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.cc8
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.h6
-rw-r--r--chromium/cc/paint/paint_op_buffer_unittest.cc144
-rw-r--r--chromium/cc/paint/paint_op_helper_unittest.cc22
-rw-r--r--chromium/cc/paint/paint_op_perftest.cc11
-rw-r--r--chromium/cc/paint/paint_op_reader.cc86
-rw-r--r--chromium/cc/paint/paint_op_reader.h2
-rw-r--r--chromium/cc/paint/paint_op_writer.cc98
-rw-r--r--chromium/cc/paint/paint_op_writer.h4
-rw-r--r--chromium/cc/paint/paint_shader.cc20
-rw-r--r--chromium/cc/paint/paint_shader.h3
-rw-r--r--chromium/cc/paint/paint_text_blob.cc19
-rw-r--r--chromium/cc/paint/paint_text_blob.h44
-rw-r--r--chromium/cc/paint/paint_text_blob_builder.cc36
-rw-r--r--chromium/cc/paint/paint_text_blob_builder.h49
-rw-r--r--chromium/cc/paint/path_transfer_cache_entry.cc54
-rw-r--r--chromium/cc/paint/path_transfer_cache_entry.h46
-rw-r--r--chromium/cc/paint/raw_memory_transfer_cache_entry.cc4
-rw-r--r--chromium/cc/paint/record_paint_canvas.cc11
-rw-r--r--chromium/cc/paint/record_paint_canvas.h7
-rw-r--r--chromium/cc/paint/skia_paint_canvas.cc10
-rw-r--r--chromium/cc/paint/skia_paint_canvas.h7
-rw-r--r--chromium/cc/paint/skia_paint_image_generator.cc18
-rw-r--r--chromium/cc/paint/skia_paint_image_generator.h10
-rw-r--r--chromium/cc/paint/skottie_wrapper.cc34
-rw-r--r--chromium/cc/paint/skottie_wrapper.h55
-rw-r--r--chromium/cc/paint/solid_color_analyzer.cc1
-rw-r--r--chromium/cc/paint/transfer_cache_entry.cc8
-rw-r--r--chromium/cc/paint/transfer_cache_entry.h1
-rw-r--r--chromium/cc/paint/transfer_cache_serialize_helper.cc7
-rw-r--r--chromium/cc/paint/transfer_cache_serialize_helper.h8
-rw-r--r--chromium/cc/paint/transfer_cache_unittest.cc36
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc2
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc9
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc90
-rw-r--r--chromium/cc/raster/playback_image_provider.cc4
-rw-r--r--chromium/cc/raster/playback_image_provider.h2
-rw-r--r--chromium/cc/raster/playback_image_provider_unittest.cc17
-rw-r--r--chromium/cc/raster/raster_buffer_provider_perftest.cc2
-rw-r--r--chromium/cc/raster/raster_source_unittest.cc10
-rw-r--r--chromium/cc/raster/single_thread_task_graph_runner.cc7
-rw-r--r--chromium/cc/raster/staging_buffer_pool.cc41
-rw-r--r--chromium/cc/raster/staging_buffer_pool.h14
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.cc128
-rw-r--r--chromium/cc/resources/resource_pool.cc89
-rw-r--r--chromium/cc/resources/resource_pool.h17
-rw-r--r--chromium/cc/resources/resource_pool_unittest.cc164
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.h2
-rw-r--r--chromium/cc/scheduler/scheduler.cc21
-rw-r--r--chromium/cc/scheduler/scheduler.h39
-rw-r--r--chromium/cc/scheduler/scheduler_settings.cc2
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc31
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.h4
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc65
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc77
-rw-r--r--chromium/cc/tiles/checker_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/checker_image_tracker.h1
-rw-r--r--chromium/cc/tiles/checker_image_tracker_unittest.cc13
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.h1
-rw-r--r--chromium/cc/tiles/decoded_image_tracker_unittest.cc46
-rw-r--r--chromium/cc/tiles/frame_viewer_instrumentation.cc9
-rw-r--r--chromium/cc/tiles/frame_viewer_instrumentation.h7
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc57
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.h7
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_perftest.cc44
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc285
-rw-r--r--chromium/cc/tiles/image_controller_unittest.cc2
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.cc2
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc25
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.h4
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_perftest.cc3
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest.cc261
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc14
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.cc25
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.h10
-rw-r--r--chromium/cc/tiles/tile.cc2
-rw-r--r--chromium/cc/tiles/tile_draw_info.h2
-rw-r--r--chromium/cc/tiles/tile_manager.cc57
-rw-r--r--chromium/cc/tiles/tile_manager.h10
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc89
-rw-r--r--chromium/cc/tiles/tile_priority.cc2
-rw-r--r--chromium/cc/tiles/tile_priority.h2
-rw-r--r--chromium/cc/trees/clip_node.cc6
-rw-r--r--chromium/cc/trees/clip_node.h1
-rw-r--r--chromium/cc/trees/damage_tracker.cc15
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc14
-rw-r--r--chromium/cc/trees/draw_property_utils.cc13
-rw-r--r--chromium/cc/trees/effect_node.cc6
-rw-r--r--chromium/cc/trees/effect_node.h2
-rw-r--r--chromium/cc/trees/element_id.cc2
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h11
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h3
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_unittest.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host.cc226
-rw-r--r--chromium/cc/trees/layer_tree_host.h116
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h20
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc81
-rw-r--r--chromium/cc/trees/layer_tree_host_common.h11
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc224
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h20
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc314
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc83
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_single_thread_client.h6
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc301
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc71
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc21
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_damage.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_masks.cc5
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc7
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_proxy.cc119
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc83
-rw-r--r--chromium/cc/trees/layer_tree_impl.h41
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc23
-rw-r--r--chromium/cc/trees/layer_tree_mutator.cc13
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h14
-rw-r--r--chromium/cc/trees/layer_tree_painter.h26
-rw-r--r--chromium/cc/trees/layer_tree_settings.h6
-rw-r--r--chromium/cc/trees/occlusion_tracker.cc8
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc66
-rw-r--r--chromium/cc/trees/property_tree.cc54
-rw-r--r--chromium/cc/trees/property_tree.h7
-rw-r--r--chromium/cc/trees/property_tree_builder.cc12
-rw-r--r--chromium/cc/trees/proxy.h9
-rw-r--r--chromium/cc/trees/proxy_impl.cc34
-rw-r--r--chromium/cc/trees/proxy_impl.h10
-rw-r--r--chromium/cc/trees/proxy_main.cc64
-rw-r--r--chromium/cc/trees/proxy_main.h4
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc3
-rw-r--r--chromium/cc/trees/render_frame_metadata.h10
-rw-r--r--chromium/cc/trees/render_frame_metadata_observer.h3
-rw-r--r--chromium/cc/trees/scroll_node.cc6
-rw-r--r--chromium/cc/trees/scroll_node.h1
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc51
-rw-r--r--chromium/cc/trees/single_thread_proxy.h11
-rw-r--r--chromium/cc/trees/transform_node.cc4
-rw-r--r--chromium/cc/trees/transform_node.h1
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc25
-rw-r--r--chromium/cc/trees/tree_synchronizer_unittest.cc92
248 files changed, 5371 insertions, 3249 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index b5a24d07eca..1c7b04e7a28 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -54,6 +54,8 @@ cc_component("cc") {
"input/snap_fling_controller.h",
"input/snap_fling_curve.cc",
"input/snap_fling_curve.h",
+ "input/snap_selection_strategy.cc",
+ "input/snap_selection_strategy.h",
"input/touch_action.h",
"layers/append_quads_data.cc",
"layers/append_quads_data.h",
@@ -295,6 +297,7 @@ 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",
@@ -360,7 +363,6 @@ cc_component("cc") {
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
"//gpu/command_buffer/client:raster_interface",
- "//gpu/ipc:gl_in_process_context",
"//gpu/skia_bindings:skia_bindings",
"//gpu/vulkan:buildflags",
"//media", # For VideoLayerImpl.
@@ -611,6 +613,7 @@ cc_test("cc_unittests") {
"paint/display_item_list_unittest.cc",
"paint/filter_operations_unittest.cc",
"paint/oop_pixeltest.cc",
+ "paint/paint_cache_unittest.cc",
"paint/paint_filter_unittest.cc",
"paint/paint_image_unittest.cc",
"paint/paint_op_buffer_unittest.cc",
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index 5a453bed667..10a074fa7f1 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -58,6 +58,7 @@ vmpstr@chromium.org
# surfaces
fsamuel@chromium.org
kylechar@chromium.org
+samans@chromium.org
# input, scrolling
bokan@chromium.org
diff --git a/chromium/cc/PRESUBMIT.py b/chromium/cc/PRESUBMIT.py
index 3e27d70855f..89f5675b100 100644
--- a/chromium/cc/PRESUBMIT.py
+++ b/chromium/cc/PRESUBMIT.py
@@ -287,17 +287,3 @@ def CheckChangeOnUpload(input_api, output_api):
results += CheckForUseOfWrongClock(input_api, output_api)
results += FindUselessIfdefs(input_api, output_api)
return results
-
-def PostUploadHook(cl, change, output_api):
- """git cl upload will call this hook after the issue is created/modified.
-
- This hook adds an extra try bot list to the CL description in order to run
- Blink tests and additional GPU tests in addition to the CQ try bots.
- """
- return output_api.EnsureCQIncludeTrybotsAreAdded(
- cl,
- [
- 'master.tryserver.blink:linux_trusty_blink_rel',
- 'luci.chromium.try:android_optional_gpu_tests_rel',
- ],
- 'Automatically added Blink and Android GPU trybots for CQ.')
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index 696e69e8e9b..b78c578afd6 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -12,7 +12,7 @@
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/animation/animation.h"
#include "cc/animation/animation_delegate.h"
#include "cc/animation/animation_events.h"
diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc
index 104b16c7843..f4fd4805933 100644
--- a/chromium/cc/animation/animation_host_unittest.cc
+++ b/chromium/cc/animation/animation_host_unittest.cc
@@ -50,7 +50,8 @@ class AnimationHostTest : public AnimationTimelinesTest {
}
void SetOutputState(base::TimeDelta local_time) {
- MutatorOutputState::AnimationState state(worklet_animation_id_, local_time);
+ MutatorOutputState::AnimationState state(worklet_animation_id_);
+ state.local_times.push_back(local_time);
worklet_animation_impl_->SetOutputState(state);
}
@@ -262,7 +263,7 @@ void CreateScrollingNodeForElement(ElementId element_id,
// A scrolling node in cc has a corresponding transform node (See
// |ScrollNode::transform_id|). This setup here creates both nodes and links
// them as they would normally be. This more complete setup is necessary here
- // because ScrollTimelin depends on both nodes for its calculations.
+ // because ScrollTimeline depends on both nodes for its calculations.
TransformNode transform_node;
transform_node.scrolls = true;
transform_node.source_node_id = TransformTree::kRootNodeId;
@@ -327,8 +328,9 @@ TEST_F(AnimationHostTest, LayerTreeMutatorUpdateReflectsScrollAnimations) {
// Create scroll timeline that links scroll animation and worklet animation
// together. Use timerange so that we have 1:1 time & scroll mapping.
- auto scroll_timeline = std::make_unique<ScrollTimeline>(
- element_id, ScrollTimeline::Vertical, 100);
+ auto scroll_timeline =
+ std::make_unique<ScrollTimeline>(element_id, ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100);
// Create a worklet animation that is bound to the scroll timeline.
scoped_refptr<WorkletAnimation> worklet_animation(
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
index 2af7060976c..f5d216cd5ab 100644
--- a/chromium/cc/animation/element_animations.cc
+++ b/chromium/cc/animation/element_animations.cc
@@ -22,6 +22,22 @@
namespace cc {
+namespace {
+
+// After BlinkGenPropertyTrees, the targeted ElementId depends on the property
+// being mutated. If an ElementId is set on the KeyframeModel, we should apply
+// the mutation to the specific element.
+// TODO(flackr): Remove ElementId from ElementAnimations once all element
+// 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())
+ return keyframe_model->element_id();
+ return element_animations->element_id();
+}
+
+} // namespace
+
scoped_refptr<ElementAnimations> ElementAnimations::Create() {
return base::WrapRefCounted(new ElementAnimations());
}
@@ -262,9 +278,9 @@ void ElementAnimations::NotifyClientFloatAnimated(
DCHECK(keyframe_model->target_property_id() == TargetProperty::OPACITY);
opacity = base::ClampToRange(opacity, 0.0f, 1.0f);
if (KeyframeModelAffectsActiveElements(keyframe_model))
- OnOpacityAnimated(ElementListType::ACTIVE, opacity);
+ OnOpacityAnimated(ElementListType::ACTIVE, opacity, keyframe_model);
if (KeyframeModelAffectsPendingElements(keyframe_model))
- OnOpacityAnimated(ElementListType::PENDING, opacity);
+ OnOpacityAnimated(ElementListType::PENDING, opacity, keyframe_model);
}
void ElementAnimations::NotifyClientFilterAnimated(
@@ -272,9 +288,9 @@ void ElementAnimations::NotifyClientFilterAnimated(
int target_property_id,
KeyframeModel* keyframe_model) {
if (KeyframeModelAffectsActiveElements(keyframe_model))
- OnFilterAnimated(ElementListType::ACTIVE, filters);
+ OnFilterAnimated(ElementListType::ACTIVE, filters, keyframe_model);
if (KeyframeModelAffectsPendingElements(keyframe_model))
- OnFilterAnimated(ElementListType::PENDING, filters);
+ OnFilterAnimated(ElementListType::PENDING, filters, keyframe_model);
}
void ElementAnimations::NotifyClientTransformOperationsAnimated(
@@ -283,9 +299,9 @@ void ElementAnimations::NotifyClientTransformOperationsAnimated(
KeyframeModel* keyframe_model) {
gfx::Transform transform = operations.Apply();
if (KeyframeModelAffectsActiveElements(keyframe_model))
- OnTransformAnimated(ElementListType::ACTIVE, transform);
+ OnTransformAnimated(ElementListType::ACTIVE, transform, keyframe_model);
if (KeyframeModelAffectsPendingElements(keyframe_model))
- OnTransformAnimated(ElementListType::PENDING, transform);
+ OnTransformAnimated(ElementListType::PENDING, transform, keyframe_model);
}
void ElementAnimations::NotifyClientScrollOffsetAnimated(
@@ -293,9 +309,11 @@ void ElementAnimations::NotifyClientScrollOffsetAnimated(
int target_property_id,
KeyframeModel* keyframe_model) {
if (KeyframeModelAffectsActiveElements(keyframe_model))
- OnScrollOffsetAnimated(ElementListType::ACTIVE, scroll_offset);
+ OnScrollOffsetAnimated(ElementListType::ACTIVE, scroll_offset,
+ keyframe_model);
if (KeyframeModelAffectsPendingElements(keyframe_model))
- OnScrollOffsetAnimated(ElementListType::PENDING, scroll_offset);
+ OnScrollOffsetAnimated(ElementListType::PENDING, scroll_offset,
+ keyframe_model);
}
void ElementAnimations::UpdateClientAnimationState() {
@@ -395,40 +413,48 @@ bool ElementAnimations::IsCurrentlyAnimatingProperty(
}
void ElementAnimations::OnFilterAnimated(ElementListType list_type,
- const FilterOperations& filters) {
- DCHECK(element_id());
+ const FilterOperations& filters,
+ KeyframeModel* keyframe_model) {
+ ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
+ DCHECK(target_element_id);
DCHECK(animation_host());
DCHECK(animation_host()->mutator_host_client());
animation_host()->mutator_host_client()->SetElementFilterMutated(
- element_id(), list_type, filters);
+ target_element_id, list_type, filters);
}
void ElementAnimations::OnOpacityAnimated(ElementListType list_type,
- float opacity) {
- DCHECK(element_id());
+ float opacity,
+ KeyframeModel* keyframe_model) {
+ ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
+ DCHECK(target_element_id);
DCHECK(animation_host());
DCHECK(animation_host()->mutator_host_client());
animation_host()->mutator_host_client()->SetElementOpacityMutated(
- element_id(), list_type, opacity);
+ target_element_id, list_type, opacity);
}
void ElementAnimations::OnTransformAnimated(ElementListType list_type,
- const gfx::Transform& transform) {
- DCHECK(element_id());
+ const gfx::Transform& transform,
+ KeyframeModel* keyframe_model) {
+ ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
+ DCHECK(target_element_id);
DCHECK(animation_host());
DCHECK(animation_host()->mutator_host_client());
animation_host()->mutator_host_client()->SetElementTransformMutated(
- element_id(), list_type, transform);
+ target_element_id, list_type, transform);
}
void ElementAnimations::OnScrollOffsetAnimated(
ElementListType list_type,
- const gfx::ScrollOffset& scroll_offset) {
- DCHECK(element_id());
+ const gfx::ScrollOffset& scroll_offset,
+ KeyframeModel* keyframe_model) {
+ ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
+ DCHECK(target_element_id);
DCHECK(animation_host());
DCHECK(animation_host()->mutator_host_client());
animation_host()->mutator_host_client()->SetElementScrollOffsetMutated(
- element_id(), list_type, scroll_offset);
+ target_element_id, list_type, scroll_offset);
}
gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const {
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
index c7e68bbec14..7c51dc7900f 100644
--- a/chromium/cc/animation/element_animations.h
+++ b/chromium/cc/animation/element_animations.h
@@ -171,12 +171,17 @@ class CC_ANIMATION_EXPORT ElementAnimations
~ElementAnimations() override;
void OnFilterAnimated(ElementListType list_type,
- const FilterOperations& filters);
- void OnOpacityAnimated(ElementListType list_type, float opacity);
+ const FilterOperations& filters,
+ KeyframeModel* keyframe_model);
+ void OnOpacityAnimated(ElementListType list_type,
+ float opacity,
+ KeyframeModel* keyframe_model);
void OnTransformAnimated(ElementListType list_type,
- const gfx::Transform& transform);
+ const gfx::Transform& transform,
+ KeyframeModel* keyframe_model);
void OnScrollOffsetAnimated(ElementListType list_type,
- const gfx::ScrollOffset& scroll_offset);
+ const gfx::ScrollOffset& scroll_offset,
+ KeyframeModel* keyframe_model);
static TargetProperties GetPropertiesMaskForAnimationState();
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index 0c33cb7db6d..a276b7d00e5 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -27,8 +27,8 @@ struct PropertyAnimationState;
typedef size_t KeyframeEffectId;
-// An KeyframeEffect owns a group of KeyframeModels for a single target
-// (identified by a ElementId). It is responsible for managing the
+// A KeyframeEffect owns a group of KeyframeModels for a single target
+// (identified by an ElementId). It is responsible for managing the
// KeyframeModels' running states (starting, running, paused, etc), as well as
// ticking the KeyframeModels when it is requested to produce new outputs for a
// given time.
diff --git a/chromium/cc/animation/keyframe_model.cc b/chromium/cc/animation/keyframe_model.cc
index 10556098fc8..13b2f100cd1 100644
--- a/chromium/cc/animation/keyframe_model.cc
+++ b/chromium/cc/animation/keyframe_model.cc
@@ -61,6 +61,7 @@ std::unique_ptr<KeyframeModel> KeyframeModel::CreateImplInstance(
DCHECK(!is_controlling_instance_);
std::unique_ptr<KeyframeModel> to_return(
new KeyframeModel(curve_->Clone(), id_, group_, target_property_id_));
+ to_return->element_id_ = element_id_;
to_return->run_state_ = initial_run_state;
to_return->iterations_ = iterations_;
to_return->iteration_start_ = iteration_start_;
@@ -263,8 +264,7 @@ base::TimeDelta KeyframeModel::TrimLocalTimeToCurrentIteration(
}
void KeyframeModel::PushPropertiesTo(KeyframeModel* other) const {
- // Currently, we only push changes due to pausing and resuming KeyframeModels
- // on the main thread.
+ other->element_id_ = element_id_;
if (run_state_ == KeyframeModel::PAUSED ||
other->run_state_ == KeyframeModel::PAUSED) {
other->run_state_ = run_state_;
diff --git a/chromium/cc/animation/keyframe_model.h b/chromium/cc/animation/keyframe_model.h
index 329a986253f..39557caa3e4 100644
--- a/chromium/cc/animation/keyframe_model.h
+++ b/chromium/cc/animation/keyframe_model.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "cc/animation/animation_export.h"
+#include "cc/trees/element_id.h"
namespace cc {
@@ -69,6 +70,9 @@ class CC_ANIMATION_EXPORT KeyframeModel {
int group() const { return group_; }
int target_property_id() const { return target_property_id_; }
+ ElementId element_id() const { return element_id_; }
+ void set_element_id(ElementId element_id) { element_id_ = element_id; }
+
RunState run_state() const { return run_state_; }
void SetRunState(RunState run_state, base::TimeTicks monotonic_time);
@@ -212,6 +216,10 @@ class CC_ANIMATION_EXPORT KeyframeModel {
// properties until all KeyframeModels in the group have finished animating.
int group_;
+ // If specified, overrides the ElementId to apply this KeyframeModel's effect
+ // value on.
+ ElementId element_id_;
+
int target_property_id_;
RunState run_state_;
double iterations_;
diff --git a/chromium/cc/animation/scroll_offset_animations_impl.cc b/chromium/cc/animation/scroll_offset_animations_impl.cc
index 7c11c2d5281..ec4bafbd264 100644
--- a/chromium/cc/animation/scroll_offset_animations_impl.cc
+++ b/chromium/cc/animation/scroll_offset_animations_impl.cc
@@ -5,7 +5,7 @@
#include "cc/animation/scroll_offset_animations_impl.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/animation_timeline.h"
diff --git a/chromium/cc/animation/scroll_timeline.cc b/chromium/cc/animation/scroll_timeline.cc
index 63a56ec8584..14cfc971219 100644
--- a/chromium/cc/animation/scroll_timeline.cc
+++ b/chromium/cc/animation/scroll_timeline.cc
@@ -11,19 +11,36 @@
namespace cc {
+namespace {
+bool IsVertical(ScrollTimeline::ScrollDirection direction) {
+ return direction == ScrollTimeline::ScrollUp ||
+ direction == ScrollTimeline::ScrollDown;
+}
+
+bool IsReverse(ScrollTimeline::ScrollDirection direction) {
+ return direction == ScrollTimeline::ScrollUp ||
+ direction == ScrollTimeline::ScrollLeft;
+}
+} // namespace
+
ScrollTimeline::ScrollTimeline(base::Optional<ElementId> scroller_id,
- ScrollDirection orientation,
+ ScrollDirection direction,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset,
double time_range)
: active_id_(),
pending_id_(scroller_id),
- orientation_(orientation),
+ direction_(direction),
+ start_scroll_offset_(start_scroll_offset),
+ end_scroll_offset_(end_scroll_offset),
time_range_(time_range) {}
ScrollTimeline::~ScrollTimeline() {}
std::unique_ptr<ScrollTimeline> ScrollTimeline::CreateImplInstance() const {
- return std::make_unique<ScrollTimeline>(pending_id_, orientation_,
- time_range_);
+ return std::make_unique<ScrollTimeline>(pending_id_, direction_,
+ start_scroll_offset_,
+ end_scroll_offset_, time_range_);
}
double ScrollTimeline::CurrentTime(const ScrollTree& scroll_tree,
@@ -53,35 +70,76 @@ double ScrollTimeline::CurrentTime(const ScrollTree& scroll_tree,
gfx::ScrollOffset scroll_dimensions =
scroll_tree.MaxScrollOffset(scroll_node->id);
- double current_offset = (orientation_ == Vertical) ? offset.y() : offset.x();
- double max_offset = (orientation_ == Vertical) ? scroll_dimensions.y()
- : scroll_dimensions.x();
+ double max_offset =
+ IsVertical(direction_) ? scroll_dimensions.y() : scroll_dimensions.x();
+ double current_physical_offset =
+ IsVertical(direction_) ? offset.y() : offset.x();
+ double current_offset = IsReverse(direction_)
+ ? max_offset - current_physical_offset
+ : current_physical_offset;
+ DCHECK_GE(max_offset, 0);
+ DCHECK_GE(current_offset, 0);
+
+ double resolved_start_scroll_offset = start_scroll_offset_.value_or(0);
+ double resolved_end_scroll_offset = end_scroll_offset_.value_or(max_offset);
// 3. If current scroll offset is less than startScrollOffset, return an
// unresolved time value if fill is none or forwards, or 0 otherwise.
- // TODO(smcgruer): Implement |startScrollOffset| and |fill|.
+ // TODO(smcgruer): Implement |fill|.
+ if (current_offset < resolved_start_scroll_offset) {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
// 4. If current scroll offset is greater than or equal to endScrollOffset,
// return an unresolved time value if fill is none or backwards, or the
// effective time range otherwise.
- // TODO(smcgruer): Implement |endScrollOffset| and |fill|.
+ // TODO(smcgruer): Implement |fill|.
+ //
+ // Note we deliberately break the spec here by only returning if the current
+ // offset is strictly greater, as that is more in line with the web animation
+ // spec. See https://github.com/WICG/scroll-animations/issues/19
+ if (current_offset > resolved_end_scroll_offset) {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+
+ // This is not by the spec, but avoids both negative current time and a
+ // division by zero issue. See
+ // https://github.com/WICG/scroll-animations/issues/20 and
+ // https://github.com/WICG/scroll-animations/issues/21
+ if (resolved_start_scroll_offset >= resolved_end_scroll_offset) {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
// 5. Return the result of evaluating the following expression:
// ((current scroll offset - startScrollOffset) /
// (endScrollOffset - startScrollOffset)) * effective time range
-
- return (std::abs(current_offset) / max_offset) * time_range_;
+ return ((current_offset - resolved_start_scroll_offset) /
+ (resolved_end_scroll_offset - resolved_start_scroll_offset)) *
+ time_range_;
}
void ScrollTimeline::PushPropertiesTo(ScrollTimeline* impl_timeline) {
DCHECK(impl_timeline);
impl_timeline->pending_id_ = pending_id_;
+ // TODO(smcgruer): This leads to incorrect behavior in the current design,
+ // because we end up using the pending start/end scroll offset for the active
+ // tree too. Instead we need to either split these (like pending_id_ and
+ // active_id_) or have a ScrollTimeline per tree.
+ impl_timeline->start_scroll_offset_ = start_scroll_offset_;
+ impl_timeline->end_scroll_offset_ = end_scroll_offset_;
}
void ScrollTimeline::PromoteScrollTimelinePendingToActive() {
active_id_ = pending_id_;
}
+void ScrollTimeline::UpdateStartAndEndScrollOffsets(
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset) {
+ start_scroll_offset_ = start_scroll_offset;
+ end_scroll_offset_ = end_scroll_offset;
+}
+
void ScrollTimeline::SetScrollerId(base::Optional<ElementId> pending_id) {
// When the scroller id changes it will first be modified in the pending tree.
// Then later (when the pending tree is promoted to active)
diff --git a/chromium/cc/animation/scroll_timeline.h b/chromium/cc/animation/scroll_timeline.h
index 1efd2a77963..c1a1dc34d76 100644
--- a/chromium/cc/animation/scroll_timeline.h
+++ b/chromium/cc/animation/scroll_timeline.h
@@ -17,18 +17,20 @@ class ScrollTree;
// progress of scrolling in some scroll container.
//
// This is the compositor-side representation of the web concept expressed in
-// https://wicg.github.io/scroll-animations/#scrolltimeline-interface. There are
-// differences between this class and the web definition of a ScrollTimeline.
-// For example the compositor does not know (or care) about 'writing modes', so
-// this class only tracks whether the ScrollTimeline orientation is horizontal
-// or vertical. Blink is expected to resolve any such 'web' requirements and
-// construct/update the compositor ScrollTimeline accordingly.
+// https://wicg.github.io/scroll-animations/#scrolltimeline-interface.
class CC_ANIMATION_EXPORT ScrollTimeline {
public:
- enum ScrollDirection { Horizontal, Vertical };
+ enum ScrollDirection {
+ ScrollUp,
+ ScrollDown,
+ ScrollLeft,
+ ScrollRight,
+ };
ScrollTimeline(base::Optional<ElementId> scroller_id,
- ScrollDirection orientation,
+ ScrollDirection direction,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset,
double time_range);
virtual ~ScrollTimeline();
@@ -43,6 +45,9 @@ class CC_ANIMATION_EXPORT ScrollTimeline {
bool is_active_tree) const;
void SetScrollerId(base::Optional<ElementId> scroller_id);
+ void UpdateStartAndEndScrollOffsets(
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset);
void PushPropertiesTo(ScrollTimeline* impl_timeline);
@@ -55,9 +60,12 @@ class CC_ANIMATION_EXPORT ScrollTimeline {
base::Optional<ElementId> active_id_;
base::Optional<ElementId> pending_id_;
- // The orientation of the ScrollTimeline indicates which axis of the scroller
- // it should base its current time on - either the horizontal or vertical.
- ScrollDirection orientation_;
+ // The direction of the ScrollTimeline indicates which axis of the scroller
+ // it should base its current time on, and where the origin point is.
+ ScrollDirection direction_;
+
+ base::Optional<double> start_scroll_offset_;
+ base::Optional<double> end_scroll_offset_;
// A ScrollTimeline maps from the scroll offset in the scroller to a time
// value based on a 'time range'. See the implementation of CurrentTime or the
diff --git a/chromium/cc/animation/scroll_timeline_unittest.cc b/chromium/cc/animation/scroll_timeline_unittest.cc
index 686ee560bf9..0611014d9df 100644
--- a/chromium/cc/animation/scroll_timeline_unittest.cc
+++ b/chromium/cc/animation/scroll_timeline_unittest.cc
@@ -11,6 +11,8 @@
namespace cc {
+namespace {
+
void SetScrollOffset(PropertyTrees* property_trees,
ElementId scroller_id,
gfx::ScrollOffset offset) {
@@ -48,6 +50,19 @@ void CreateScrollingElement(PropertyTrees* property_trees,
property_trees->element_id_to_scroll_node_index[scroller_id] = scroll_node_id;
}
+// Helper method to calculate the current time, implementing only step 5 of
+// https://wicg.github.io/scroll-animations/#current-time-algorithm
+double CalculateCurrentTime(double current_scroll_offset,
+ double start_scroll_offset,
+ double end_scroll_offset,
+ double effective_time_range) {
+ return ((current_scroll_offset - start_scroll_offset) /
+ (end_scroll_offset - start_scroll_offset)) *
+ effective_time_range;
+}
+
+} // namespace
+
class ScrollTimelineTest : public ::testing::Test {
public:
ScrollTimelineTest()
@@ -83,10 +98,10 @@ TEST_F(ScrollTimelineTest, BasicCurrentTimeCalculations) {
// just compute one edge and use it for vertical/horizontal.
double time_range = content_size().height() - container_size().height();
- ScrollTimeline vertical_timeline(scroller_id(), ScrollTimeline::Vertical,
- time_range);
- ScrollTimeline horizontal_timeline(scroller_id(), ScrollTimeline::Horizontal,
- time_range);
+ ScrollTimeline vertical_timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, time_range);
+ ScrollTimeline horizontal_timeline(scroller_id(), ScrollTimeline::ScrollRight,
+ base::nullopt, base::nullopt, time_range);
// Unscrolled, both timelines should read a current time of 0.
SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset());
@@ -105,7 +120,8 @@ TEST_F(ScrollTimelineTest, BasicCurrentTimeCalculations) {
TEST_F(ScrollTimelineTest, CurrentTimeIsAdjustedForTimeRange) {
// Here we set a time range to 100, which gives the current time the form of
// 'percentage scrolled'.
- ScrollTimeline timeline(scroller_id(), ScrollTimeline::Vertical, 100);
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100);
double halfwayY = (content_size().height() - container_size().height()) / 2.;
SetScrollOffset(&property_trees(), scroller_id(),
@@ -137,7 +153,8 @@ TEST_F(ScrollTimelineTest, ActiveTimeIsSetOnlyAfterPromotion) {
double halfwayY = (content_size().height() - container_size().height()) / 2.;
SetScrollOffset(&pending_tree, scroller_id, gfx::ScrollOffset(0, halfwayY));
- ScrollTimeline main_timeline(scroller_id, ScrollTimeline::Vertical, 100);
+ ScrollTimeline main_timeline(scroller_id, ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100);
// Now create an impl version of the ScrollTimeline. Initilly this should only
// have a pending scroller id, as the active tree may not yet have the
@@ -163,7 +180,8 @@ TEST_F(ScrollTimelineTest, ActiveTimeIsSetOnlyAfterPromotion) {
TEST_F(ScrollTimelineTest, CurrentTimeIsAdjustedForPixelSnapping) {
double time_range = content_size().height() - container_size().height();
- ScrollTimeline timeline(scroller_id(), ScrollTimeline::Vertical, time_range);
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, time_range);
SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 50));
@@ -176,4 +194,85 @@ TEST_F(ScrollTimelineTest, CurrentTimeIsAdjustedForPixelSnapping) {
EXPECT_FLOAT_EQ(49.5, timeline.CurrentTime(scroll_tree(), false));
}
+TEST_F(ScrollTimelineTest, CurrentTimeHandlesStartScrollOffset) {
+ double time_range = content_size().height() - container_size().height();
+ const double start_scroll_offset = 20;
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ start_scroll_offset, base::nullopt, time_range);
+
+ // Unscrolled, the timeline should read a current time of unresolved, since
+ // the current offset (0) will be less than the startScrollOffset.
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset());
+ EXPECT_TRUE(std::isnan(timeline.CurrentTime(scroll_tree(), false)));
+
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 19));
+ EXPECT_TRUE(std::isnan(timeline.CurrentTime(scroll_tree(), false)));
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 20));
+ EXPECT_FLOAT_EQ(0, timeline.CurrentTime(scroll_tree(), false));
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 50));
+ EXPECT_FLOAT_EQ(
+ CalculateCurrentTime(50, start_scroll_offset, time_range, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 200));
+ EXPECT_FLOAT_EQ(
+ CalculateCurrentTime(200, start_scroll_offset, time_range, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+}
+
+TEST_F(ScrollTimelineTest, CurrentTimeHandlesEndScrollOffset) {
+ double time_range = content_size().height() - container_size().height();
+ const double end_scroll_offset = time_range - 20;
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ base::nullopt, end_scroll_offset, time_range);
+
+ SetScrollOffset(&property_trees(), scroller_id(),
+ gfx::ScrollOffset(0, time_range));
+ EXPECT_TRUE(std::isnan(timeline.CurrentTime(scroll_tree(), false)));
+ SetScrollOffset(&property_trees(), scroller_id(),
+ gfx::ScrollOffset(0, time_range - 20));
+ EXPECT_FLOAT_EQ(
+ CalculateCurrentTime(time_range - 20, 0, end_scroll_offset, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+ SetScrollOffset(&property_trees(), scroller_id(),
+ gfx::ScrollOffset(0, time_range - 50));
+ EXPECT_FLOAT_EQ(
+ CalculateCurrentTime(time_range - 50, 0, end_scroll_offset, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+ SetScrollOffset(&property_trees(), scroller_id(),
+ gfx::ScrollOffset(0, time_range - 200));
+ EXPECT_FLOAT_EQ(
+ CalculateCurrentTime(time_range - 200, 0, end_scroll_offset, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+}
+
+TEST_F(ScrollTimelineTest, CurrentTimeHandlesCombinedStartAndEndScrollOffset) {
+ double time_range = content_size().height() - container_size().height();
+ double start_scroll_offset = 20;
+ double end_scroll_offset = time_range - 50;
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ start_scroll_offset, end_scroll_offset, time_range);
+ SetScrollOffset(&property_trees(), scroller_id(),
+ gfx::ScrollOffset(0, time_range - 150));
+ EXPECT_FLOAT_EQ(CalculateCurrentTime(time_range - 150, start_scroll_offset,
+ end_scroll_offset, time_range),
+ timeline.CurrentTime(scroll_tree(), false));
+}
+
+TEST_F(ScrollTimelineTest, CurrentTimeHandlesEqualStartAndEndScrollOffset) {
+ double time_range = content_size().height() - container_size().height();
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown, 20, 20,
+ time_range);
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 150));
+ EXPECT_TRUE(std::isnan(timeline.CurrentTime(scroll_tree(), false)));
+}
+
+TEST_F(ScrollTimelineTest,
+ CurrentTimeHandlesStartOffsetLargerThanEndScrollOffset) {
+ double time_range = content_size().height() - container_size().height();
+ ScrollTimeline timeline(scroller_id(), ScrollTimeline::ScrollDown, 50, 10,
+ time_range);
+ SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 150));
+ EXPECT_TRUE(std::isnan(timeline.CurrentTime(scroll_tree(), false)));
+}
+
} // namespace cc
diff --git a/chromium/cc/animation/worklet_animation.cc b/chromium/cc/animation/worklet_animation.cc
index 34a9746df3c..b6f359038ef 100644
--- a/chromium/cc/animation/worklet_animation.cc
+++ b/chromium/cc/animation/worklet_animation.cc
@@ -108,12 +108,19 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
double current_time =
CurrentTime(monotonic_time, scroll_tree, is_active_tree);
+ // TODO(yigu): If current_time becomes newly unresolved and last_current_time_
+ // is resolved, we apply the last current time to the animation if the scroll
+ // timeline becomes newly inactive. See https://crbug.com/906050.
last_current_time_ = current_time;
switch (state_) {
case State::PENDING:
- input_state->Add(
- {worklet_animation_id(), name(), current_time, CloneOptions()});
+ // TODO(yigu): cc side WorkletAnimation is only capable of handling single
+ // keyframe effect at the moment. We should pass in the number of effects
+ // once Worklet Group Effect is fully implemented in cc.
+ // https://crbug.com/767043.
+ input_state->Add({worklet_animation_id(), name(), current_time,
+ CloneOptions(), 1 /* num_effects */});
state_ = State::RUNNING;
break;
case State::RUNNING:
@@ -127,7 +134,10 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
void WorkletAnimation::SetOutputState(
const MutatorOutputState::AnimationState& state) {
- local_time_ = state.local_time;
+ // TODO(yigu): cc side WorkletAnimation is only capable of handling single
+ // keyframe effect at the moment. https://crbug.com/767043.
+ DCHECK_EQ(state.local_times.size(), 1u);
+ local_time_ = state.local_times[0];
}
// TODO(crbug.com/780151): Multiply the result by the play back rate.
@@ -159,11 +169,15 @@ bool WorkletAnimation::NeedsUpdate(base::TimeTicks monotonic_time,
return needs_update;
}
-void WorkletAnimation::SetScrollSourceId(
- base::Optional<ElementId> scroller_id) {
+void WorkletAnimation::UpdateScrollTimeline(
+ base::Optional<ElementId> scroller_id,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset) {
// Calling this method implies that we are a ScrollTimeline based animation,
// so the below call is done unchecked.
scroll_timeline_->SetScrollerId(scroller_id);
+ scroll_timeline_->UpdateStartAndEndScrollOffsets(start_scroll_offset,
+ end_scroll_offset);
SetNeedsPushProperties();
}
diff --git a/chromium/cc/animation/worklet_animation.h b/chromium/cc/animation/worklet_animation.h
index 1ab919d555e..fc8e67e0f01 100644
--- a/chromium/cc/animation/worklet_animation.h
+++ b/chromium/cc/animation/worklet_animation.h
@@ -60,10 +60,11 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
void PushPropertiesTo(Animation* animation_impl) override;
- // Should be called when the scroll source of the ScrollTimeline attached to
- // this animation has a change in ElementId. Such a change happens when the
- // scroll source changes compositing state.
- void SetScrollSourceId(base::Optional<ElementId> scroller_id);
+ // Should be called when the ScrollTimeline attached to this animation has a
+ // change, such as when the scroll source changes ElementId.
+ void UpdateScrollTimeline(base::Optional<ElementId> scroller_id,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset);
// Should be called when the pending tree is promoted to active, as this may
// require updating the ElementId for the ScrollTimeline scroll source.
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index 673c2cc1985..c8d009f4adf 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -49,7 +49,11 @@ class WorkletAnimationTest : public AnimationTimelinesTest {
class MockScrollTimeline : public ScrollTimeline {
public:
MockScrollTimeline()
- : ScrollTimeline(ElementId(), ScrollTimeline::Vertical, 0) {}
+ : ScrollTimeline(ElementId(),
+ ScrollTimeline::ScrollDown,
+ base::nullopt,
+ base::nullopt,
+ 0) {}
MOCK_CONST_METHOD2(CurrentTime, double(const ScrollTree&, bool));
};
@@ -64,8 +68,10 @@ TEST_F(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe) {
false /* not impl instance*/, std::move(effect)));
EXPECT_CALL(*mock_effect, Tick(_)).Times(0);
- worklet_animation->SetOutputState(
- {worklet_animation_id_, base::TimeDelta::FromSecondsD(1)});
+
+ MutatorOutputState::AnimationState state(worklet_animation_id_);
+ state.local_times.push_back(base::TimeDelta::FromSecondsD(1));
+ worklet_animation->SetOutputState(state);
worklet_animation->Tick(base::TimeTicks());
}
@@ -87,7 +93,9 @@ TEST_F(WorkletAnimationTest, LocalTimeIsUsedWhenTicking) {
keyframe_model->set_needs_synchronized_start_time(false);
base::TimeDelta local_time = base::TimeDelta::FromSecondsD(duration / 2);
- worklet_animation_->SetOutputState({worklet_animation_id_, local_time});
+ MutatorOutputState::AnimationState state(worklet_animation_id_);
+ state.local_times.push_back(local_time);
+ worklet_animation_->SetOutputState(state);
worklet_animation_->Tick(base::TimeTicks());
diff --git a/chromium/cc/base/completion_event.h b/chromium/cc/base/completion_event.h
index 0c620db4e72..5c9debd64f4 100644
--- a/chromium/cc/base/completion_event.h
+++ b/chromium/cc/base/completion_event.h
@@ -39,7 +39,8 @@ class CompletionEvent {
DCHECK(!waited_);
waited_ = true;
#endif
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ // http://crbug.com/902653
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
event_.Wait();
}
@@ -48,7 +49,8 @@ class CompletionEvent {
DCHECK(!waited_);
waited_ = true;
#endif
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ // http://crbug.com/902653
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
if (event_.TimedWait(max_time))
return true;
#if DCHECK_IS_ON()
diff --git a/chromium/cc/base/devtools_instrumentation.cc b/chromium/cc/base/devtools_instrumentation.cc
index d6f77f027e3..fab22da704c 100644
--- a/chromium/cc/base/devtools_instrumentation.cc
+++ b/chromium/cc/base/devtools_instrumentation.cc
@@ -8,9 +8,8 @@ namespace cc {
namespace devtools_instrumentation {
namespace internal {
-const char kCategory[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
-const char kCategoryFrame[] =
- TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame");
+constexpr const char CategoryName::CategoryName::kTimeline[];
+constexpr const char CategoryName::CategoryName::kTimelineFrame[];
const char kData[] = "data";
const char kFrameId[] = "frameId";
const char kLayerId[] = "layerId";
@@ -36,13 +35,14 @@ ScopedImageDecodeTask::ScopedImageDecodeTask(const void* image_ptr,
: decode_type_(decode_type),
task_type_(task_type),
start_time_(base::TimeTicks::Now()) {
- TRACE_EVENT_BEGIN1(internal::kCategory, internal::kImageDecodeTask,
- internal::kPixelRefId,
+ TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline,
+ internal::kImageDecodeTask, internal::kPixelRefId,
reinterpret_cast<uint64_t>(image_ptr));
}
ScopedImageDecodeTask::~ScopedImageDecodeTask() {
- TRACE_EVENT_END0(internal::kCategory, internal::kImageDecodeTask);
+ TRACE_EVENT_END0(internal::CategoryName::kTimeline,
+ internal::kImageDecodeTask);
base::TimeDelta duration = base::TimeTicks::Now() - start_time_;
switch (task_type_) {
case kInRaster:
diff --git a/chromium/cc/base/devtools_instrumentation.h b/chromium/cc/base/devtools_instrumentation.h
index 0562877ed4a..0697422a428 100644
--- a/chromium/cc/base/devtools_instrumentation.h
+++ b/chromium/cc/base/devtools_instrumentation.h
@@ -12,15 +12,21 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/base_export.h"
namespace cc {
namespace devtools_instrumentation {
namespace internal {
-CC_BASE_EXPORT extern const char kCategory[];
-CC_BASE_EXPORT extern const char kCategoryFrame[];
+struct CC_BASE_EXPORT CategoryName {
+ // Put these strings into a struct to allow external linkage.
+ static constexpr const char kTimeline[] =
+ TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
+ static constexpr const char kTimelineFrame[] =
+ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame");
+};
+
CC_BASE_EXPORT extern const char kData[];
CC_BASE_EXPORT extern const char kFrameId[];
CC_BASE_EXPORT extern const char kLayerId[];
@@ -44,10 +50,12 @@ class CC_BASE_EXPORT ScopedLayerTask {
public:
ScopedLayerTask(const char* event_name, int layer_id)
: event_name_(event_name) {
- TRACE_EVENT_BEGIN1(internal::kCategory, event_name_, internal::kLayerId,
- layer_id);
+ TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline, event_name_,
+ internal::kLayerId, layer_id);
+ }
+ ~ScopedLayerTask() {
+ TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_);
}
- ~ScopedLayerTask() { TRACE_EVENT_END0(internal::kCategory, event_name_); }
private:
const char* event_name_;
@@ -78,10 +86,13 @@ class CC_BASE_EXPORT ScopedLayerTreeTask {
int layer_id,
int layer_tree_host_id)
: event_name_(event_name) {
- TRACE_EVENT_BEGIN2(internal::kCategory, event_name_, internal::kLayerId,
- layer_id, internal::kLayerTreeId, layer_tree_host_id);
+ TRACE_EVENT_BEGIN2(internal::CategoryName::kTimeline, event_name_,
+ internal::kLayerId, layer_id, internal::kLayerTreeId,
+ layer_tree_host_id);
+ }
+ ~ScopedLayerTreeTask() {
+ TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_);
}
- ~ScopedLayerTreeTask() { TRACE_EVENT_END0(internal::kCategory, event_name_); }
private:
const char* event_name_;
@@ -92,11 +103,13 @@ class CC_BASE_EXPORT ScopedLayerTreeTask {
struct CC_BASE_EXPORT ScopedCommitTrace {
public:
explicit ScopedCommitTrace(int layer_tree_host_id) {
- TRACE_EVENT_BEGIN1(internal::kCategory, internal::kCompositeLayers,
- internal::kLayerTreeId, layer_tree_host_id);
+ TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline,
+ internal::kCompositeLayers, internal::kLayerTreeId,
+ layer_tree_host_id);
}
~ScopedCommitTrace() {
- TRACE_EVENT_END0(internal::kCategory, internal::kCompositeLayers);
+ TRACE_EVENT_END0(internal::CategoryName::kTimeline,
+ internal::kCompositeLayers);
}
private:
@@ -104,11 +117,13 @@ struct CC_BASE_EXPORT ScopedCommitTrace {
};
struct CC_BASE_EXPORT ScopedLayerObjectTracker
- : public base::trace_event::TraceScopedTrackableObject<int> {
+ : public base::trace_event::
+ TraceScopedTrackableObject<int, internal::CategoryName::kTimeline> {
explicit ScopedLayerObjectTracker(int layer_id)
- : base::trace_event::TraceScopedTrackableObject<int>(internal::kCategory,
- internal::kLayerId,
- layer_id) {}
+ : base::trace_event::
+ TraceScopedTrackableObject<int, internal::CategoryName::kTimeline>(
+ internal::kLayerId,
+ layer_id) {}
private:
DISALLOW_COPY_AND_ASSIGN(ScopedLayerObjectTracker);
@@ -116,26 +131,27 @@ struct CC_BASE_EXPORT ScopedLayerObjectTracker
inline void CC_BASE_EXPORT DidActivateLayerTree(int layer_tree_host_id,
int frame_id) {
- TRACE_EVENT_INSTANT2(internal::kCategoryFrame, internal::kActivateLayerTree,
- TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId,
- layer_tree_host_id, internal::kFrameId, frame_id);
+ TRACE_EVENT_INSTANT2(internal::CategoryName::kTimelineFrame,
+ internal::kActivateLayerTree, TRACE_EVENT_SCOPE_THREAD,
+ internal::kLayerTreeId, layer_tree_host_id,
+ internal::kFrameId, frame_id);
}
inline void CC_BASE_EXPORT DidBeginFrame(int layer_tree_host_id) {
- TRACE_EVENT_INSTANT1(internal::kCategoryFrame, internal::kBeginFrame,
- TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId,
- layer_tree_host_id);
+ TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame,
+ internal::kBeginFrame, TRACE_EVENT_SCOPE_THREAD,
+ internal::kLayerTreeId, layer_tree_host_id);
}
inline void CC_BASE_EXPORT DidDrawFrame(int layer_tree_host_id) {
- TRACE_EVENT_INSTANT1(internal::kCategoryFrame, internal::kDrawFrame,
- TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId,
- layer_tree_host_id);
+ TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame,
+ internal::kDrawFrame, TRACE_EVENT_SCOPE_THREAD,
+ internal::kLayerTreeId, layer_tree_host_id);
}
inline void CC_BASE_EXPORT DidRequestMainThreadFrame(int layer_tree_host_id) {
TRACE_EVENT_INSTANT1(
- internal::kCategoryFrame, internal::kRequestMainThreadFrame,
+ internal::CategoryName::kTimelineFrame, internal::kRequestMainThreadFrame,
TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id);
}
@@ -150,7 +166,7 @@ BeginMainThreadFrameData(int frame_id) {
inline void CC_BASE_EXPORT WillBeginMainThreadFrame(int layer_tree_host_id,
int frame_id) {
TRACE_EVENT_INSTANT2(
- internal::kCategoryFrame, internal::kBeginMainThreadFrame,
+ internal::CategoryName::kTimelineFrame, internal::kBeginMainThreadFrame,
TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id,
internal::kData, BeginMainThreadFrameData(frame_id));
}
@@ -166,7 +182,7 @@ NeedsBeginFrameData(bool needs_begin_frame) {
inline void CC_BASE_EXPORT NeedsBeginFrameChanged(int layer_tree_host_id,
bool new_value) {
TRACE_EVENT_INSTANT2(
- internal::kCategoryFrame, internal::kNeedsBeginFrameChanged,
+ internal::CategoryName::kTimelineFrame, internal::kNeedsBeginFrameChanged,
TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id,
internal::kData, NeedsBeginFrameData(new_value));
}
diff --git a/chromium/cc/base/math_util.cc b/chromium/cc/base/math_util.cc
index 7ac7fb42f5e..d212a733474 100644
--- a/chromium/cc/base/math_util.cc
+++ b/chromium/cc/base/math_util.cc
@@ -11,7 +11,7 @@
#include <xmmintrin.h>
#endif
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "ui/gfx/geometry/angle_conversions.h"
#include "ui/gfx/geometry/quad_f.h"
diff --git a/chromium/cc/base/region.cc b/chromium/cc/base/region.cc
index 5653634e8fa..3187693ce30 100644
--- a/chromium/cc/base/region.cc
+++ b/chromium/cc/base/region.cc
@@ -6,7 +6,7 @@
#include <stddef.h>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/base/simple_enclosed_region.h"
#include "ui/gfx/geometry/vector2d.h"
diff --git a/chromium/cc/base/rtree.h b/chromium/cc/base/rtree.h
index d6a1e8d8da8..840eaabe079 100644
--- a/chromium/cc/base/rtree.h
+++ b/chromium/cc/base/rtree.h
@@ -61,12 +61,12 @@ class RTree {
// Given a query rect, returns elements that intersect the rect. Elements are
// returned in the order they appeared in the initial container.
- std::vector<T> Search(const gfx::Rect& query) const;
+ void Search(const gfx::Rect& query, std::vector<T>* results) const;
// Given a query rect, returns non-owning pointers to elements that intersect
// the rect. Elements are returned in the order they appeared in the initial
// container.
- std::vector<const T*> SearchRefs(const gfx::Rect& query) const;
+ void SearchRefs(const gfx::Rect& query, std::vector<const T*>* results) const;
// Returns the total bounds of all items in this rtree.
gfx::Rect GetBounds() const;
@@ -288,19 +288,18 @@ auto RTree<T>::BuildRecursive(std::vector<Branch<T>>* branches, int level)
}
template <typename T>
-std::vector<T> RTree<T>::Search(const gfx::Rect& query) const {
- std::vector<T> results;
+void RTree<T>::Search(const gfx::Rect& query, std::vector<T>* results) const {
+ results->clear();
if (num_data_elements_ > 0 && query.Intersects(root_.bounds))
- SearchRecursive(root_.subtree, query, &results);
- return results;
+ SearchRecursive(root_.subtree, query, results);
}
template <typename T>
-std::vector<const T*> RTree<T>::SearchRefs(const gfx::Rect& query) const {
- std::vector<const T*> results;
+void RTree<T>::SearchRefs(const gfx::Rect& query,
+ std::vector<const T*>* results) const {
+ results->clear();
if (num_data_elements_ > 0 && query.Intersects(root_.bounds))
- SearchRefsRecursive(root_.subtree, query, &results);
- return results;
+ SearchRefsRecursive(root_.subtree, query, results);
}
template <typename T>
diff --git a/chromium/cc/base/rtree_perftest.cc b/chromium/cc/base/rtree_perftest.cc
index e7c70d5b1f2..70d44bcd843 100644
--- a/chromium/cc/base/rtree_perftest.cc
+++ b/chromium/cc/base/rtree_perftest.cc
@@ -58,7 +58,9 @@ class RTreePerfTest : public testing::Test {
timer_.Reset();
do {
- Accumulate(rtree.Search(queries[query_index]));
+ std::vector<size_t> results;
+ rtree.Search(queries[query_index], &results);
+ Accumulate(results);
query_index = (query_index + 1) % queries.size();
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
diff --git a/chromium/cc/base/rtree_unittest.cc b/chromium/cc/base/rtree_unittest.cc
index d5242a1a4aa..e5b937942d9 100644
--- a/chromium/cc/base/rtree_unittest.cc
+++ b/chromium/cc/base/rtree_unittest.cc
@@ -35,20 +35,21 @@ TEST(RTreeTest, NoOverlap) {
RTree<size_t> rtree;
rtree.Build(rects);
- std::vector<size_t> results = rtree.Search(gfx::Rect(0, 0, 50, 50));
+ std::vector<size_t> results;
+ rtree.Search(gfx::Rect(0, 0, 50, 50), &results);
ASSERT_EQ(2500u, results.size());
// Note that the results have to be sorted.
for (size_t i = 0; i < 2500; ++i) {
ASSERT_EQ(results[i], i);
}
- results = rtree.Search(gfx::Rect(0, 0, 50, 49));
+ rtree.Search(gfx::Rect(0, 0, 50, 49), &results);
ASSERT_EQ(2450u, results.size());
for (size_t i = 0; i < 2450; ++i) {
ASSERT_EQ(results[i], i);
}
- results = rtree.Search(gfx::Rect(5, 6, 1, 1));
+ rtree.Search(gfx::Rect(5, 6, 1, 1), &results);
ASSERT_EQ(1u, results.size());
EXPECT_EQ(6u * 50 + 5u, results[0]);
}
@@ -64,14 +65,15 @@ TEST(RTreeTest, Overlap) {
RTree<size_t> rtree;
rtree.Build(rects);
- std::vector<size_t> results = rtree.Search(gfx::Rect(0, 0, 1, 1));
+ std::vector<size_t> results;
+ rtree.Search(gfx::Rect(0, 0, 1, 1), &results);
ASSERT_EQ(2500u, results.size());
// Both the checks for the elements assume elements are sorted.
for (size_t i = 0; i < 2500; ++i) {
ASSERT_EQ(results[i], i);
}
- results = rtree.Search(gfx::Rect(0, 49, 1, 1));
+ rtree.Search(gfx::Rect(0, 49, 1, 1), &results);
ASSERT_EQ(50u, results.size());
for (size_t i = 0; i < 50; ++i) {
EXPECT_EQ(results[i], 2450u + i);
@@ -100,9 +102,13 @@ TEST(RTreeTest, SortedResults) {
for (int y = 0; y < 50; ++y) {
for (int x = 0; x < 50; ++x) {
- VerifySorted(rtree.Search(gfx::Rect(x, y, 1, 1)));
- VerifySorted(rtree.Search(gfx::Rect(x, y, 50, 1)));
- VerifySorted(rtree.Search(gfx::Rect(x, y, 1, 50)));
+ std::vector<size_t> results;
+ rtree.Search(gfx::Rect(x, y, 1, 1), &results);
+ VerifySorted(results);
+ rtree.Search(gfx::Rect(x, y, 50, 1), &results);
+ VerifySorted(results);
+ rtree.Search(gfx::Rect(x, y, 1, 50), &results);
+ VerifySorted(results);
}
}
}
@@ -172,11 +178,12 @@ TEST(RTreeTest, Payload) {
[](const Container& items, size_t index) { return items[index].first; },
[](const Container& items, size_t index) { return items[index].second; });
- auto results = rtree.Search(gfx::Rect(0, 0, 1, 1));
+ std::vector<float> results;
+ rtree.Search(gfx::Rect(0, 0, 1, 1), &results);
ASSERT_EQ(1u, results.size());
EXPECT_FLOAT_EQ(10.f, results[0]);
- results = rtree.Search(gfx::Rect(5, 5, 10, 10));
+ rtree.Search(gfx::Rect(5, 5, 10, 10), &results);
ASSERT_EQ(4u, results.size());
// Items returned should be in the order they were inserted.
EXPECT_FLOAT_EQ(40.f, results[0]);
diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc
index 8b70bc435c2..d363fe84b1d 100644
--- a/chromium/cc/base/switches.cc
+++ b/chromium/cc/base/switches.cc
@@ -84,8 +84,7 @@ const char kUIShowSurfaceDamageRects[] = "ui-show-surface-damage-rects";
const char kShowScreenSpaceRects[] = "show-screenspace-rects";
const char kUIShowScreenSpaceRects[] = "ui-show-screenspace-rects";
-// Switches cc machinery to use layer lists instead of layer trees
-const char kEnableLayerLists[] = "enable-layer-lists";
+// Switches the ui compositor to use layer lists instead of layer trees.
const char kUIEnableLayerLists[] = "ui-enable-layer-lists";
// Prevents the layer tree unit tests from timing out.
diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h
index 7234ee4024c..fe8de281021 100644
--- a/chromium/cc/base/switches.h
+++ b/chromium/cc/base/switches.h
@@ -44,7 +44,6 @@ CC_BASE_EXPORT extern const char kShowSurfaceDamageRects[];
CC_BASE_EXPORT extern const char kUIShowSurfaceDamageRects[];
CC_BASE_EXPORT extern const char kShowScreenSpaceRects[];
CC_BASE_EXPORT extern const char kUIShowScreenSpaceRects[];
-CC_BASE_EXPORT extern const char kEnableLayerLists[];
CC_BASE_EXPORT extern const char kUIEnableLayerLists[];
CC_BASE_EXPORT extern const char kCompositedRenderPassBorders[];
CC_BASE_EXPORT extern const char kCompositedSurfaceBorders[];
diff --git a/chromium/cc/benchmarks/benchmark_instrumentation.h b/chromium/cc/benchmarks/benchmark_instrumentation.h
index 9b5e5efef97..d946c6e6b25 100644
--- a/chromium/cc/benchmarks/benchmark_instrumentation.h
+++ b/chromium/cc/benchmarks/benchmark_instrumentation.h
@@ -18,7 +18,11 @@ namespace benchmark_instrumentation {
// The benchmarks search for events and their arguments by name.
namespace internal {
-const char kCategory[] = "cc,benchmark";
+constexpr const char* Category() {
+ // Declared as a constexpr function to have an external linkage and to be
+ // known at compile-time.
+ return "cc,benchmark";
+}
const char kBeginFrameId[] = "begin_frame_id";
} // namespace internal
@@ -31,11 +35,11 @@ class ScopedBeginFrameTask {
public:
ScopedBeginFrameTask(const char* event_name, unsigned int begin_frame_id)
: event_name_(event_name) {
- TRACE_EVENT_BEGIN1(internal::kCategory, event_name_,
+ TRACE_EVENT_BEGIN1(internal::Category(), event_name_,
internal::kBeginFrameId, begin_frame_id);
}
~ScopedBeginFrameTask() {
- TRACE_EVENT_END0(internal::kCategory, event_name_);
+ TRACE_EVENT_END0(internal::Category(), event_name_);
}
private:
diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index e4d5e25a8aa..d3652f0dba9 100644
--- a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -65,8 +65,8 @@ void RunBenchmark(RasterSource* raster_source,
image_settings->images_to_skip = {};
image_settings->image_to_current_frame_index = {};
- PlaybackImageProvider image_provider(
- image_decode_cache, gfx::ColorSpace(), std::move(image_settings));
+ PlaybackImageProvider image_provider(image_decode_cache,
+ std::move(image_settings));
RasterSource::PlaybackSettings settings;
settings.image_provider = &image_provider;
diff --git a/chromium/cc/debug/layer_tree_debug_state.cc b/chromium/cc/debug/layer_tree_debug_state.cc
index 56b88794b87..6b51ff0b6f5 100644
--- a/chromium/cc/debug/layer_tree_debug_state.cc
+++ b/chromium/cc/debug/layer_tree_debug_state.cc
@@ -24,6 +24,7 @@ LayerTreeDebugState::LayerTreeDebugState()
slow_down_raster_scale_factor(0),
rasterize_only_visible_content(false),
show_picture_borders(false),
+ show_hit_test_borders(false),
record_rendering_stats_(false) {}
LayerTreeDebugState::LayerTreeDebugState(const LayerTreeDebugState& other) =
@@ -73,6 +74,7 @@ bool LayerTreeDebugState::Equal(const LayerTreeDebugState& a,
a.slow_down_raster_scale_factor == b.slow_down_raster_scale_factor &&
a.rasterize_only_visible_content == b.rasterize_only_visible_content &&
a.show_picture_borders == b.show_picture_borders &&
+ a.show_hit_test_borders == b.show_hit_test_borders &&
a.record_rendering_stats_ == b.record_rendering_stats_);
}
@@ -98,6 +100,8 @@ LayerTreeDebugState LayerTreeDebugState::Unite(const LayerTreeDebugState& a,
r.rasterize_only_visible_content |= b.rasterize_only_visible_content;
r.show_picture_borders |= b.show_picture_borders;
+ r.show_hit_test_borders |= b.show_hit_test_borders;
+
r.record_rendering_stats_ |= b.record_rendering_stats_;
return r;
diff --git a/chromium/cc/debug/layer_tree_debug_state.h b/chromium/cc/debug/layer_tree_debug_state.h
index 2ea5f9c3aa9..c7438b6fe48 100644
--- a/chromium/cc/debug/layer_tree_debug_state.h
+++ b/chromium/cc/debug/layer_tree_debug_state.h
@@ -46,6 +46,8 @@ class CC_DEBUG_EXPORT LayerTreeDebugState {
bool rasterize_only_visible_content;
bool show_picture_borders;
+ bool show_hit_test_borders;
+
void SetRecordRenderingStats(bool enabled);
bool RecordRenderingStats() const;
diff --git a/chromium/cc/debug/rendering_stats.h b/chromium/cc/debug/rendering_stats.h
index 156db0c15b9..4fe3f55336d 100644
--- a/chromium/cc/debug/rendering_stats.h
+++ b/chromium/cc/debug/rendering_stats.h
@@ -11,7 +11,7 @@
#include <vector>
#include "base/time/time.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/debug/debug_export.h"
diff --git a/chromium/cc/input/browser_controls_offset_manager.cc b/chromium/cc/input/browser_controls_offset_manager.cc
index e55bf940440..afbe9770086 100644
--- a/chromium/cc/input/browser_controls_offset_manager.cc
+++ b/chromium/cc/input/browser_controls_offset_manager.cc
@@ -38,6 +38,7 @@ BrowserControlsOffsetManager::BrowserControlsOffsetManager(
float controls_show_threshold,
float controls_hide_threshold)
: client_(client),
+ animation_initialized_(false),
animation_start_value_(0.f),
animation_stop_value_(0.f),
animation_direction_(NO_ANIMATION),
@@ -47,7 +48,8 @@ BrowserControlsOffsetManager::BrowserControlsOffsetManager(
baseline_bottom_content_offset_(0.f),
controls_show_threshold_(controls_hide_threshold),
controls_hide_threshold_(controls_show_threshold),
- pinch_gesture_active_(false) {
+ pinch_gesture_active_(false),
+ constraint_changed_since_commit_(false) {
CHECK(client_);
}
@@ -92,6 +94,17 @@ void BrowserControlsOffsetManager::UpdateBrowserControlsState(
DCHECK(!(constraints == BrowserControlsState::kHidden &&
current == BrowserControlsState::kShown));
+ TRACE_EVENT2("cc", "BrowserControlsOffsetManager::UpdateBrowserControlsState",
+ "constraints", static_cast<int>(constraints), "current",
+ static_cast<int>(current));
+
+ // If the constraints have changed we need to inform Blink about it since
+ // that'll affect main thread scrolling as well as layout.
+ if (permitted_state_ != constraints) {
+ constraint_changed_since_commit_ = true;
+ client_->SetNeedsCommit();
+ }
+
permitted_state_ = constraints;
// Don't do anything if it doesn't matter which state the controls are in.
@@ -105,6 +118,7 @@ void BrowserControlsOffsetManager::UpdateBrowserControlsState(
current == BrowserControlsState::kHidden)
final_shown_ratio = 0.f;
if (final_shown_ratio == TopControlsShownRatio()) {
+ TRACE_EVENT_INSTANT0("cc", "Ratio Unchanged", TRACE_EVENT_SCOPE_THREAD);
ResetAnimations();
return;
}
@@ -113,10 +127,18 @@ void BrowserControlsOffsetManager::UpdateBrowserControlsState(
SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS);
} else {
ResetAnimations();
- // We depend on the main thread to push the new ratio. crbug.com/754346 .
+ client_->SetCurrentBrowserControlsShownRatio(final_shown_ratio);
}
}
+BrowserControlsState BrowserControlsOffsetManager::PullConstraintForMainThread(
+ bool* out_changed_since_commit) {
+ DCHECK(out_changed_since_commit);
+ *out_changed_since_commit = constraint_changed_since_commit_;
+ constraint_changed_since_commit_ = false;
+ return permitted_state_;
+}
+
void BrowserControlsOffsetManager::ScrollBegin() {
if (pinch_gesture_active_)
return;
@@ -197,6 +219,16 @@ gfx::Vector2dF BrowserControlsOffsetManager::Animate(
if (!has_animation() || !client_->HaveRootScrollNode())
return gfx::Vector2dF();
+ if (!animation_initialized_) {
+ // Setup the animation start and time here so that they use the same clock
+ // as frame times. This is helpful for tests that mock time.
+ animation_start_time_ = monotonic_time;
+ animation_stop_time_ =
+ animation_start_time_ +
+ base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs);
+ animation_initialized_ = true;
+ }
+
float old_offset = ContentTopOffset();
float new_ratio = gfx::Tween::ClampedFloatValueBetween(
monotonic_time, animation_start_time_, animation_start_value_,
@@ -211,6 +243,7 @@ gfx::Vector2dF BrowserControlsOffsetManager::Animate(
}
void BrowserControlsOffsetManager::ResetAnimations() {
+ animation_initialized_ = false;
animation_start_time_ = base::TimeTicks();
animation_start_value_ = 0.f;
animation_stop_time_ = base::TimeTicks();
@@ -234,13 +267,9 @@ void BrowserControlsOffsetManager::SetupAnimation(
return;
}
- animation_start_time_ = base::TimeTicks::Now();
animation_start_value_ = TopControlsShownRatio();
const float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
- animation_stop_time_ =
- animation_start_time_ +
- base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs);
animation_stop_value_ = animation_start_value_ + max_ending_ratio;
animation_direction_ = direction;
diff --git a/chromium/cc/input/browser_controls_offset_manager.h b/chromium/cc/input/browser_controls_offset_manager.h
index ae4d9e4268f..8d0435d2808 100644
--- a/chromium/cc/input/browser_controls_offset_manager.h
+++ b/chromium/cc/input/browser_controls_offset_manager.h
@@ -53,6 +53,9 @@ class CC_EXPORT BrowserControlsOffsetManager {
BrowserControlsState current,
bool animate);
+ BrowserControlsState PullConstraintForMainThread(
+ bool* out_changed_since_commit);
+
void ScrollBegin();
gfx::Vector2dF ScrollBy(const gfx::Vector2dF& pending_delta);
void ScrollEnd();
@@ -81,6 +84,9 @@ class CC_EXPORT BrowserControlsOffsetManager {
// The client manages the lifecycle of this.
BrowserControlsOffsetManagerClient* client_;
+ // animation_initialized_ tracks if we've initialized the start and end
+ // times since that must happen at a BeginFrame.
+ bool animation_initialized_;
base::TimeTicks animation_start_time_;
float animation_start_value_;
base::TimeTicks animation_stop_time_;
@@ -106,6 +112,10 @@ class CC_EXPORT BrowserControlsOffsetManager {
bool pinch_gesture_active_;
+ // Used to track whether the constraint has changed and we need up reflect
+ // the changes to Blink.
+ bool constraint_changed_since_commit_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserControlsOffsetManager);
};
diff --git a/chromium/cc/input/browser_controls_offset_manager_client.h b/chromium/cc/input/browser_controls_offset_manager_client.h
index df1a742669d..5a2ce4cb5dc 100644
--- a/chromium/cc/input/browser_controls_offset_manager_client.h
+++ b/chromium/cc/input/browser_controls_offset_manager_client.h
@@ -15,6 +15,7 @@ class CC_EXPORT BrowserControlsOffsetManagerClient {
virtual float CurrentBrowserControlsShownRatio() const = 0;
virtual void DidChangeBrowserControlsPosition() = 0;
virtual bool HaveRootScrollNode() const = 0;
+ virtual void SetNeedsCommit() = 0;
protected:
virtual ~BrowserControlsOffsetManagerClient() {}
diff --git a/chromium/cc/input/browser_controls_offset_manager_unittest.cc b/chromium/cc/input/browser_controls_offset_manager_unittest.cc
index 3caad9cd2ec..3a8cfdc7df8 100644
--- a/chromium/cc/input/browser_controls_offset_manager_unittest.cc
+++ b/chromium/cc/input/browser_controls_offset_manager_unittest.cc
@@ -71,6 +71,8 @@ class MockBrowserControlsOffsetManagerClient
return top_controls_shown_ratio_;
}
+ void SetNeedsCommit() override {}
+
LayerImpl* rootScrollLayer() { return root_scroll_layer_.get(); }
BrowserControlsOffsetManager* manager() {
@@ -167,7 +169,12 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownHideAnimation) {
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -199,7 +206,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->BottomControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -229,7 +241,12 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownShowAnimation) {
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -256,7 +273,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->BottomControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -283,7 +305,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -310,7 +337,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -341,7 +373,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -372,7 +409,12 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -435,7 +477,12 @@ TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
EXPECT_TRUE(manager->has_animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous;
+
+ // First animate will establish the animaion.
+ float previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -456,6 +503,12 @@ TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
EXPECT_TRUE(manager->has_animation());
time = base::TimeTicks::Now();
+
+ // First animate will establish the animaion.
+ previous = manager->TopControlsShownRatio();
+ manager->Animate(time);
+ EXPECT_EQ(manager->TopControlsShownRatio(), previous);
+
while (manager->has_animation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
diff --git a/chromium/cc/input/browser_controls_state.h b/chromium/cc/input/browser_controls_state.h
index 38310496c5a..8b2f93f4171 100644
--- a/chromium/cc/input/browser_controls_state.h
+++ b/chromium/cc/input/browser_controls_state.h
@@ -8,6 +8,7 @@
namespace cc {
enum class BrowserControlsState { kShown = 1, kHidden = 2, kBoth = 3 };
-}
+
+} // namespace cc
#endif // CC_INPUT_BROWSER_CONTROLS_STATE_H_
diff --git a/chromium/cc/input/main_thread_scrolling_reason.cc b/chromium/cc/input/main_thread_scrolling_reason.cc
index a85b60f97a7..728708ce776 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason.cc
@@ -5,7 +5,7 @@
#include "cc/input/main_thread_scrolling_reason.h"
#include "base/stl_util.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
namespace cc {
@@ -47,8 +47,6 @@ void MainThreadScrollingReason::AddToTracedValue(
traced_value.AppendString("Has transform and LCD text");
if (reasons & kBackgroundNotOpaqueInRectAndLCDText)
traced_value.AppendString("Background is not opaque in rect and LCD text");
- if (reasons & kHasBorderRadius)
- traced_value.AppendString("Has border radius");
if (reasons & kHasClipRelatedProperty)
traced_value.AppendString("Has clip related property");
if (reasons & kHasBoxShadowFromNonRootLayer)
diff --git a/chromium/cc/input/main_thread_scrolling_reason.h b/chromium/cc/input/main_thread_scrolling_reason.h
index cf2deff0ce8..732c3fa904b 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.h
+++ b/chromium/cc/input/main_thread_scrolling_reason.h
@@ -46,7 +46,6 @@ struct CC_EXPORT MainThreadScrollingReason {
kHasOpacityAndLCDText = 1 << 16,
kHasTransformAndLCDText = 1 << 17,
kBackgroundNotOpaqueInRectAndLCDText = 1 << 18,
- kHasBorderRadius = 1 << 19,
kHasClipRelatedProperty = 1 << 20,
kHasBoxShadowFromNonRootLayer = 1 << 21,
kIsNotStackingContextAndLCDText = 1 << 22,
@@ -72,9 +71,8 @@ struct CC_EXPORT MainThreadScrollingReason {
static const uint32_t kNonCompositedReasons =
kHasOpacityAndLCDText | kHasTransformAndLCDText |
- kBackgroundNotOpaqueInRectAndLCDText | kHasBorderRadius |
- kHasClipRelatedProperty | kHasBoxShadowFromNonRootLayer |
- kIsNotStackingContextAndLCDText;
+ kBackgroundNotOpaqueInRectAndLCDText | kHasClipRelatedProperty |
+ kHasBoxShadowFromNonRootLayer | kIsNotStackingContextAndLCDText;
// Returns true if the given MainThreadScrollingReason can be set by the main
// thread.
diff --git a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
index 9f8e6b641d8..7560dda71d9 100644
--- a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
@@ -16,13 +16,14 @@ TEST_F(MainThreadScrollingReasonTest, AsText) {
"Has background-attachment:fixed,"
"Has non-layer viewport-constrained objects,"
"Threaded scrolling is disabled,"
- "Scrollbar scrolling,Page overlay,"
+ "Scrollbar scrolling,"
+ "Page overlay,"
"Handling scroll from main thread,"
"Custom scrollbar scrolling,"
"Has opacity and LCD text,"
"Has transform and LCD text,"
"Background is not opaque in rect and LCD text,"
- "Has border radius,Has clip related property,"
+ "Has clip related property,"
"Has box shadow from non-root layer,"
"Is not stacking context and LCD text,"
"Non fast scrollable region,"
diff --git a/chromium/cc/input/scroll_snap_data.cc b/chromium/cc/input/scroll_snap_data.cc
index 9e873aea523..3fc17474fc7 100644
--- a/chromium/cc/input/scroll_snap_data.cc
+++ b/chromium/cc/input/scroll_snap_data.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/input/scroll_snap_data.h"
+#include "cc/input/snap_selection_strategy.h"
#include <algorithm>
#include <cmath>
@@ -11,8 +12,8 @@ namespace cc {
namespace {
bool IsMutualVisible(const SnapSearchResult& a, const SnapSearchResult& b) {
- return a.visible_range().Contains(b.snap_offset()) &&
- b.visible_range().Contains(a.snap_offset());
+ return a.visible_range().Contains(gfx::RangeF(b.snap_offset())) &&
+ b.visible_range().Contains(gfx::RangeF(a.snap_offset()));
}
bool SnappableOnAxis(const SnapAreaData& area, SearchAxis search_axis) {
@@ -21,34 +22,36 @@ bool SnappableOnAxis(const SnapAreaData& area, SearchAxis search_axis) {
: area.scroll_snap_align.alignment_block != SnapAlignment::kNone;
}
-} // namespace
-
-bool SnapVisibleRange::Contains(float value) const {
- if (start_ < end_)
- return start_ <= value && value <= end_;
- return end_ <= value && value <= start_;
+void SetOrUpdateResult(const SnapSearchResult& candidate,
+ base::Optional<SnapSearchResult>* result) {
+ if (result->has_value())
+ result->value().Union(candidate);
+ else
+ *result = candidate;
}
-SnapSearchResult::SnapSearchResult(float offset, const SnapVisibleRange& range)
+} // namespace
+
+SnapSearchResult::SnapSearchResult(float offset, const gfx::RangeF& range)
: snap_offset_(offset) {
set_visible_range(range);
}
-void SnapSearchResult::set_visible_range(const SnapVisibleRange& range) {
+void SnapSearchResult::set_visible_range(const gfx::RangeF& range) {
DCHECK(range.start() <= range.end());
visible_range_ = range;
}
void SnapSearchResult::Clip(float max_snap, float max_visible) {
snap_offset_ = std::max(std::min(snap_offset_, max_snap), 0.0f);
- visible_range_ = SnapVisibleRange(
- std::max(std::min(visible_range_.start(), max_visible), 0.0f),
- std::max(std::min(visible_range_.end(), max_visible), 0.0f));
+ visible_range_ =
+ gfx::RangeF(std::max(std::min(visible_range_.start(), max_visible), 0.0f),
+ std::max(std::min(visible_range_.end(), max_visible), 0.0f));
}
void SnapSearchResult::Union(const SnapSearchResult& other) {
DCHECK(snap_offset_ == other.snap_offset_);
- visible_range_ = SnapVisibleRange(
+ visible_range_ = gfx::RangeF(
std::min(visible_range_.start(), other.visible_range_.start()),
std::max(visible_range_.end(), other.visible_range_.end()));
}
@@ -88,13 +91,14 @@ void SnapContainerData::AddSnapAreaData(SnapAreaData snap_area_data) {
}
bool SnapContainerData::FindSnapPosition(
- const gfx::ScrollOffset& current_position,
- bool should_snap_on_x,
- bool should_snap_on_y,
+ const SnapSelectionStrategy& strategy,
gfx::ScrollOffset* snap_position) const {
+ gfx::ScrollOffset base_position = strategy.base_position();
SnapAxis axis = scroll_snap_type_.axis;
- should_snap_on_x &= (axis == SnapAxis::kX || axis == SnapAxis::kBoth);
- should_snap_on_y &= (axis == SnapAxis::kY || axis == SnapAxis::kBoth);
+ bool should_snap_on_x = strategy.ShouldSnapOnX() &&
+ (axis == SnapAxis::kX || axis == SnapAxis::kBoth);
+ bool should_snap_on_y = strategy.ShouldSnapOnY() &&
+ (axis == SnapAxis::kY || axis == SnapAxis::kBoth);
if (!should_snap_on_x && !should_snap_on_y)
return false;
@@ -102,18 +106,18 @@ bool SnapContainerData::FindSnapPosition(
// A region that includes every reachable scroll position.
gfx::RectF scrollable_region(0, 0, max_position_.x(), max_position_.y());
if (should_snap_on_x) {
- // Start from current offset in the cross axis and assume it's always
+ // Start from current position in the cross axis and assume it's always
// visible.
SnapSearchResult initial_snap_position_y = {
- current_position.y(), SnapVisibleRange(0, max_position_.x())};
- closest_x = FindClosestValidArea(SearchAxis::kX, current_position.x(),
- initial_snap_position_y);
+ base_position.y(), gfx::RangeF(0, max_position_.x())};
+ closest_x =
+ FindClosestValidArea(SearchAxis::kX, strategy, initial_snap_position_y);
}
if (should_snap_on_y) {
SnapSearchResult initial_snap_position_x = {
- current_position.x(), SnapVisibleRange(0, max_position_.y())};
- closest_y = FindClosestValidArea(SearchAxis::kY, current_position.y(),
- initial_snap_position_x);
+ base_position.x(), gfx::RangeF(0, max_position_.y())};
+ closest_y =
+ FindClosestValidArea(SearchAxis::kY, strategy, initial_snap_position_x);
}
if (!closest_x.has_value() && !closest_y.has_value())
@@ -126,17 +130,18 @@ bool SnapContainerData::FindSnapPosition(
if (closest_x.has_value() && closest_y.has_value() &&
!IsMutualVisible(closest_x.value(), closest_y.value())) {
bool candidate_on_x_axis_is_closer =
- std::abs(closest_x.value().snap_offset() - current_position.x()) <=
- std::abs(closest_y.value().snap_offset() - current_position.y());
- if (candidate_on_x_axis_is_closer)
- closest_y = FindClosestValidArea(SearchAxis::kY, current_position.y(),
- closest_x.value());
- else
- closest_x = FindClosestValidArea(SearchAxis::kX, current_position.x(),
- closest_y.value());
+ std::abs(closest_x.value().snap_offset() - base_position.x()) <=
+ std::abs(closest_y.value().snap_offset() - base_position.y());
+ if (candidate_on_x_axis_is_closer) {
+ closest_y =
+ FindClosestValidArea(SearchAxis::kY, strategy, closest_x.value());
+ } else {
+ closest_x =
+ FindClosestValidArea(SearchAxis::kX, strategy, closest_y.value());
+ }
}
- *snap_position = current_position;
+ *snap_position = strategy.current_position();
if (closest_x.has_value())
snap_position->set_x(closest_x.value().snap_offset());
if (closest_y.has_value())
@@ -146,13 +151,36 @@ bool SnapContainerData::FindSnapPosition(
base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea(
SearchAxis axis,
- float current_offset,
+ const SnapSelectionStrategy& strategy,
const SnapSearchResult& cros_axis_snap_result) const {
- base::Optional<SnapSearchResult> result;
- base::Optional<SnapSearchResult> inplace;
- // The valid snap offsets immediately before and after the current offset.
+ // 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.
+ float intended_position = axis == SearchAxis::kX
+ ? strategy.intended_position().x()
+ : strategy.intended_position().y();
+ // The position from which we search for the closest snap position.
+ float base_position = axis == SearchAxis::kX ? strategy.base_position().x()
+ : strategy.base_position().y();
+
float smallest_distance =
axis == SearchAxis::kX ? proximity_range_.x() : proximity_range_.y();
for (const SnapAreaData& area : snap_area_list_) {
@@ -160,52 +188,54 @@ base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea(
continue;
SnapSearchResult candidate = GetSnapSearchResult(axis, area);
- if (IsSnapportCoveredOnAxis(axis, current_offset, area.rect)) {
- // Since snap area is currently covering the snapport, we consider the
- // current offset as a valid snap position.
- SnapSearchResult inplace_candidate = candidate;
- inplace_candidate.set_snap_offset(current_offset);
- if (IsMutualVisible(inplace_candidate, cros_axis_snap_result)) {
- // If we've already found a valid overflowing area before, we enlarge
- // the area's visible region.
- if (inplace.has_value())
- inplace.value().Union(inplace_candidate);
- else
- inplace = inplace_candidate;
- // Even if a snap area covers the snapport, we need to continue this
- // search to find previous and next snap positions and also to have
- // alternative snap candidates if this inplace candidate is ultimately
- // rejected. And this covering snap area has its own alignment that may
- // generates a snap position rejecting the current inplace candidate.
- }
+ if (IsSnapportCoveredOnAxis(axis, intended_position, area.rect)) {
+ // Since snap area will cover the snapport, we consider the intended
+ // position as a valid snap position.
+ SnapSearchResult covering_candidate = candidate;
+ covering_candidate.set_snap_offset(intended_position);
+ if (IsMutualVisible(covering_candidate, cros_axis_snap_result))
+ SetOrUpdateResult(covering_candidate, &covering);
+ // Even if a snap area covers the snapport, we need to continue this
+ // search to find previous and next snap positions and also to have
+ // alternative snap candidates if this covering candidate is ultimately
+ // rejected. And this covering snap area has its own alignment that may
+ // generates a snap position rejecting the current inplace candidate.
}
if (!IsMutualVisible(candidate, cros_axis_snap_result))
continue;
- float distance = std::abs(candidate.snap_offset() - current_offset);
+ 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;
- result = candidate;
+ closest = candidate;
}
- if (candidate.snap_offset() < current_offset &&
+ if (candidate.snap_offset() < intended_position &&
candidate.snap_offset() > prev)
prev = candidate.snap_offset();
- if (candidate.snap_offset() > current_offset &&
+ if (candidate.snap_offset() > intended_position &&
candidate.snap_offset() < next)
next = candidate.snap_offset();
}
// According to the spec [1], if the snap area is covering the snapport, the
- // scroll offset is a valid snap position only if the distance between the
+ // scroll position is a valid snap position only if the distance between the
// geometrically previous and subsequent snap positions in that axis is larger
// than size of the snapport in that axis.
// [1] https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow
float size = axis == SearchAxis::kX ? rect_.width() : rect_.height();
- if (inplace.has_value() &&
- (prev == std::numeric_limits<float>::lowest() ||
- next == std::numeric_limits<float>::max() || next - prev > size)) {
- return inplace;
+ if (prev != std::numeric_limits<float>::lowest() &&
+ next != std::numeric_limits<float>::max() && next - prev <= size) {
+ covering = base::nullopt;
}
- return result;
+ const base::Optional<SnapSearchResult>& picked =
+ strategy.PickBestResult(closest, covering);
+ return picked.has_value() ? picked : current;
}
SnapSearchResult SnapContainerData::GetSnapSearchResult(
@@ -213,8 +243,8 @@ SnapSearchResult SnapContainerData::GetSnapSearchResult(
const SnapAreaData& area) const {
SnapSearchResult result;
if (axis == SearchAxis::kX) {
- result.set_visible_range(SnapVisibleRange(area.rect.y() - rect_.bottom(),
- area.rect.bottom() - rect_.y()));
+ result.set_visible_range(gfx::RangeF(area.rect.y() - rect_.bottom(),
+ area.rect.bottom() - rect_.y()));
// https://www.w3.org/TR/css-scroll-snap-1/#scroll-snap-align
switch (area.scroll_snap_align.alignment_inline) {
case SnapAlignment::kStart:
@@ -232,8 +262,8 @@ SnapSearchResult SnapContainerData::GetSnapSearchResult(
}
result.Clip(max_position_.x(), max_position_.y());
} else {
- result.set_visible_range(SnapVisibleRange(area.rect.x() - rect_.right(),
- area.rect.right() - rect_.x()));
+ result.set_visible_range(gfx::RangeF(area.rect.x() - rect_.right(),
+ area.rect.right() - rect_.x()));
switch (area.scroll_snap_align.alignment_block) {
case SnapAlignment::kStart:
result.set_snap_offset(area.rect.y() - rect_.y());
diff --git a/chromium/cc/input/scroll_snap_data.h b/chromium/cc/input/scroll_snap_data.h
index c18f7374229..3057acf339e 100644
--- a/chromium/cc/input/scroll_snap_data.h
+++ b/chromium/cc/input/scroll_snap_data.h
@@ -11,9 +11,12 @@
#include "cc/cc_export.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/range/range_f.h"
namespace cc {
+class SnapSelectionStrategy;
+
// See https://www.w3.org/TR/css-scroll-snap-1/#snap-axis
enum class SnapAxis : unsigned {
kBoth,
@@ -85,28 +88,13 @@ struct ScrollSnapAlign {
SnapAlignment alignment_inline;
};
-// We should really use gfx::RangeF. However, it includes windows.h which would
-// bring in complexity to the compilation. https://crbug.com/855717
-class SnapVisibleRange {
- public:
- SnapVisibleRange() {}
- SnapVisibleRange(float start, float end) : start_(start), end_(end) {}
- bool Contains(float value) const;
- float start() const { return start_; }
- float end() const { return end_; }
-
- private:
- float start_;
- float end_;
-};
-
// This class includes snap offset and visible range needed to perform a snap
// operation on one axis for a specific area. The data can be used to determine
// whether this snap area provides a valid snap position for the current scroll.
class SnapSearchResult {
public:
SnapSearchResult() {}
- SnapSearchResult(float offset, const SnapVisibleRange& range);
+ SnapSearchResult(float offset, const gfx::RangeF& range);
// Clips the |snap_offset| between 0 and |max_snap|. And clips the
// |visible_range| between 0 and |max_visible|.
void Clip(float max_snap, float max_visible);
@@ -118,15 +106,15 @@ class SnapSearchResult {
float snap_offset() const { return snap_offset_; }
void set_snap_offset(float offset) { snap_offset_ = offset; }
- SnapVisibleRange visible_range() const { return visible_range_; }
- void set_visible_range(const SnapVisibleRange& range);
+ gfx::RangeF visible_range() const { return visible_range_; }
+ void set_visible_range(const gfx::RangeF& range);
private:
float snap_offset_;
// This is the range on the cross axis, within which the SnapArea generating
// this |snap_offset| is visible. We expect the range to be in order (as
- // opposed to reversed), i.e., start < end.
- SnapVisibleRange visible_range_;
+ // opposed to reversed), i.e., start() < end().
+ gfx::RangeF visible_range_;
};
// Snap area is a bounding box that could be snapped to when a scroll happens in
@@ -196,9 +184,7 @@ class CC_EXPORT SnapContainerData {
return !(*this == other);
}
- bool FindSnapPosition(const gfx::ScrollOffset& current_position,
- bool should_snap_on_x,
- bool should_snap_on_y,
+ bool FindSnapPosition(const SnapSelectionStrategy& strategy,
gfx::ScrollOffset* snap_position) const;
void AddSnapAreaData(SnapAreaData snap_area_data);
@@ -222,8 +208,8 @@ class CC_EXPORT SnapContainerData {
gfx::ScrollOffset proximity_range() const { return proximity_range_; }
private:
- // Finds the best SnapArea candidate that minimizes the distance between
- // current and candidate positions, while satisfying two invariants:
+ // Finds the best SnapArea candidate that's optimal for the given selection
+ // strategy, while satisfying two invariants:
// - |candidate.snap_offset| is within |cross_axis_snap_result|'s visible
// range on |axis|.
// - |cross_axis_snap_result.snap_offset| is within |candidate|'s visible
@@ -234,7 +220,7 @@ class CC_EXPORT SnapContainerData {
// |snap_offset| and its visible range on the cross axis.
base::Optional<SnapSearchResult> FindClosestValidArea(
SearchAxis axis,
- float current_offset,
+ const SnapSelectionStrategy& strategy,
const SnapSearchResult& cross_axis_snap_result) const;
// Returns all the info needed to snap at this area on the given axis,
diff --git a/chromium/cc/input/scroll_snap_data_unittest.cc b/chromium/cc/input/scroll_snap_data_unittest.cc
index d2347148d0b..6f994d543a0 100644
--- a/chromium/cc/input/scroll_snap_data_unittest.cc
+++ b/chromium/cc/input/scroll_snap_data_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/input/scroll_snap_data.h"
+#include "cc/input/snap_selection_strategy.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,10 +18,12 @@ TEST_F(ScrollSnapDataTest, StartAlignmentCalculation) {
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
gfx::RectF(100, 150, 100, 100), false);
container.AddSnapAreaData(area);
- gfx::ScrollOffset current_position(0, 0);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+ true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(90, snap_position.x());
EXPECT_EQ(140, snap_position.y());
}
@@ -32,10 +35,12 @@ TEST_F(ScrollSnapDataTest, CenterAlignmentCalculation) {
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kCenter),
gfx::RectF(100, 150, 100, 100), false);
container.AddSnapAreaData(area);
- gfx::ScrollOffset current_position(0, 0);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+ true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(40, snap_position.x());
EXPECT_EQ(40, snap_position.y());
}
@@ -47,10 +52,12 @@ TEST_F(ScrollSnapDataTest, EndAlignmentCalculation) {
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd),
gfx::RectF(150, 200, 100, 100), false);
container.AddSnapAreaData(area);
- gfx::ScrollOffset current_position(0, 0);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+ true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(40, snap_position.x());
EXPECT_EQ(90, snap_position.y());
}
@@ -62,10 +69,12 @@ TEST_F(ScrollSnapDataTest, UnreachableSnapPositionCalculation) {
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd, SnapAlignment::kStart),
gfx::RectF(200, 0, 100, 100), false);
container.AddSnapAreaData(area);
- gfx::ScrollOffset current_position(50, 50);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(50, 50),
+ true, true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
// Aligning to start on x would lead the scroll offset larger than max, and
// aligning to end on y would lead the scroll offset smaller than zero. So
// we expect these are clamped.
@@ -85,13 +94,15 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionIndependently) {
gfx::RectF(0, 70, 150, 150), false);
SnapAreaData snap_on_both(ScrollSnapAlign(SnapAlignment::kStart),
gfx::RectF(50, 150, 150, 150), false);
- gfx::ScrollOffset current_position(100, 100);
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
container.AddSnapAreaData(snap_on_both);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+ true, true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(80, snap_position.x());
EXPECT_EQ(70, snap_position.y());
}
@@ -108,13 +119,15 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionOnAxisValueBoth) {
gfx::RectF(0, 70, 150, 150), false);
SnapAreaData snap_on_both(ScrollSnapAlign(SnapAlignment::kStart),
gfx::RectF(50, 150, 150, 150), false);
- gfx::ScrollOffset current_position(40, 120);
+
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
container.AddSnapAreaData(snap_on_both);
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(40, 120),
+ true, true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(50, snap_position.x());
EXPECT_EQ(150, snap_position.y());
}
@@ -129,12 +142,14 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonScrolledAxis) {
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
gfx::RectF(0, 70, 150, 150), false);
- gfx::ScrollOffset current_position(100, 100);
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(container.FindSnapPosition(current_position, true, false,
- &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+ true, false);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(80, snap_position.x());
EXPECT_EQ(100, snap_position.y());
}
@@ -149,19 +164,20 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonVisibleAreas) {
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
gfx::RectF(400, 300, 100, 100), false);
- gfx::ScrollOffset current_position(0, 0);
+
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
gfx::ScrollOffset snap_position;
- EXPECT_FALSE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+ true);
+ EXPECT_FALSE(container.FindSnapPosition(*strategy, &snap_position));
}
TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
SnapContainerData container(
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
- gfx::ScrollOffset current_position(0, 0);
// Both the areas are currently visible.
// However, if we snap to them on x and y independently, none is visible after
@@ -180,9 +196,12 @@ TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
container.AddSnapAreaData(snap_x);
container.AddSnapAreaData(snap_y1);
container.AddSnapAreaData(snap_y2);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+ true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
EXPECT_EQ(150, snap_position.x());
EXPECT_EQ(80, snap_position.y());
}
@@ -193,13 +212,15 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapToPositionsOutsideProximityRange) {
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
container.set_proximity_range(gfx::ScrollOffset(50, 50));
- gfx::ScrollOffset current_position(100, 100);
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
gfx::RectF(80, 160, 100, 100), false);
container.AddSnapAreaData(area);
+
gfx::ScrollOffset snap_position;
- EXPECT_TRUE(
- container.FindSnapPosition(current_position, true, true, &snap_position));
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+ true, true);
+ EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
// The snap position on x, 80, is within the proximity range of [50, 150].
// However, the snap position on y, 160, is outside the proximity range of
diff --git a/chromium/cc/input/snap_fling_controller.h b/chromium/cc/input/snap_fling_controller.h
index 20f305651c2..eb07106796c 100644
--- a/chromium/cc/input/snap_fling_controller.h
+++ b/chromium/cc/input/snap_fling_controller.h
@@ -24,8 +24,8 @@ class SnapFlingCurve;
class SnapFlingClient {
public:
virtual bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement,
- gfx::Vector2dF* out_initial_offset,
- gfx::Vector2dF* out_target_offset) const = 0;
+ gfx::Vector2dF* out_initial_position,
+ gfx::Vector2dF* out_target_position) const = 0;
virtual gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) = 0;
virtual void ScrollEndForSnapFling() = 0;
virtual void RequestAnimationForSnapFling() = 0;
diff --git a/chromium/cc/input/snap_selection_strategy.cc b/chromium/cc/input/snap_selection_strategy.cc
new file mode 100644
index 00000000000..ce0f2655ecf
--- /dev/null
+++ b/chromium/cc/input/snap_selection_strategy.cc
@@ -0,0 +1,151 @@
+// 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/input/snap_selection_strategy.h"
+
+namespace cc {
+
+std::unique_ptr<SnapSelectionStrategy>
+SnapSelectionStrategy::CreateForEndPosition(
+ const gfx::ScrollOffset& current_position,
+ bool scrolled_x,
+ bool scrolled_y) {
+ return std::make_unique<EndPositionStrategy>(current_position, scrolled_x,
+ scrolled_y);
+}
+
+std::unique_ptr<SnapSelectionStrategy>
+SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset current_position,
+ gfx::ScrollOffset step) {
+ return std::make_unique<DirectionStrategy>(current_position, step);
+}
+
+std::unique_ptr<SnapSelectionStrategy>
+SnapSelectionStrategy::CreateForEndAndDirection(
+ gfx::ScrollOffset current_position,
+ gfx::ScrollOffset displacement) {
+ return std::make_unique<EndAndDirectionStrategy>(current_position,
+ displacement);
+}
+
+bool EndPositionStrategy::ShouldSnapOnX() const {
+ return scrolled_x_;
+}
+
+bool EndPositionStrategy::ShouldSnapOnY() const {
+ return scrolled_y_;
+}
+
+gfx::ScrollOffset EndPositionStrategy::intended_position() const {
+ return current_position_;
+}
+
+gfx::ScrollOffset EndPositionStrategy::base_position() const {
+ return current_position_;
+}
+
+// |position| is unused in this method.
+bool EndPositionStrategy::IsValidSnapPosition(SearchAxis axis,
+ float position) const {
+ return (scrolled_x_ && axis == SearchAxis::kX) ||
+ (scrolled_y_ && axis == SearchAxis::kY);
+}
+
+const base::Optional<SnapSearchResult>& EndPositionStrategy::PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const {
+ return covering.has_value() ? covering : closest;
+}
+
+bool DirectionStrategy::ShouldSnapOnX() const {
+ return step_.x() != 0;
+}
+
+bool DirectionStrategy::ShouldSnapOnY() const {
+ return step_.y() != 0;
+}
+
+gfx::ScrollOffset DirectionStrategy::intended_position() const {
+ return current_position_ + step_;
+}
+
+gfx::ScrollOffset DirectionStrategy::base_position() const {
+ return current_position_;
+}
+
+bool DirectionStrategy::IsValidSnapPosition(SearchAxis axis,
+ float position) const {
+ if (axis == SearchAxis::kX) {
+ return (step_.x() > 0 &&
+ position > current_position_.x()) || // "Right" arrow
+ (step_.x() < 0 && position < current_position_.x()); // "Left" arrow
+ } else {
+ return (step_.y() > 0 &&
+ position > current_position_.y()) || // "Down" arrow
+ (step_.y() < 0 && position < current_position_.y()); // "Up" arrow
+ }
+}
+
+const base::Optional<SnapSearchResult>& DirectionStrategy::PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const {
+ // We choose the |closest| result only if the default landing position (using
+ // the default step) is not a valid snap position (not making a snap area
+ // covering the snapport), or the |closest| is closer than the default landing
+ // position.
+ if (!closest.has_value())
+ return covering;
+ if (!covering.has_value())
+ return closest;
+
+ // "Right" or "Down" arrow.
+ if ((step_.x() > 0 || step_.y() > 0) &&
+ closest.value().snap_offset() < covering.value().snap_offset()) {
+ return closest;
+ }
+ // "Left" or "Up" arrow.
+ if ((step_.x() < 0 || step_.y() < 0) &&
+ closest.value().snap_offset() > covering.value().snap_offset()) {
+ return closest;
+ }
+
+ return covering;
+}
+
+bool EndAndDirectionStrategy::ShouldSnapOnX() const {
+ return displacement_.x() != 0;
+}
+
+bool EndAndDirectionStrategy::ShouldSnapOnY() const {
+ return displacement_.y() != 0;
+}
+
+gfx::ScrollOffset EndAndDirectionStrategy::intended_position() const {
+ return current_position_ + displacement_;
+}
+
+gfx::ScrollOffset EndAndDirectionStrategy::base_position() const {
+ return current_position_ + displacement_;
+}
+
+bool EndAndDirectionStrategy::IsValidSnapPosition(SearchAxis axis,
+ float position) const {
+ if (axis == SearchAxis::kX) {
+ return (displacement_.x() > 0 &&
+ position > current_position_.x()) || // Right
+ (displacement_.x() < 0 && position < current_position_.x()); // Left
+ } else {
+ return (displacement_.y() > 0 &&
+ position > current_position_.y()) || // Down
+ (displacement_.y() < 0 && position < current_position_.y()); // Up
+ }
+}
+
+const base::Optional<SnapSearchResult>& EndAndDirectionStrategy::PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const {
+ return covering.has_value() ? covering : closest;
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/snap_selection_strategy.h b/chromium/cc/input/snap_selection_strategy.h
new file mode 100644
index 00000000000..cebc63e96b5
--- /dev/null
+++ b/chromium/cc/input/snap_selection_strategy.h
@@ -0,0 +1,170 @@
+// 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_INPUT_SNAP_SELECTION_STRATEGY_H_
+#define CC_INPUT_SNAP_SELECTION_STRATEGY_H_
+
+#include "scroll_snap_data.h"
+
+#include <memory>
+
+namespace cc {
+
+// This class represents an abstract strategy that decide which snap selection
+// should be considered valid. There are concrete implementations for three core
+// scrolling types: scroll with end position only, scroll with direction only,
+// and scroll with end position and direction.
+class CC_EXPORT SnapSelectionStrategy {
+ public:
+ SnapSelectionStrategy() = default;
+ virtual ~SnapSelectionStrategy() = default;
+ static std::unique_ptr<SnapSelectionStrategy> CreateForEndPosition(
+ const gfx::ScrollOffset& current_position,
+ bool scrolled_x,
+ bool scrolled_y);
+ static std::unique_ptr<SnapSelectionStrategy> CreateForDirection(
+ gfx::ScrollOffset current_position,
+ gfx::ScrollOffset step);
+ static std::unique_ptr<SnapSelectionStrategy> CreateForEndAndDirection(
+ gfx::ScrollOffset current_position,
+ gfx::ScrollOffset displacement);
+
+ // Returns whether it's snappable on x or y depending on the scroll performed.
+ virtual bool ShouldSnapOnX() const = 0;
+ virtual bool ShouldSnapOnY() const = 0;
+
+ // Returns the end position of the scroll if no snap interferes.
+ virtual gfx::ScrollOffset intended_position() const = 0;
+ // Returns the scroll position from which the snap position should minimize
+ // its distance.
+ virtual gfx::ScrollOffset base_position() const = 0;
+ // Returns the current scroll position of the snap container.
+ const gfx::ScrollOffset& current_position() const {
+ return current_position_;
+ }
+
+ // Returns true if the selection strategy considers the given snap offset
+ // valid for the current axis.
+ virtual bool IsValidSnapPosition(SearchAxis axis, float position) const = 0;
+
+ // Returns the best result according to snap selection strategy. This method
+ // is called at the end of selection process to make the final decision.
+ //
+ // -closest: snap search result representing closest match.
+ // -covering: snap search result representing the original target if it makes
+ // a snaparea covering the snapport.
+ virtual const base::Optional<SnapSearchResult>& PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const = 0;
+
+ protected:
+ explicit SnapSelectionStrategy(const gfx::ScrollOffset& current_position)
+ : current_position_(current_position) {}
+ const gfx::ScrollOffset current_position_;
+};
+
+// Examples for intended end position scrolls include
+// - a panning gesture, released without momentum
+// - manupulating the scrollbar "thumb" explicitly
+// - programmatically scrolling via APIs such as scrollTo()
+// - tabbing through the document's focusable elements
+// - navigating to an anchor within the page
+// - homing operations such as the Home/End keys
+// For this type of scrolls, we want to
+// * Minimize the distance between the snap position and the end position.
+// * Return the end position if that makes a snap area covers the snapport.
+class EndPositionStrategy : public SnapSelectionStrategy {
+ public:
+ EndPositionStrategy(const gfx::ScrollOffset& current_position,
+ bool scrolled_x,
+ bool scrolled_y)
+ : SnapSelectionStrategy(current_position),
+ scrolled_x_(scrolled_x),
+ scrolled_y_(scrolled_y) {}
+ ~EndPositionStrategy() override = default;
+
+ bool ShouldSnapOnX() const override;
+ bool ShouldSnapOnY() const override;
+
+ gfx::ScrollOffset intended_position() const override;
+ gfx::ScrollOffset base_position() const override;
+
+ bool IsValidSnapPosition(SearchAxis axis, float position) const override;
+
+ const base::Optional<SnapSearchResult>& PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const override;
+
+ private:
+ // Whether the x axis and y axis have been scrolled in this scroll gesture.
+ const bool scrolled_x_;
+ const bool scrolled_y_;
+};
+
+// Examples for intended direction scrolls include
+// - pressing an arrow key on the keyboard
+// - a swiping gesture interpreted as a fixed (rather than inertial) scroll
+// For this type of scrolls, we want to
+// * Minimize the distance between the snap position and the starting position,
+// so that we stop at the first snap position in that direction.
+// * Return the default intended position (using the default step) if that makes
+// a snap area covers the snapport.
+class DirectionStrategy : public SnapSelectionStrategy {
+ public:
+ DirectionStrategy(const gfx::ScrollOffset& current_position,
+ const gfx::ScrollOffset& step)
+ : SnapSelectionStrategy(current_position), step_(step) {}
+ ~DirectionStrategy() override = default;
+
+ bool ShouldSnapOnX() const override;
+ bool ShouldSnapOnY() const override;
+
+ gfx::ScrollOffset intended_position() const override;
+ gfx::ScrollOffset base_position() const override;
+
+ bool IsValidSnapPosition(SearchAxis axis, float position) const override;
+
+ const base::Optional<SnapSearchResult>& PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const override;
+
+ private:
+ // The default step for this DirectionStrategy.
+ const gfx::ScrollOffset step_;
+};
+
+// Examples for intended direction and end position scrolls include
+// - a “fling” gesture, interpreted with momentum
+// - programmatically scrolling via APIs such as scrollBy()
+// - paging operations such as the PgUp/PgDn keys (or equivalent operations on
+// the scrollbar)
+// For this type of scrolls, we want to
+// * Minimize the distance between the snap position and the end position.
+// * Return the end position if that makes a snap area covers the snapport.
+class EndAndDirectionStrategy : public SnapSelectionStrategy {
+ public:
+ EndAndDirectionStrategy(const gfx::ScrollOffset& current_position,
+ const gfx::ScrollOffset& displacement)
+ : SnapSelectionStrategy(current_position), displacement_(displacement) {}
+ ~EndAndDirectionStrategy() override = default;
+
+ bool ShouldSnapOnX() const override;
+ bool ShouldSnapOnY() const override;
+
+ gfx::ScrollOffset intended_position() const override;
+ gfx::ScrollOffset base_position() const override;
+
+ bool IsValidSnapPosition(SearchAxis axis, float position) const override;
+
+ const base::Optional<SnapSearchResult>& PickBestResult(
+ const base::Optional<SnapSearchResult>& closest,
+ const base::Optional<SnapSearchResult>& covering) const override;
+
+ private:
+ const gfx::ScrollOffset displacement_;
+};
+
+} // namespace cc
+
+#endif // CC_INPUT_SNAP_SELECTION_STRATEGY_H_
diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc
index e8cd98328ae..1837ed16487 100644
--- a/chromium/cc/layers/heads_up_display_layer.cc
+++ b/chromium/cc/layers/heads_up_display_layer.cc
@@ -8,6 +8,7 @@
#include "base/trace_event/trace_event.h"
#include "cc/layers/heads_up_display_layer_impl.h"
+#include "cc/trees/layer_tree_host.h"
namespace cc {
@@ -27,6 +28,32 @@ HeadsUpDisplayLayer::HeadsUpDisplayLayer()
HeadsUpDisplayLayer::~HeadsUpDisplayLayer() = default;
+void HeadsUpDisplayLayer::UpdateLocationAndSize(
+ const gfx::Size& device_viewport,
+ float device_scale_factor) {
+ gfx::Size device_viewport_in_layout_pixels =
+ gfx::Size(device_viewport.width() / device_scale_factor,
+ device_viewport.height() / device_scale_factor);
+
+ gfx::Size bounds;
+ gfx::Transform matrix;
+ matrix.MakeIdentity();
+
+ if (layer_tree_host()->GetDebugState().ShowHudRects()) {
+ bounds = device_viewport_in_layout_pixels;
+ } else {
+ // If the HUD is not displaying full-viewport rects (e.g., it is showing the
+ // 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);
+ }
+
+ SetBounds(bounds);
+ SetTransform(matrix);
+}
+
bool HeadsUpDisplayLayer::HasDrawableContent() const {
return true;
}
diff --git a/chromium/cc/layers/heads_up_display_layer.h b/chromium/cc/layers/heads_up_display_layer.h
index ee3402e67c2..2936a975c80 100644
--- a/chromium/cc/layers/heads_up_display_layer.h
+++ b/chromium/cc/layers/heads_up_display_layer.h
@@ -20,6 +20,9 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer {
public:
static scoped_refptr<HeadsUpDisplayLayer> Create();
+ void UpdateLocationAndSize(const gfx::Size& device_viewport,
+ float device_scale_factor);
+
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
// Layer overrides.
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index ee4a8ff3813..cb7ee65c26e 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -11,13 +11,19 @@
#include <vector>
#include "base/numerics/safe_conversions.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/debug/debug_colors.h"
+#include "cc/paint/display_item_list.h"
+#include "cc/paint/paint_canvas.h"
+#include "cc/paint/paint_flags.h"
+#include "cc/paint/paint_shader.h"
+#include "cc/paint/record_paint_canvas.h"
+#include "cc/paint/skia_paint_canvas.h"
#include "cc/raster/scoped_gpu_raster.h"
#include "cc/resources/memory_history.h"
#include "cc/trees/frame_rate_counter.h"
@@ -33,42 +39,54 @@
#include "components/viz/common/resources/platform_color.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_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkCanvas.h"
+#include "gpu/config/gpu_feature_info.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
+#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/skia_util.h"
#include "ui/gl/trace_util.h"
namespace cc {
-static inline SkPaint CreatePaint() {
- SkPaint paint;
-#if (SK_R32_SHIFT || SK_B32_SHIFT != 16)
- // The SkCanvas is in RGBA but the shader is expecting BGRA, so we need to
- // swizzle our colors when drawing to the SkCanvas.
- SkScalar color_matrix[20];
- for (int i = 0; i < 20; ++i)
- color_matrix[i] = 0;
- color_matrix[0 + 5 * 2] = 1;
- color_matrix[1 + 5 * 1] = 1;
- color_matrix[2 + 5 * 0] = 1;
- color_matrix[3 + 5 * 3] = 1;
-
- paint.setColorFilter(
- SkColorFilter::MakeMatrixFilterRowMajor255(color_matrix));
-#endif
- return paint;
+namespace {
+
+void DrawArc(PaintCanvas* canvas,
+ const SkRect& oval,
+ SkScalar start_angle,
+ SkScalar sweep_angle,
+ const PaintFlags& flags) {
+ DCHECK_GT(sweep_angle, 0.f);
+ DCHECK_LT(sweep_angle, 360.f);
+ SkPath path;
+ path.moveTo(oval.centerX(), oval.centerY());
+ path.arcTo(oval, start_angle, sweep_angle, false /* forceMoveTo */);
+ path.close();
+ canvas->drawPath(path, flags);
}
+class DummyImageProvider : public ImageProvider {
+ public:
+ DummyImageProvider() = default;
+ ~DummyImageProvider() override = default;
+ ScopedDecodedDrawImage GetDecodedDrawImage(
+ const DrawImage& draw_image) override {
+ NOTREACHED();
+ return ScopedDecodedDrawImage();
+ }
+};
+
+} // namespace
+
HeadsUpDisplayLayerImpl::Graph::Graph(double indicator_value,
double start_upper_bound)
: value(0.0),
@@ -90,7 +108,9 @@ HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl,
internal_contents_scale_(1.f),
fps_graph_(60.0, 80.0),
paint_time_graph_(16.0, 48.0),
- fade_step_(0) {}
+ fade_step_(0),
+ raster_color_space_(gfx::ColorSpace::CreateSRGB(),
+ gfx::ColorSpace::GetNextId()) {}
HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() {
ReleaseResources();
@@ -106,11 +126,10 @@ class HudGpuBacking : public ResourcePool::GpuBacking {
~HudGpuBacking() override {
if (mailbox.IsZero())
return;
- auto* sii = compositor_context_provider->SharedImageInterface();
if (returned_sync_token.HasData())
- sii->DestroySharedImage(returned_sync_token, mailbox);
+ shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
else if (mailbox_sync_token.HasData())
- sii->DestroySharedImage(mailbox_sync_token, mailbox);
+ shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
}
void OnMemoryDump(
@@ -126,7 +145,7 @@ class HudGpuBacking : public ResourcePool::GpuBacking {
pmd->AddOwnershipEdge(buffer_dump_guid, tracing_guid, importance);
}
- viz::ContextProvider* compositor_context_provider;
+ gpu::SharedImageInterface* shared_image_interface = nullptr;
};
class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
@@ -198,14 +217,33 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
// Update state that will be drawn.
UpdateHudContents();
+ // TODO(penghuang): Do not use worker_context_provider() when context_provider
+ // is changed to RasterContextProvider.
+ // https://crbug.com/c/1286950
+ auto* raster_context_provider =
+ gpu_raster ? layer_tree_frame_sink->worker_context_provider() : nullptr;
+ base::Optional<viz::RasterContextProvider::ScopedRasterContextLock> lock;
+ bool use_oopr = false;
+ if (raster_context_provider) {
+ lock.emplace(raster_context_provider);
+ use_oopr = raster_context_provider->GetGpuFeatureInfo()
+ .status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
+ gpu::kGpuFeatureStatusEnabled;
+ if (!use_oopr) {
+ raster_context_provider = nullptr;
+ lock.reset();
+ }
+ }
+
+ auto* context_provider = layer_tree_frame_sink->context_provider();
if (!pool_) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
layer_tree_impl()->task_runner_provider()->HasImplThread()
? layer_tree_impl()->task_runner_provider()->ImplThreadTaskRunner()
: layer_tree_impl()->task_runner_provider()->MainThreadTaskRunner();
pool_ = std::make_unique<ResourcePool>(
- resource_provider, layer_tree_frame_sink->context_provider(),
- std::move(task_runner), ResourcePool::kDefaultExpirationDelay,
+ resource_provider, context_provider, std::move(task_runner),
+ ResourcePool::kDefaultExpirationDelay,
layer_tree_impl()->settings().disallow_non_exact_resource_reuse);
}
@@ -220,39 +258,58 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
// compositing.
ResourcePool::InUsePoolResource pool_resource;
if (draw_mode == DRAW_MODE_HARDWARE) {
- viz::ContextProvider* context_provider =
- layer_tree_impl()->context_provider();
- DCHECK(context_provider);
-
+ DCHECK(raster_context_provider || context_provider);
+ const auto& caps = raster_context_provider
+ ? raster_context_provider->ContextCapabilities()
+ : context_provider->ContextCapabilities();
viz::ResourceFormat format =
- viz::PlatformColor::BestSupportedRenderBufferFormat(
- context_provider->ContextCapabilities());
+ viz::PlatformColor::BestSupportedRenderBufferFormat(caps);
pool_resource = pool_->AcquireResource(internal_content_bounds_, format,
gfx::ColorSpace());
if (!pool_resource.gpu_backing()) {
auto backing = std::make_unique<HudGpuBacking>();
- backing->compositor_context_provider = context_provider;
+ auto* sii = raster_context_provider
+ ? raster_context_provider->SharedImageInterface()
+ : context_provider->SharedImageInterface();
+ backing->shared_image_interface = sii;
backing->InitOverlayCandidateAndTextureTarget(
- pool_resource.format(), context_provider->ContextCapabilities(),
+ pool_resource.format(), caps,
layer_tree_impl()
->settings()
.resource_settings.use_gpu_memory_buffer_resources);
- auto* sii = context_provider->SharedImageInterface();
- uint32_t flags = gpu::SHARED_IMAGE_USAGE_GLES2;
- if (gpu_raster)
- flags |= gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+
+ uint32_t flags = 0;
+ if (use_oopr) {
+ flags = gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
+ } else if (gpu_raster) {
+ flags = gpu::SHARED_IMAGE_USAGE_GLES2 |
+ gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+ }
if (backing->overlay_candidate)
flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
backing->mailbox =
sii->CreateSharedImage(pool_resource.format(), pool_resource.size(),
pool_resource.color_space(), flags);
- gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
- gl->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
+ if (raster_context_provider) {
+ auto* ri = raster_context_provider->RasterInterface();
+ ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
+ } else {
+ auto* gl = context_provider->ContextGL();
+ gl->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
+ }
pool_resource.set_gpu_backing(std::move(backing));
} else if (pool_resource.gpu_backing()->returned_sync_token.HasData()) {
- context_provider->ContextGL()->WaitSyncTokenCHROMIUM(
- pool_resource.gpu_backing()->returned_sync_token.GetConstData());
+ if (raster_context_provider) {
+ auto* ri = raster_context_provider->RasterInterface();
+ ri->WaitSyncTokenCHROMIUM(
+ pool_resource.gpu_backing()->returned_sync_token.GetConstData());
+ } else {
+ auto* gl = context_provider->ContextGL();
+ gl->WaitSyncTokenCHROMIUM(
+ pool_resource.gpu_backing()->returned_sync_token.GetConstData());
+ }
pool_resource.gpu_backing()->returned_sync_token = gpu::SyncToken();
}
} else {
@@ -285,29 +342,60 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
DCHECK_EQ(draw_mode, DRAW_MODE_HARDWARE);
DCHECK(pool_resource.gpu_backing());
auto* backing = static_cast<HudGpuBacking*>(pool_resource.gpu_backing());
- viz::ContextProvider* context_provider =
- layer_tree_impl()->context_provider();
- gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
- GLuint mailbox_texture_id =
- gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
- {
- ScopedGpuRaster gpu_raster(context_provider);
- viz::ClientResourceProvider::ScopedSkSurface scoped_surface(
- context_provider->GrContext(), mailbox_texture_id,
- backing->texture_target, pool_resource.size(), pool_resource.format(),
- false /* can_use_lcd_text */, 0 /* msaa_sample_count */);
- SkSurface* surface = scoped_surface.surface();
- if (!surface) {
- pool_->ReleaseResource(std::move(pool_resource));
- return;
+ if (use_oopr) {
+ const auto& size = pool_resource.size();
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>(
+ DisplayItemList::kTopLevelDisplayItemList);
+ RecordPaintCanvas canvas(display_item_list.get(),
+ SkRect::MakeIWH(size.width(), size.height()));
+ display_item_list->StartPaint();
+ DrawHudContents(&canvas);
+ display_item_list->EndPaintOfUnpaired(gfx::Rect(size));
+ display_item_list->Finalize();
+
+ auto* ri = raster_context_provider->RasterInterface();
+ 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);
+ gfx::Vector2dF post_translate(0.f, 0.f);
+ DummyImageProvider image_provider;
+ ri->RasterCHROMIUM(display_item_list.get(), &image_provider, size,
+ gfx::Rect(size), gfx::Rect(size), post_translate,
+ 1.f /* post_scale */, false /* requires_clear */);
+ ri->EndRasterCHROMIUM();
+ backing->mailbox_sync_token =
+ viz::ClientResourceProvider::GenerateSyncTokenHelper(ri);
+ } else {
+ auto* gl = context_provider->ContextGL();
+ GLuint mailbox_texture_id =
+ gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
+
+ {
+ ScopedGpuRaster gpu_raster(context_provider);
+ viz::ClientResourceProvider::ScopedSkSurface scoped_surface(
+ context_provider->GrContext(), mailbox_texture_id,
+ backing->texture_target, pool_resource.size(),
+ pool_resource.format(), false /* can_use_lcd_text */,
+ 0 /* msaa_sample_count */);
+ SkSurface* surface = scoped_surface.surface();
+ if (!surface) {
+ pool_->ReleaseResource(std::move(pool_resource));
+ return;
+ }
+ SkiaPaintCanvas canvas(surface->getCanvas());
+ DrawHudContents(&canvas);
}
- DrawHudContents(surface->getCanvas());
- }
- gl->DeleteTextures(1, &mailbox_texture_id);
- backing->mailbox_sync_token =
- viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
+ gl->DeleteTextures(1, &mailbox_texture_id);
+ backing->mailbox_sync_token =
+ viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
+ }
} else if (draw_mode == DRAW_MODE_HARDWARE) {
// If not using |gpu_raster| but using gpu compositing, we DrawHudContents()
// into a software bitmap and upload it to a texture for compositing.
@@ -324,7 +412,8 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
pool_resource.size().width(), pool_resource.size().height());
}
- DrawHudContents(staging_surface_->getCanvas());
+ SkiaPaintCanvas canvas(staging_surface_->getCanvas());
+ DrawHudContents(&canvas);
TRACE_EVENT0("cc", "UploadHudTexture");
SkPixmap pixmap;
@@ -333,10 +422,12 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
gl->BindTexture(backing->texture_target, mailbox_texture_id);
DCHECK(GLSupportsFormat(pool_resource.format()));
+ // We should use gl compatible format for skia SW rasterization.
+ constexpr GLenum format = SK_B32_SHIFT ? GL_RGBA : GL_BGRA_EXT;
+ constexpr GLenum type = GL_UNSIGNED_BYTE;
gl->TexSubImage2D(
backing->texture_target, 0, 0, 0, pool_resource.size().width(),
- pool_resource.size().height(), GLDataFormat(pool_resource.format()),
- GLDataType(pool_resource.format()), pixmap.addr());
+ pool_resource.size().height(), format, type, pixmap.addr());
gl->DeleteTextures(1, &mailbox_texture_id);
backing->mailbox_sync_token =
viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
@@ -354,12 +445,14 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
info, backing->shared_memory->memory(), info.minRowBytes());
- DrawHudContents(surface->getCanvas());
+ SkiaPaintCanvas canvas(surface->getCanvas());
+ DrawHudContents(&canvas);
}
// Exports the backing to the ResourceProvider, giving it a ResourceId that
// can be used in a DrawQuad.
- pool_->PrepareForExport(pool_resource);
+ bool exported = pool_->PrepareForExport(pool_resource);
+ DCHECK(exported);
viz::ResourceId resource_id = pool_resource.resource_id_for_export();
// Save the resource to prevent reuse until it is exported to the display
@@ -389,7 +482,8 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
/*uv_bottom_right=*/gfx::PointF(1.f, 1.f),
/*background_color=*/SK_ColorTRANSPARENT, vertex_opacity,
/*flipped=*/false,
- /*nearest_neighbor=*/false, /*secure_output_only=*/false);
+ /*nearest_neighbor=*/false, /*secure_output_only=*/false,
+ ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
break;
}
@@ -456,7 +550,7 @@ void HeadsUpDisplayLayerImpl::UpdateHudContents() {
paint_time_graph_.UpdateUpperBound();
}
-void HeadsUpDisplayLayerImpl::DrawHudContents(SkCanvas* canvas) {
+void HeadsUpDisplayLayerImpl::DrawHudContents(PaintCanvas* canvas) {
const LayerTreeDebugState& debug_state = layer_tree_impl()->debug_state();
TRACE_EVENT0("cc", "DrawHudContents");
@@ -486,85 +580,74 @@ void HeadsUpDisplayLayerImpl::DrawHudContents(SkCanvas* canvas) {
canvas->restore();
}
-int HeadsUpDisplayLayerImpl::MeasureText(SkPaint* paint,
- const std::string& text,
- int size) const {
- DCHECK(typeface_.get());
- const bool anti_alias = paint->isAntiAlias();
- paint->setAntiAlias(true);
- paint->setTextSize(size);
- paint->setTypeface(typeface_);
- SkScalar text_width = paint->measureText(text.c_str(), text.length());
-
- paint->setAntiAlias(anti_alias);
- return SkScalarCeilToInt(text_width);
-}
-void HeadsUpDisplayLayerImpl::DrawText(SkCanvas* canvas,
- SkPaint* paint,
+
+void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
+ PaintFlags* flags,
const std::string& text,
- SkPaint::Align align,
+ TextAlign align,
int size,
int x,
int y) const {
DCHECK(typeface_.get());
- const bool anti_alias = paint->isAntiAlias();
- paint->setAntiAlias(true);
-
- paint->setTextSize(size);
- paint->setTextAlign(align);
- paint->setTypeface(typeface_);
- canvas->drawText(text.c_str(), text.length(), x, y, *paint);
+ flags->setAntiAlias(true);
+ flags->setTextSize(size);
+ flags->setTypeface(typeface_);
+ if (align == TextAlign::kCenter) {
+ auto width = flags->ToSkPaint().measureText(text.c_str(), text.length());
+ x -= width * 0.5f;
+ } else if (align == TextAlign::kRight) {
+ auto width = flags->ToSkPaint().measureText(text.c_str(), text.length());
+ x -= width;
+ }
+ auto sk_paint = flags->ToSkPaint();
- paint->setAntiAlias(anti_alias);
+ 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);
}
-void HeadsUpDisplayLayerImpl::DrawText(SkCanvas* canvas,
- SkPaint* paint,
+void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
+ PaintFlags* flags,
const std::string& text,
- SkPaint::Align align,
+ TextAlign align,
int size,
const SkPoint& pos) const {
- DrawText(canvas, paint, text, align, size, pos.x(), pos.y());
+ DrawText(canvas, flags, text, align, size, pos.x(), pos.y());
}
-void HeadsUpDisplayLayerImpl::DrawGraphBackground(SkCanvas* canvas,
- SkPaint* paint,
+void HeadsUpDisplayLayerImpl::DrawGraphBackground(PaintCanvas* canvas,
+ PaintFlags* flags,
const SkRect& bounds) const {
- paint->setColor(DebugColors::HUDBackgroundColor());
- canvas->drawRect(bounds, *paint);
+ flags->setColor(DebugColors::HUDBackgroundColor());
+ canvas->drawRect(bounds, *flags);
}
-void HeadsUpDisplayLayerImpl::DrawGraphLines(SkCanvas* canvas,
- SkPaint* paint,
+void HeadsUpDisplayLayerImpl::DrawGraphLines(PaintCanvas* canvas,
+ PaintFlags* flags,
const SkRect& bounds,
const Graph& graph) const {
// Draw top and bottom line.
- paint->setColor(DebugColors::HUDSeparatorLineColor());
- canvas->drawLine(bounds.left(),
- bounds.top() - 1,
- bounds.right(),
- bounds.top() - 1,
- *paint);
- canvas->drawLine(
- bounds.left(), bounds.bottom(), bounds.right(), bounds.bottom(), *paint);
+ flags->setColor(DebugColors::HUDSeparatorLineColor());
+ canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(),
+ bounds.top() - 1, *flags);
+ canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(),
+ bounds.bottom(), *flags);
// Draw indicator line (additive blend mode to increase contrast when drawn on
// top of graph).
- paint->setColor(DebugColors::HUDIndicatorLineColor());
- paint->setBlendMode(SkBlendMode::kPlus);
+ flags->setColor(DebugColors::HUDIndicatorLineColor());
+ flags->setBlendMode(SkBlendMode::kPlus);
const double indicator_top =
bounds.height() * (1.0 - graph.indicator / graph.current_upper_bound) -
1.0;
- canvas->drawLine(bounds.left(),
- bounds.top() + indicator_top,
- bounds.right(),
- bounds.top() + indicator_top,
- *paint);
- paint->setBlendMode(SkBlendMode::kSrcOver);
+ canvas->drawLine(bounds.left(), bounds.top() + indicator_top, bounds.right(),
+ bounds.top() + indicator_top, *flags);
+ flags->setBlendMode(SkBlendMode::kSrcOver);
}
SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
- SkCanvas* canvas,
+ PaintCanvas* canvas,
const FrameRateCounter* fps_counter,
int right,
int top) const {
@@ -585,8 +668,8 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
int left = bounds().width() - width - right;
SkRect area = SkRect::MakeXYWH(left, top, width, height);
- SkPaint paint = CreatePaint();
- DrawGraphBackground(canvas, &paint, area);
+ PaintFlags flags;
+ DrawGraphBackground(canvas, &flags, area);
SkRect title_bounds = SkRect::MakeXYWH(
left + kPadding, top + kPadding, kGraphWidth + kHistogramWidth + kGap + 2,
@@ -594,14 +677,12 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
SkRect text_bounds =
SkRect::MakeXYWH(left + kPadding, title_bounds.bottom() + 2 * kPadding,
kGraphWidth + kHistogramWidth + kGap + 2, kFontHeight);
- SkRect graph_bounds = SkRect::MakeXYWH(left + kPadding,
- text_bounds.bottom() + 2 * kPadding,
- kGraphWidth,
- kGraphHeight);
- SkRect histogram_bounds = SkRect::MakeXYWH(graph_bounds.right() + kGap,
- graph_bounds.top(),
- kHistogramWidth,
- kGraphHeight);
+ SkRect graph_bounds =
+ SkRect::MakeXYWH(left + kPadding, text_bounds.bottom() + 2 * kPadding,
+ kGraphWidth, kGraphHeight);
+ SkRect histogram_bounds =
+ SkRect::MakeXYWH(graph_bounds.right() + kGap, graph_bounds.top(),
+ kHistogramWidth, kGraphHeight);
const std::string title("Frame Rate");
const std::string value_text =
@@ -611,33 +692,23 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
VLOG(1) << value_text;
- paint.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &paint, title, SkPaint::kLeft_Align, kTitleFontHeight,
+ flags.setColor(DebugColors::HUDTitleColor());
+ DrawText(canvas, &flags, title, TextAlign::kLeft, kTitleFontHeight,
title_bounds.left(), title_bounds.bottom());
- paint.setColor(DebugColors::FPSDisplayTextAndGraphColor());
- DrawText(canvas,
- &paint,
- value_text,
- SkPaint::kLeft_Align,
- kFontHeight,
- text_bounds.left(),
- text_bounds.bottom());
- DrawText(canvas,
- &paint,
- min_max_text,
- SkPaint::kRight_Align,
- kFontHeight,
- text_bounds.right(),
- text_bounds.bottom());
-
- DrawGraphLines(canvas, &paint, graph_bounds, fps_graph_);
+ flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
+ DrawText(canvas, &flags, value_text, TextAlign::kLeft, kFontHeight,
+ text_bounds.left(), text_bounds.bottom());
+ DrawText(canvas, &flags, min_max_text, TextAlign::kRight, kFontHeight,
+ text_bounds.right(), text_bounds.bottom());
+
+ DrawGraphLines(canvas, &flags, graph_bounds, fps_graph_);
// Collect graph and histogram data.
SkPath path;
const int kHistogramSize = 20;
- double histogram[kHistogramSize] = { 1.0 };
+ double histogram[kHistogramSize] = {1.0};
double max_bucket_value = 1.0;
for (FrameRateCounter::RingBufferType::Iterator it = --fps_counter->end(); it;
@@ -674,19 +745,15 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
}
// Draw FPS histogram.
- paint.setColor(DebugColors::HUDSeparatorLineColor());
- canvas->drawLine(histogram_bounds.left() - 1,
- histogram_bounds.top() - 1,
- histogram_bounds.left() - 1,
- histogram_bounds.bottom() + 1,
- paint);
- canvas->drawLine(histogram_bounds.right() + 1,
- histogram_bounds.top() - 1,
- histogram_bounds.right() + 1,
- histogram_bounds.bottom() + 1,
- paint);
-
- paint.setColor(DebugColors::FPSDisplayTextAndGraphColor());
+ flags.setColor(DebugColors::HUDSeparatorLineColor());
+ canvas->drawLine(histogram_bounds.left() - 1, histogram_bounds.top() - 1,
+ histogram_bounds.left() - 1, histogram_bounds.bottom() + 1,
+ flags);
+ canvas->drawLine(histogram_bounds.right() + 1, histogram_bounds.top() - 1,
+ histogram_bounds.right() + 1, histogram_bounds.bottom() + 1,
+ flags);
+
+ flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
const double bar_height = histogram_bounds.height() / kHistogramSize;
for (int i = kHistogramSize - 1; i >= 0; --i) {
@@ -696,22 +763,21 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
canvas->drawRect(
SkRect::MakeXYWH(histogram_bounds.left(),
histogram_bounds.bottom() - (i + 1) * bar_height,
- bar_width,
- 1),
- paint);
+ bar_width, 1),
+ flags);
}
}
// Draw FPS graph.
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(1);
- canvas->drawPath(path, paint);
+ flags.setAntiAlias(true);
+ flags.setStyle(PaintFlags::kStroke_Style);
+ flags.setStrokeWidth(1);
+ canvas->drawPath(path, flags);
return area;
}
-SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
+SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(PaintCanvas* canvas,
int right,
int top,
int width) const {
@@ -725,8 +791,8 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
const double kMegabyte = 1024.0 * 1024.0;
- SkPaint paint = CreatePaint();
- DrawGraphBackground(canvas, &paint, area);
+ PaintFlags flags;
+ DrawGraphBackground(canvas, &flags, area);
SkPoint title_pos =
SkPoint::Make(left + kPadding, top + kFontHeight + kPadding);
@@ -735,31 +801,32 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
SkPoint stat2_pos = SkPoint::Make(left + width - kPadding - 1,
top + 2 * kPadding + 3 * kFontHeight);
- paint.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &paint, "GPU Memory", SkPaint::kLeft_Align, kTitleFontHeight,
+ flags.setColor(DebugColors::HUDTitleColor());
+ DrawText(canvas, &flags, "GPU Memory", TextAlign::kLeft, kTitleFontHeight,
title_pos);
- paint.setColor(DebugColors::MemoryDisplayTextColor());
+ flags.setColor(DebugColors::MemoryDisplayTextColor());
std::string text = base::StringPrintf(
"%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte);
- DrawText(canvas, &paint, text, SkPaint::kRight_Align, kFontHeight, stat1_pos);
+ DrawText(canvas, &flags, text, TextAlign::kRight, kFontHeight, stat1_pos);
if (!memory_entry_.had_enough_memory)
- paint.setColor(SK_ColorRED);
+ flags.setColor(SK_ColorRED);
text = base::StringPrintf("%6.1f MB max ",
memory_entry_.total_budget_in_bytes / kMegabyte);
- DrawText(canvas, &paint, text, SkPaint::kRight_Align, kFontHeight, stat2_pos);
+
+ DrawText(canvas, &flags, text, TextAlign::kRight, kFontHeight, stat2_pos);
// Draw memory graph.
int length = 2 * kFontHeight + kPadding + 12;
SkRect oval =
SkRect::MakeXYWH(left + kPadding * 6,
top + kTitleFontHeight + kPadding * 3, length, length);
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kFill_Style);
+ flags.setAntiAlias(true);
+ flags.setStyle(PaintFlags::kFill_Style);
- paint.setColor(SkColorSetARGB(64, 255, 255, 0));
- canvas->drawArc(oval, 180, 180, true, paint);
+ flags.setColor(SkColorSetARGB(64, 255, 255, 0));
+ DrawArc(canvas, oval, 180, 180, flags);
int radius = length / 2;
int cx = oval.left() + radius;
@@ -773,24 +840,25 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
const SkScalar pos[] = {SkFloatToScalar(0.2f), SkFloatToScalar(0.4f),
SkFloatToScalar(0.6f), SkFloatToScalar(0.8f),
SkFloatToScalar(1.0f)};
- paint.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, 5));
- paint.setFlags(SkPaint::kAntiAlias_Flag);
+ flags.setShader(PaintShader::MakeSweepGradient(
+ cx, cy, colors, pos, 5, SkShader::kClamp_TileMode, 0, 360));
+ flags.setAntiAlias(true);
// Draw current status.
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setAlpha(32);
- paint.setStrokeWidth(4);
- canvas->drawArc(oval, 180, angle, true, paint);
+ flags.setStyle(PaintFlags::kStroke_Style);
+ flags.setAlpha(32);
+ flags.setStrokeWidth(4);
+ DrawArc(canvas, oval, 180, angle, flags);
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(SkColorSetARGB(255, 0, 255, 0));
- canvas->drawArc(oval, 180, angle, true, paint);
- paint.setShader(nullptr);
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SkColorSetARGB(255, 0, 255, 0));
+ DrawArc(canvas, oval, 180, angle, flags);
+ flags.setShader(nullptr);
return area;
}
-SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(SkCanvas* canvas,
+SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
int right,
int top,
int width) const {
@@ -830,24 +898,24 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(SkCanvas* canvas,
const int left = bounds().width() - width - right;
const SkRect area = SkRect::MakeXYWH(left, top, width, height);
- SkPaint paint = CreatePaint();
- DrawGraphBackground(canvas, &paint, area);
+ PaintFlags flags;
+ DrawGraphBackground(canvas, &flags, area);
SkPoint gpu_status_pos = SkPoint::Make(left + width - kPadding,
top + 2 * kFontHeight + 2 * kPadding);
- paint.setColor(DebugColors::HUDTitleColor());
- DrawText(canvas, &paint, "GPU Raster", SkPaint::kLeft_Align, kTitleFontHeight,
+ flags.setColor(DebugColors::HUDTitleColor());
+ DrawText(canvas, &flags, "GPU Raster", TextAlign::kLeft, kTitleFontHeight,
left + kPadding, top + kFontHeight + kPadding);
- paint.setColor(color);
- DrawText(canvas, &paint, status, SkPaint::kRight_Align, kFontHeight,
+ flags.setColor(color);
+ DrawText(canvas, &flags, status, TextAlign::kRight, kFontHeight,
gpu_status_pos);
return area;
}
void HeadsUpDisplayLayerImpl::DrawDebugRect(
- SkCanvas* canvas,
- SkPaint* paint,
+ PaintCanvas* canvas,
+ PaintFlags* flags,
const DebugRect& rect,
SkColor stroke_color,
SkColor fill_color,
@@ -858,14 +926,14 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect(
gfx::ScaleToEnclosingRect(rect.rect, 1.0 / internal_contents_scale_,
1.0 / internal_contents_scale_);
SkIRect sk_rect = RectToSkIRect(debug_layer_rect);
- paint->setColor(fill_color);
- paint->setStyle(SkPaint::kFill_Style);
- canvas->drawIRect(sk_rect, *paint);
+ flags->setColor(fill_color);
+ flags->setStyle(PaintFlags::kFill_Style);
+ canvas->drawIRect(sk_rect, *flags);
- paint->setColor(stroke_color);
- paint->setStyle(SkPaint::kStroke_Style);
- paint->setStrokeWidth(SkFloatToScalar(stroke_width));
- canvas->drawIRect(sk_rect, *paint);
+ flags->setColor(stroke_color);
+ flags->setStyle(PaintFlags::kStroke_Style);
+ flags->setStrokeWidth(SkFloatToScalar(stroke_width));
+ canvas->drawIRect(sk_rect, *flags);
if (label_text.length()) {
const int kFontHeight = 12;
@@ -881,33 +949,29 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect(
canvas->clipRect(sk_clip_rect);
canvas->translate(sk_clip_rect.x(), sk_clip_rect.y());
- SkPaint label_paint = CreatePaint();
- label_paint.setTextSize(kFontHeight);
- label_paint.setTypeface(typeface_);
- label_paint.setColor(stroke_color);
+ PaintFlags label_flags;
+ label_flags.setTextSize(kFontHeight);
+ label_flags.setTypeface(typeface_);
+ label_flags.setColor(stroke_color);
- const SkScalar label_text_width =
- label_paint.measureText(label_text.c_str(), label_text.length());
+ const SkScalar label_text_width = label_flags.ToSkPaint().measureText(
+ label_text.c_str(), label_text.length());
canvas->drawRect(SkRect::MakeWH(label_text_width + 2 * kPadding,
kFontHeight + 2 * kPadding),
- label_paint);
-
- label_paint.setAntiAlias(true);
- label_paint.setColor(SkColorSetARGB(255, 50, 50, 50));
- canvas->drawText(label_text.c_str(),
- label_text.length(),
- kPadding,
- kFontHeight * 0.8f + kPadding,
- label_paint);
+ label_flags);
+ label_flags.setAntiAlias(true);
+ label_flags.setColor(SkColorSetARGB(255, 50, 50, 50));
+ DrawText(canvas, &label_flags, label_text, TextAlign::kLeft, kFontHeight,
+ kPadding, kFontHeight * 0.8f + kPadding);
canvas->restore();
}
}
void HeadsUpDisplayLayerImpl::DrawDebugRects(
- SkCanvas* canvas,
+ PaintCanvas* canvas,
DebugRectHistory* debug_rect_history) {
- SkPaint paint = CreatePaint();
+ PaintFlags flags;
const std::vector<DebugRect>& debug_rects = debug_rect_history->debug_rects();
std::vector<DebugRect> new_paint_rects;
@@ -970,13 +1034,8 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
break;
}
- DrawDebugRect(canvas,
- &paint,
- debug_rects[i],
- stroke_color,
- fill_color,
- stroke_width,
- label_text);
+ DrawDebugRect(canvas, &flags, debug_rects[i], stroke_color, fill_color,
+ stroke_width, label_text);
}
if (new_paint_rects.size()) {
@@ -986,13 +1045,10 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
if (fade_step_ > 0) {
fade_step_--;
for (size_t i = 0; i < paint_rects_.size(); ++i) {
- DrawDebugRect(canvas,
- &paint,
- paint_rects_[i],
+ DrawDebugRect(canvas, &flags, paint_rects_[i],
DebugColors::PaintRectBorderColor(fade_step_),
DebugColors::PaintRectFillColor(fade_step_),
- DebugColors::PaintRectBorderWidth(),
- "");
+ DebugColors::PaintRectBorderWidth(), "");
}
}
}
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h
index 6102b0da115..9a97daea2d4 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.h
+++ b/chromium/cc/layers/heads_up_display_layer_impl.h
@@ -14,13 +14,12 @@
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/layers/layer_impl.h"
+#include "cc/paint/color_space_transfer_cache_entry.h"
#include "cc/resources/memory_history.h"
#include "cc/resources/resource_pool.h"
#include "cc/trees/debug_rect_history.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-class SkCanvas;
-class SkPaint;
class SkTypeface;
struct SkRect;
@@ -31,6 +30,10 @@ class ClientResourceProvider;
namespace cc {
class FrameRateCounter;
class LayerTreeFrameSink;
+class PaintCanvas;
+class PaintFlags;
+
+enum class TextAlign { kLeft, kCenter, kRight };
class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
public:
@@ -93,50 +96,49 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
void AsValueInto(base::trace_event::TracedValue* dict) const override;
void UpdateHudContents();
- void DrawHudContents(SkCanvas* canvas);
-
- int MeasureText(SkPaint* paint, const std::string& text, int size) const;
- void DrawText(SkCanvas* canvas,
- SkPaint* paint,
+ void DrawHudContents(PaintCanvas* canvas);
+ void DrawText(PaintCanvas* canvas,
+ PaintFlags* flags,
const std::string& text,
- SkPaint::Align align,
+ TextAlign align,
int size,
int x,
int y) const;
- void DrawText(SkCanvas* canvas,
- SkPaint* paint,
+ void DrawText(PaintCanvas* canvas,
+ PaintFlags* flags,
const std::string& text,
- SkPaint::Align align,
+ TextAlign align,
int size,
const SkPoint& pos) const;
- void DrawGraphBackground(SkCanvas* canvas,
- SkPaint* paint,
+ void DrawGraphBackground(PaintCanvas* canvas,
+ PaintFlags* flags,
const SkRect& bounds) const;
- void DrawGraphLines(SkCanvas* canvas,
- SkPaint* paint,
+ void DrawGraphLines(PaintCanvas* canvas,
+ PaintFlags* flags,
const SkRect& bounds,
const Graph& graph) const;
- SkRect DrawFPSDisplay(SkCanvas* canvas,
+ SkRect DrawFPSDisplay(PaintCanvas* canvas,
const FrameRateCounter* fps_counter,
int right,
int top) const;
- SkRect DrawMemoryDisplay(SkCanvas* canvas,
+ SkRect DrawMemoryDisplay(PaintCanvas* canvas,
int top,
int right,
int width) const;
- SkRect DrawGpuRasterizationStatus(SkCanvas* canvas,
+ SkRect DrawGpuRasterizationStatus(PaintCanvas* canvas,
int right,
int top,
int width) const;
- void DrawDebugRect(SkCanvas* canvas,
- SkPaint* paint,
+ void DrawDebugRect(PaintCanvas* canvas,
+ PaintFlags* flags,
const DebugRect& rect,
SkColor stroke_color,
SkColor fill_color,
float stroke_width,
const std::string& label_text) const;
- void DrawDebugRects(SkCanvas* canvas, DebugRectHistory* debug_rect_history);
+ void DrawDebugRects(PaintCanvas* canvas,
+ DebugRectHistory* debug_rect_history);
ResourcePool::InUsePoolResource in_flight_resource_;
std::unique_ptr<ResourcePool> pool_;
@@ -157,6 +159,9 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
base::TimeTicks time_of_last_graph_update_;
+ // color space for OOPR
+ const RasterColorSpace raster_color_space_;
+
DISALLOW_COPY_AND_ASSIGN(HeadsUpDisplayLayerImpl);
};
diff --git a/chromium/cc/layers/heads_up_display_unittest.cc b/chromium/cc/layers/heads_up_display_unittest.cc
index 840f82f8ef4..6ebce87e16e 100644
--- a/chromium/cc/layers/heads_up_display_unittest.cc
+++ b/chromium/cc/layers/heads_up_display_unittest.cc
@@ -82,5 +82,24 @@ class HudWithRootLayerChange : public HeadsUpDisplayTest {
SINGLE_AND_MULTI_THREAD_TEST_F(HudWithRootLayerChange);
+class HeadsUpDisplaySizeWithFPS : public LayerTreeTest {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->initial_debug_state.show_fps_counter = true;
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DidCommit() override {
+ ASSERT_TRUE(layer_tree_host()->hud_layer());
+ EXPECT_EQ(gfx::Size(256, 256), layer_tree_host()->hud_layer()->bounds());
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(HeadsUpDisplaySizeWithFPS);
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index dfc03bb5898..f976fa6e1aa 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -509,7 +509,7 @@ void Layer::SetMaskLayer(PictureLayer* mask_layer) {
inputs_.mask_layer->RemoveFromParent();
DCHECK(!inputs_.mask_layer->parent());
inputs_.mask_layer->SetParent(this);
- if (inputs_.filters.IsEmpty() && inputs_.background_filters.IsEmpty() &&
+ if (inputs_.filters.IsEmpty() && inputs_.backdrop_filters.IsEmpty() &&
(!layer_tree_host_ ||
layer_tree_host_->GetSettings().enable_mask_tiling)) {
inputs_.mask_layer->SetLayerMaskType(
@@ -537,11 +537,11 @@ void Layer::SetFilters(const FilterOperations& filters) {
SetNeedsCommit();
}
-void Layer::SetBackgroundFilters(const FilterOperations& filters) {
+void Layer::SetBackdropFilters(const FilterOperations& filters) {
DCHECK(IsPropertyChangeAllowed());
- if (inputs_.background_filters == filters)
+ if (inputs_.backdrop_filters == filters)
return;
- inputs_.background_filters = filters;
+ inputs_.backdrop_filters = filters;
// We will not set the mask type to MULTI_TEXTURE_MASK if the mask layer's
// filters are removed, because we do not want to reraster if the filters are
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index 4e288f8cfb0..b90f4559bc0 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -278,9 +278,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// 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.
- void SetBackgroundFilters(const FilterOperations& filters);
- const FilterOperations& background_filters() const {
- return inputs_.background_filters;
+ void SetBackdropFilters(const FilterOperations& filters);
+ const FilterOperations& backdrop_filters() const {
+ return inputs_.backdrop_filters;
}
void SetBackdropFilterQuality(const float quality);
@@ -900,7 +900,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
SkColor background_color;
FilterOperations filters;
- FilterOperations background_filters;
+ FilterOperations backdrop_filters;
gfx::PointF filters_origin;
float backdrop_filter_quality;
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 3a4bf4536a8..3a1f4e9aadf 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -14,7 +14,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
#include "cc/base/simple_enclosed_region.h"
#include "cc/benchmarks/micro_benchmark_impl.h"
@@ -789,7 +789,7 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
*state);
if (debug_info_)
- state->SetValue("debug_info", *debug_info_);
+ state->SetValue("debug_info", debug_info_);
}
size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
diff --git a/chromium/cc/layers/layer_impl_test_properties.h b/chromium/cc/layers/layer_impl_test_properties.h
index 038c420cac6..c931d45d95f 100644
--- a/chromium/cc/layers/layer_impl_test_properties.h
+++ b/chromium/cc/layers/layer_impl_test_properties.h
@@ -47,7 +47,7 @@ struct CC_EXPORT LayerImplTestProperties {
int sorting_context_id;
float opacity;
FilterOperations filters;
- FilterOperations background_filters;
+ FilterOperations backdrop_filters;
float backdrop_filter_quality;
gfx::PointF filters_origin;
SkBlendMode blend_mode;
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index 1b4dc11a35e..1f207f8e3bc 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -397,7 +397,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
- root->SetBackgroundFilters(arbitrary_filters));
+ root->SetBackdropFilters(arbitrary_filters));
EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
root->PushPropertiesTo(root_impl.get());
child->PushPropertiesTo(child_impl.get());
diff --git a/chromium/cc/layers/nine_patch_generator.cc b/chromium/cc/layers/nine_patch_generator.cc
index ac64a5049e1..7677f48bd11 100644
--- a/chromium/cc/layers/nine_patch_generator.cc
+++ b/chromium/cc/layers/nine_patch_generator.cc
@@ -360,7 +360,9 @@ void NinePatchGenerator::AppendQuads(LayerImpl* layer_impl,
quad->SetNew(shared_quad_state, output_rect, visible_rect, needs_blending,
resource, premultiplied_alpha, image_rect.origin(),
image_rect.bottom_right(), SK_ColorTRANSPARENT,
- vertex_opacity, flipped, nearest_neighbor_, false);
+ vertex_opacity, flipped, nearest_neighbor_,
+ /*secure_output_only=*/false,
+ ui::ProtectedVideoType::kClear);
layer_impl->ValidateQuadResources(quad);
}
}
diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer_impl.cc
index 831dffcf63c..c7e055e541d 100644
--- a/chromium/cc/layers/painted_overlay_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/painted_overlay_scrollbar_layer_impl.cc
@@ -158,11 +158,11 @@ void PaintedOverlayScrollbarLayerImpl::AppendTrackQuads(
float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
viz::TextureDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- quad->SetNew(shared_quad_state, scaled_track_quad_rect,
- scaled_visible_track_quad_rect, needs_blending,
- track_resource_id, premultipled_alpha, uv_top_left,
- uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped,
- nearest_neighbor, false);
+ quad->SetNew(
+ shared_quad_state, scaled_track_quad_rect, scaled_visible_track_quad_rect,
+ needs_blending, track_resource_id, premultipled_alpha, uv_top_left,
+ uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor,
+ /*secure_output_only=*/false, ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
index 912e2a0a322..09febcc0984 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
@@ -124,7 +124,8 @@ void PaintedScrollbarLayerImpl::AppendQuads(
scaled_visible_thumb_quad_rect, needs_blending,
thumb_resource_id, premultipled_alpha, uv_top_left,
uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped,
- nearest_neighbor, false);
+ nearest_neighbor, /*secure_output_only=*/false,
+ ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
}
@@ -143,7 +144,8 @@ void PaintedScrollbarLayerImpl::AppendQuads(
scaled_visible_track_quad_rect, needs_blending,
track_resource_id, premultipled_alpha, uv_top_left,
uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped,
- nearest_neighbor, false);
+ nearest_neighbor, /*secure_output_only=*/false,
+ ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
}
}
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index 94772c09ab4..5c4c58fc5da 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -15,7 +15,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/time/time.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "cc/benchmarks/micro_benchmark_impl.h"
@@ -526,7 +526,8 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
if (!has_draw_quad) {
// Checkerboard.
SkColor color = SafeOpaqueBackgroundColor();
- if (ShowDebugBorders(DebugBorderType::LAYER)) {
+ if (mask_type_ == Layer::LayerMaskType::NOT_MASK &&
+ ShowDebugBorders(DebugBorderType::LAYER)) {
// Fill the whole tile with the missing tile color.
color = DebugColors::OOMTileBorderColor();
}
@@ -1560,13 +1561,30 @@ void PictureLayerImpl::UpdateIdealScales() {
float min_contents_scale = MinimumContentsScale();
DCHECK_GT(min_contents_scale, 0.f);
- ideal_page_scale_ = IsAffectedByPageScale()
- ? layer_tree_impl()->current_page_scale_factor()
- : 1.f;
ideal_device_scale_ = layer_tree_impl()->device_scale_factor();
+ if (layer_tree_impl()->PageScaleLayer()) {
+ ideal_page_scale_ = IsAffectedByPageScale()
+ ? layer_tree_impl()->current_page_scale_factor()
+ : 1.f;
+ ideal_contents_scale_ = GetIdealContentsScale();
+ } else {
+ // This layer may be in a layer tree embedded in a hierarchy that has its
+ // own page scale factor. We represent that here as
+ // 'external_page_scale_factor', a value that affects raster scale in the
+ // same way that page_scale_factor does, but doesn't affect any geometry
+ // calculations.
+ float external_page_scale_factor =
+ layer_tree_impl() ? layer_tree_impl()->external_page_scale_factor()
+ : 1.f;
+ DCHECK(!layer_tree_impl() || external_page_scale_factor == 1.f ||
+ layer_tree_impl()->current_page_scale_factor() == 1.f);
+ ideal_page_scale_ = external_page_scale_factor;
+ ideal_contents_scale_ =
+ GetIdealContentsScale() * external_page_scale_factor;
+ }
ideal_contents_scale_ =
std::min(kMaxIdealContentsScale,
- std::max(GetIdealContentsScale(), min_contents_scale));
+ std::max(ideal_contents_scale_, min_contents_scale));
ideal_source_scale_ =
ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
}
diff --git a/chromium/cc/layers/recording_source_unittest.cc b/chromium/cc/layers/recording_source_unittest.cc
index 15b5249fc10..dbdcaa17c49 100644
--- a/chromium/cc/layers/recording_source_unittest.cc
+++ b/chromium/cc/layers/recording_source_unittest.cc
@@ -16,10 +16,6 @@
namespace cc {
namespace {
-gfx::ColorSpace DefaultColorSpace() {
- return gfx::ColorSpace::CreateSRGB();
-}
-
std::unique_ptr<FakeRecordingSource> CreateRecordingSource(
const gfx::Rect& viewport) {
gfx::Rect layer_rect(viewport.right(), viewport.bottom());
@@ -110,8 +106,7 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) {
std::vector<const DrawImage*> images;
raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128),
&images);
- DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex);
EXPECT_EQ(1u, images.size());
EXPECT_FLOAT_EQ(scale, image.scale().width());
EXPECT_FLOAT_EQ(scale, image.scale().height());
@@ -160,12 +155,8 @@ TEST(RecordingSourceTest, NoDiscardableImages) {
PaintFlags simple_flags;
simple_flags.setColor(SkColorSetARGB(255, 12, 23, 34));
- SkBitmap non_discardable_bitmap;
- non_discardable_bitmap.allocN32Pixels(128, 128);
- non_discardable_bitmap.setImmutable();
- sk_sp<SkImage> non_discardable_image =
- SkImage::MakeFromBitmap(non_discardable_bitmap);
-
+ auto non_discardable_image =
+ CreateNonDiscardablePaintImage(gfx::Size(128, 128));
recording_source->add_draw_rect_with_flags(gfx::Rect(0, 0, 256, 256),
simple_flags);
recording_source->add_draw_rect_with_flags(gfx::Rect(128, 128, 512, 512),
@@ -274,12 +265,8 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) {
std::unique_ptr<FakeRecordingSource> recording_source =
CreateRecordingSource(recorded_viewport);
-
- SkBitmap non_discardable_bitmap;
- non_discardable_bitmap.allocN32Pixels(512, 512);
- non_discardable_bitmap.setImmutable();
- sk_sp<SkImage> non_discardable_image =
- SkImage::MakeFromBitmap(non_discardable_bitmap);
+ PaintImage non_discardable_image =
+ CreateNonDiscardablePaintImage(gfx::Size(512, 512));
PaintImage discardable_image[2][2];
discardable_image[0][0] = CreateDiscardablePaintImage(gfx::Size(128, 128));
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index 1461252b8ed..d4a0e72f590 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -149,8 +149,8 @@ gfx::Transform RenderSurfaceImpl::SurfaceScale() const {
return surface_scale;
}
-const FilterOperations& RenderSurfaceImpl::BackgroundFilters() const {
- return OwningEffectNode()->background_filters;
+const FilterOperations& RenderSurfaceImpl::BackdropFilters() const {
+ return OwningEffectNode()->backdrop_filters;
}
bool RenderSurfaceImpl::TrilinearFiltering() const {
@@ -374,7 +374,7 @@ std::unique_ptr<viz::RenderPass> RenderSurfaceImpl::CreateRenderPass() {
pass->SetNew(id(), content_rect(), damage_rect,
draw_properties_.screen_space_transform);
pass->filters = Filters();
- pass->background_filters = BackgroundFilters();
+ pass->backdrop_filters = BackdropFilters();
pass->generate_mipmap = TrilinearFiltering();
pass->cache_render_pass = ShouldCacheRenderSurface();
pass->has_damage_from_contributing_content =
diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h
index 8e7c143087f..6e648a4d8ff 100644
--- a/chromium/cc/layers/render_surface_impl.h
+++ b/chromium/cc/layers/render_surface_impl.h
@@ -149,7 +149,7 @@ class CC_EXPORT RenderSurfaceImpl {
bool HasMaskingContributingSurface() const;
const FilterOperations& Filters() const;
- const FilterOperations& BackgroundFilters() const;
+ const FilterOperations& BackdropFilters() 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 031d23cf451..4425f722798 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -1342,7 +1342,7 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest {
layer_tree_host_->SetViewportSizeAndScale(
layer_tree_host_->device_viewport_size(), test_scale,
- layer_tree_host_->local_surface_id_from_parent());
+ layer_tree_host_->local_surface_id_allocation_from_parent());
scrollbar_layer->Update();
@@ -1407,7 +1407,7 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest {
layer_tree_host_->SetViewportSizeAndScale(
layer_tree_host_->device_viewport_size(), test_scale,
- layer_tree_host_->local_surface_id_from_parent());
+ layer_tree_host_->local_surface_id_allocation_from_parent());
scrollbar_layer->Update();
diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc
index 89dca4bd5c4..7611dd03e9d 100644
--- a/chromium/cc/layers/surface_layer.cc
+++ b/chromium/cc/layers/surface_layer.cc
@@ -34,8 +34,8 @@ SurfaceLayer::~SurfaceLayer() {
DCHECK(!layer_tree_host());
}
-void SurfaceLayer::SetPrimarySurfaceId(const viz::SurfaceId& surface_id,
- const DeadlinePolicy& deadline_policy) {
+void SurfaceLayer::SetSurfaceId(const viz::SurfaceId& surface_id,
+ const DeadlinePolicy& deadline_policy) {
if (surface_range_.end() == surface_id &&
deadline_policy.use_existing_deadline()) {
return;
@@ -46,7 +46,7 @@ void SurfaceLayer::SetPrimarySurfaceId(const viz::SurfaceId& surface_id,
"LocalSurfaceId.Embed.Flow",
TRACE_ID_GLOBAL(surface_id.local_surface_id().embed_trace_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "SetPrimarySurfaceId", "surface_id", surface_id.ToString());
+ "SetSurfaceId", "surface_id", surface_id.ToString());
if (layer_tree_host() && surface_range_.IsValid())
layer_tree_host()->RemoveSurfaceRange(surface_range_);
@@ -67,7 +67,8 @@ void SurfaceLayer::SetPrimarySurfaceId(const viz::SurfaceId& surface_id,
SetNeedsCommit();
}
-void SurfaceLayer::SetFallbackSurfaceId(const viz::SurfaceId& surface_id) {
+void SurfaceLayer::SetOldestAcceptableFallback(
+ const viz::SurfaceId& surface_id) {
// The fallback should never move backwards.
DCHECK(!surface_range_.start() ||
!surface_range_.start()->IsNewerThan(surface_id));
@@ -78,7 +79,7 @@ void SurfaceLayer::SetFallbackSurfaceId(const viz::SurfaceId& surface_id) {
"LocalSurfaceId.Submission.Flow",
TRACE_ID_GLOBAL(surface_id.local_surface_id().submission_trace_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "SetFallbackSurfaceId", "surface_id", surface_id.ToString());
+ "SetOldestAcceptableFallback", "surface_id", surface_id.ToString());
if (layer_tree_host() && surface_range_.IsValid())
layer_tree_host()->RemoveSurfaceRange(surface_range_);
@@ -152,7 +153,7 @@ void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
TRACE_EVENT0("cc", "SurfaceLayer::PushPropertiesTo");
SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
layer_impl->SetRange(surface_range_, std::move(deadline_in_frames_));
- // Unless the client explicitly calls SetPrimarySurfaceId again after this
+ // Unless the client explicitly calls SetSurfaceId again after this
// commit, don't block on |surface_range_| again.
deadline_in_frames_ = 0u;
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
diff --git a/chromium/cc/layers/surface_layer.h b/chromium/cc/layers/surface_layer.h
index 8a832fba879..61c78304062 100644
--- a/chromium/cc/layers/surface_layer.h
+++ b/chromium/cc/layers/surface_layer.h
@@ -27,9 +27,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
static scoped_refptr<SurfaceLayer> Create();
static scoped_refptr<SurfaceLayer> Create(UpdateSubmissionStateCB);
- void SetPrimarySurfaceId(const viz::SurfaceId& surface_id,
- const DeadlinePolicy& deadline_policy);
- void SetFallbackSurfaceId(const viz::SurfaceId& surface_id);
+ void SetSurfaceId(const viz::SurfaceId& surface_id,
+ const DeadlinePolicy& deadline_policy);
+ void SetOldestAcceptableFallback(const viz::SurfaceId& surface_id);
// When stretch_content_to_fill_bounds is true, the scale of the embedded
// surface is ignored and the content will be stretched to fill the bounds.
@@ -49,11 +49,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
void SetLayerTreeHost(LayerTreeHost* host) override;
void PushPropertiesTo(LayerImpl* layer) override;
- const viz::SurfaceId& primary_surface_id() const {
- return surface_range_.end();
- }
+ const viz::SurfaceId& surface_id() const { return surface_range_.end(); }
- const base::Optional<viz::SurfaceId>& fallback_surface_id() const {
+ const base::Optional<viz::SurfaceId>& oldest_acceptable_fallback() const {
return surface_range_.start();
}
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index ad3031ebcc1..23810a45400 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -6,7 +6,7 @@
#include <stdint.h>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/debug/debug_colors.h"
#include "cc/layers/append_quads_data.h"
#include "cc/trees/layer_tree_impl.h"
@@ -49,8 +49,7 @@ void SurfaceLayerImpl::SetRange(const viz::SurfaceRange& surface_range,
TRACE_ID_GLOBAL(
surface_range.end().local_surface_id().embed_trace_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "ImplSetPrimarySurfaceId", "surface_id",
- surface_range.end().ToString());
+ "ImplSetSurfaceId", "surface_id", surface_range.end().ToString());
}
if (surface_range.start() &&
@@ -61,7 +60,7 @@ void SurfaceLayerImpl::SetRange(const viz::SurfaceRange& surface_range,
TRACE_ID_GLOBAL(
surface_range.start()->local_surface_id().submission_trace_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "ImplSetFallbackSurfaceId", "surface_id",
+ "ImplSetOldestAcceptableFallback", "surface_id",
surface_range.start()->ToString());
}
@@ -180,7 +179,8 @@ viz::SurfaceDrawQuad* SurfaceLayerImpl::CreateSurfaceDrawQuad(
render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
surface_draw_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
surface_range, background_color(),
- stretch_content_to_fill_bounds_);
+ stretch_content_to_fill_bounds_,
+ has_pointer_events_none_);
return surface_draw_quad;
}
diff --git a/chromium/cc/layers/surface_layer_unittest.cc b/chromium/cc/layers/surface_layer_unittest.cc
index 57be59a6142..3faa62a9544 100644
--- a/chromium/cc/layers/surface_layer_unittest.cc
+++ b/chromium/cc/layers/surface_layer_unittest.cc
@@ -12,6 +12,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "cc/animation/animation_host.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
@@ -56,7 +57,7 @@ class SurfaceLayerTest : public testing::Test {
layer_tree_host_ = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host_.get());
layer_tree_host_->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
host_impl_.CreatePendingTree();
}
@@ -83,7 +84,7 @@ TEST_F(SurfaceLayerTest, UseExistingDeadlineForNewSurfaceLayer) {
viz::SurfaceId primary_id(
kArbitraryFrameSinkId,
viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
- layer->SetPrimarySurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
EXPECT_EQ(0u, layer->deadline_in_frames());
}
@@ -95,7 +96,7 @@ TEST_F(SurfaceLayerTest, UseInfiniteDeadlineForNewSurfaceLayer) {
viz::SurfaceId primary_id(
kArbitraryFrameSinkId,
viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
- layer->SetPrimarySurfaceId(primary_id, DeadlinePolicy::UseInfiniteDeadline());
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseInfiniteDeadline());
EXPECT_EQ(std::numeric_limits<uint32_t>::max(), layer->deadline_in_frames());
}
@@ -107,14 +108,13 @@ TEST_F(SurfaceLayerTest, ResetDeadlineOnInvalidSurfaceId) {
viz::SurfaceId primary_id(
kArbitraryFrameSinkId,
viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
- layer->SetPrimarySurfaceId(primary_id,
- DeadlinePolicy::UseSpecifiedDeadline(3u));
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(3u));
EXPECT_EQ(3u, layer->deadline_in_frames());
// Reset the surface layer to an invalid SurfaceId. Verify that the deadline
// is reset.
- layer->SetPrimarySurfaceId(viz::SurfaceId(),
- DeadlinePolicy::UseSpecifiedDeadline(3u));
+ layer->SetSurfaceId(viz::SurfaceId(),
+ DeadlinePolicy::UseSpecifiedDeadline(3u));
EXPECT_EQ(0u, layer->deadline_in_frames());
}
@@ -126,12 +126,10 @@ TEST_F(SurfaceLayerTest, PushProperties) {
viz::SurfaceId primary_id(
kArbitraryFrameSinkId,
viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
- layer->SetPrimarySurfaceId(primary_id,
- DeadlinePolicy::UseSpecifiedDeadline(1u));
- layer->SetPrimarySurfaceId(primary_id,
- DeadlinePolicy::UseSpecifiedDeadline(2u));
- layer->SetPrimarySurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
- layer->SetFallbackSurfaceId(primary_id);
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(1u));
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(2u));
+ layer->SetSurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
+ layer->SetOldestAcceptableFallback(primary_id);
layer->SetBackgroundColor(SK_ColorBLUE);
layer->SetStretchContentToFillBounds(true);
@@ -164,9 +162,8 @@ TEST_F(SurfaceLayerTest, PushProperties) {
viz::SurfaceId fallback_id(
kArbitraryFrameSinkId,
viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
- layer->SetFallbackSurfaceId(fallback_id);
- layer->SetPrimarySurfaceId(fallback_id,
- DeadlinePolicy::UseExistingDeadline());
+ layer->SetOldestAcceptableFallback(fallback_id);
+ layer->SetSurfaceId(fallback_id, DeadlinePolicy::UseExistingDeadline());
layer->SetBackgroundColor(SK_ColorGREEN);
layer->SetStretchContentToFillBounds(false);
@@ -201,17 +198,15 @@ TEST_F(SurfaceLayerTest, CheckSurfaceReferencesForClonedLayer) {
// animation is done.
scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create();
layer1->SetLayerTreeHost(layer_tree_host_.get());
- layer1->SetPrimarySurfaceId(old_surface_id,
- DeadlinePolicy::UseDefaultDeadline());
- layer1->SetFallbackSurfaceId(old_surface_id);
+ layer1->SetSurfaceId(old_surface_id, DeadlinePolicy::UseDefaultDeadline());
+ layer1->SetOldestAcceptableFallback(old_surface_id);
// This layer will eventually be switched be switched to show the new surface
// id and will be retained when animation is done.
scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create();
layer2->SetLayerTreeHost(layer_tree_host_.get());
- layer2->SetPrimarySurfaceId(old_surface_id,
- DeadlinePolicy::UseDefaultDeadline());
- layer2->SetFallbackSurfaceId(old_surface_id);
+ layer2->SetSurfaceId(old_surface_id, DeadlinePolicy::UseDefaultDeadline());
+ layer2->SetOldestAcceptableFallback(old_surface_id);
std::unique_ptr<SurfaceLayerImpl> layer_impl1 =
SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer1->id());
@@ -231,9 +226,8 @@ TEST_F(SurfaceLayerTest, CheckSurfaceReferencesForClonedLayer) {
viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
// Switch the new layer to use |new_surface_id|.
- layer2->SetPrimarySurfaceId(new_surface_id,
- DeadlinePolicy::UseDefaultDeadline());
- layer2->SetFallbackSurfaceId(new_surface_id);
+ layer2->SetSurfaceId(new_surface_id, DeadlinePolicy::UseDefaultDeadline());
+ layer2->SetOldestAcceptableFallback(new_surface_id);
SynchronizeTrees();
@@ -269,8 +263,8 @@ TEST_F(SurfaceLayerTest, CheckNeedsSurfaceIdsSyncForClonedLayers) {
scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create();
layer1->SetLayerTreeHost(layer_tree_host_.get());
- layer1->SetPrimarySurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
- layer1->SetFallbackSurfaceId(surface_id);
+ layer1->SetSurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
+ layer1->SetOldestAcceptableFallback(surface_id);
// Verify the surface id is in SurfaceLayerIds() and
// needs_surface_ranges_sync() is true.
@@ -287,8 +281,8 @@ TEST_F(SurfaceLayerTest, CheckNeedsSurfaceIdsSyncForClonedLayers) {
// Create the second layer that is a clone of the first.
scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create();
layer2->SetLayerTreeHost(layer_tree_host_.get());
- layer2->SetPrimarySurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
- layer2->SetFallbackSurfaceId(surface_id);
+ layer2->SetSurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
+ layer2->SetOldestAcceptableFallback(surface_id);
// Verify that after creating the second layer with the same surface id that
// needs_surface_ranges_sync() is still false.
diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc
index f1b6e748a16..9d2e07594a9 100644
--- a/chromium/cc/layers/texture_layer_impl.cc
+++ b/chromium/cc/layers/texture_layer_impl.cc
@@ -155,7 +155,8 @@ void TextureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, needs_blending,
resource_id_, premultiplied_alpha_, uv_top_left_,
uv_bottom_right_, bg_color, vertex_opacity_, flipped_,
- nearest_neighbor_, false);
+ nearest_neighbor_, /*secure_output_only=*/false,
+ ui::ProtectedVideoType::kClear);
quad->set_resource_size_in_pixels(transferable_resource_.size);
ValidateQuadResources(quad);
}
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index ef8c52d3697..de62de061e6 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -175,7 +175,7 @@ class TextureLayerTest : public testing::Test {
&fake_client_, &task_graph_runner_, animation_host_.get());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
@@ -268,7 +268,7 @@ TEST_F(TextureLayerTest, ShutdownWithResource) {
}
host->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
host->SetVisible(true);
host->SetRootLayer(layer);
@@ -710,7 +710,7 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
SetMailbox('1');
EXPECT_EQ(0, callback_count_);
@@ -781,7 +781,7 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
SetMailbox('1');
PostSetNeedsCommitToMainThread();
@@ -1312,7 +1312,7 @@ class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
}
void BeginTest() override {
@@ -1382,7 +1382,7 @@ class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
}
void BeginTest() override {
diff --git a/chromium/cc/layers/ui_resource_layer_impl.cc b/chromium/cc/layers/ui_resource_layer_impl.cc
index e34f189493d..c3a94fc6fbc 100644
--- a/chromium/cc/layers/ui_resource_layer_impl.cc
+++ b/chromium/cc/layers/ui_resource_layer_impl.cc
@@ -130,7 +130,7 @@ void UIResourceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, needs_blending,
resource, premultiplied_alpha, uv_top_left_, uv_bottom_right_,
SK_ColorTRANSPARENT, vertex_opacity_, flipped, nearest_neighbor,
- false);
+ /*secure_output_only=*/false, ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
}
diff --git a/chromium/cc/layers/video_layer_impl.cc b/chromium/cc/layers/video_layer_impl.cc
index c356a8f66a9..84c9913b451 100644
--- a/chromium/cc/layers/video_layer_impl.cc
+++ b/chromium/cc/layers/video_layer_impl.cc
@@ -122,6 +122,8 @@ void VideoLayerImpl::AppendQuads(viz::RenderPass* render_pass,
DCHECK(frame_.get());
gfx::Transform transform = DrawTransform();
+ // bounds() is in post-rotation space so quad rect in content space must be
+ // in pre-rotation space
gfx::Size rotated_size = bounds();
switch (video_rotation_) {
@@ -143,20 +145,19 @@ void VideoLayerImpl::AppendQuads(viz::RenderPass* render_pass,
break;
}
+ gfx::Rect quad_rect(rotated_size);
Occlusion occlusion_in_video_space =
draw_properties()
.occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
transform);
gfx::Rect visible_quad_rect =
- occlusion_in_video_space.GetUnoccludedContentRect(
- gfx::Rect(rotated_size));
+ occlusion_in_video_space.GetUnoccludedContentRect(quad_rect);
if (visible_quad_rect.IsEmpty())
return;
- updater_->AppendQuads(render_pass, frame_, transform, rotated_size,
- visible_quad_rect, clip_rect(), is_clipped(),
- contents_opaque(), draw_opacity(),
- GetSortingContextId(), visible_quad_rect);
+ updater_->AppendQuads(
+ render_pass, frame_, transform, quad_rect, visible_quad_rect, clip_rect(),
+ is_clipped(), contents_opaque(), draw_opacity(), GetSortingContextId());
}
void VideoLayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc
index f7f67de0341..f70e8e22646 100644
--- a/chromium/cc/layers/video_layer_impl_unittest.cc
+++ b/chromium/cc/layers/video_layer_impl_unittest.cc
@@ -394,8 +394,6 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
ASSERT_TRUE(video_frame);
video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY,
true);
- video_frame->metadata()->SetBoolean(
- media::VideoFrameMetadata::REQUIRE_OVERLAY, true);
FakeVideoFrameProvider provider;
provider.set_frame(video_frame);
@@ -419,7 +417,6 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
(yuv_draw_quad->ya_tex_size.height() + 1) / 2);
EXPECT_EQ(yuv_draw_quad->uv_tex_size.width(),
(yuv_draw_quad->ya_tex_size.width() + 1) / 2);
- EXPECT_TRUE(yuv_draw_quad->require_overlay);
}
TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) {
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 34be99f811b..3dfd15b8666 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -16,6 +16,7 @@
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/quads/compositor_frame.h"
@@ -97,6 +98,10 @@ AsyncLayerTreeFrameSink::AsyncLayerTreeFrameSink(
"GraphicsPipeline.%s.SubmitCompositorFrameAfterBeginFrame",
params->client_name)),
weak_factory_(this) {
+ // We should not create hit test data provider if we want to use cc layer tree
+ // to generated data.
+ if (features::IsVizHitTestingSurfaceLayerEnabled())
+ DCHECK(!params->hit_test_data_provider);
DETACH_FROM_THREAD(thread_checker_);
}
@@ -161,7 +166,8 @@ void AsyncLayerTreeFrameSink::SetLocalSurfaceId(
}
void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ 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);
@@ -180,8 +186,11 @@ void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
}
if (!enable_surface_synchronization_) {
- local_surface_id_ =
- local_surface_id_provider_->GetLocalSurfaceIdForFrame(frame);
+ const viz::LocalSurfaceIdAllocation& local_surface_id_allocation =
+ local_surface_id_provider_->GetLocalSurfaceIdAllocationForFrame(frame);
+ local_surface_id_ = local_surface_id_allocation.local_surface_id();
+ frame.metadata.local_surface_id_allocation_time =
+ local_surface_id_allocation.allocation_time();
} else {
if (local_surface_id_ == last_submitted_local_surface_id_) {
DCHECK_EQ(last_submitted_device_scale_factor_,
@@ -205,6 +214,9 @@ void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
else
hit_test_region_list = client_->BuildHitTestData();
+ if (show_hit_test_borders && hit_test_region_list)
+ hit_test_region_list->flags |= viz::HitTestRegionFlags::kHitTestDebug;
+
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();
@@ -260,6 +272,11 @@ void AsyncLayerTreeFrameSink::DidDeleteSharedBitmap(
compositor_frame_sink_ptr_->DidDeleteSharedBitmap(id);
}
+void AsyncLayerTreeFrameSink::ForceAllocateNewId() {
+ DCHECK(!enable_surface_synchronization_);
+ local_surface_id_provider_->ForceAllocateNewId();
+}
+
void AsyncLayerTreeFrameSink::DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -267,14 +284,13 @@ void AsyncLayerTreeFrameSink::DidReceiveCompositorFrameAck(
client_->DidReceiveCompositorFrameAck();
}
-void AsyncLayerTreeFrameSink::DidPresentCompositorFrame(
- uint32_t presentation_token,
- const gfx::PresentationFeedback& feedback) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- client_->DidPresentCompositorFrame(presentation_token, feedback);
-}
+void AsyncLayerTreeFrameSink::OnBeginFrame(
+ const viz::BeginFrameArgs& args,
+ const base::flat_map<uint32_t, gfx::PresentationFeedback>& feedbacks) {
+ for (const auto& pair : feedbacks) {
+ client_->DidPresentCompositorFrame(pair.first, pair.second);
+ }
-void AsyncLayerTreeFrameSink::OnBeginFrame(const viz::BeginFrameArgs& args) {
DCHECK_LE(pipeline_reporting_frame_times_.size(), 25u);
if (args.trace_id != -1) {
base::TimeTicks current_time = base::TimeTicks::Now();
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 71be58d39f3..f3f3be12461 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
@@ -117,20 +117,21 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
bool BindToClient(LayerTreeFrameSinkClient* client) override;
void DetachFromClient() override;
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
- void SubmitCompositorFrame(viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool show_hit_test_borders) override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
const viz::SharedBitmapId& id) override;
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
+ void ForceAllocateNewId() override;
private:
// mojom::CompositorFrameSinkClient implementation:
void DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) override;
- void DidPresentCompositorFrame(
- uint32_t presentation_token,
- const gfx::PresentationFeedback& feedback) override;
- void OnBeginFrame(const viz::BeginFrameArgs& begin_frame_args) override;
+ void OnBeginFrame(const viz::BeginFrameArgs& begin_frame_args,
+ const base::flat_map<uint32_t, gfx::PresentationFeedback>&
+ feedbacks) override;
void OnBeginFramePausedChanged(bool paused) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
diff --git a/chromium/cc/paint/BUILD.gn b/chromium/cc/paint/BUILD.gn
index 6ea4596b91b..21c6b8b7b5d 100644
--- a/chromium/cc/paint/BUILD.gn
+++ b/chromium/cc/paint/BUILD.gn
@@ -31,14 +31,14 @@ cc_component("paint") {
"image_provider.h",
"image_transfer_cache_entry.cc",
"image_transfer_cache_entry.h",
+ "paint_cache.cc",
+ "paint_cache.h",
"paint_canvas.h",
"paint_export.h",
"paint_filter.cc",
"paint_filter.h",
"paint_flags.cc",
"paint_flags.h",
- "paint_font.cc",
- "paint_font.h",
"paint_image.cc",
"paint_image.h",
"paint_image_builder.cc",
@@ -59,12 +59,6 @@ cc_component("paint") {
"paint_recorder.h",
"paint_shader.cc",
"paint_shader.h",
- "paint_text_blob.cc",
- "paint_text_blob.h",
- "paint_text_blob_builder.cc",
- "paint_text_blob_builder.h",
- "path_transfer_cache_entry.cc",
- "path_transfer_cache_entry.h",
"raw_memory_transfer_cache_entry.cc",
"raw_memory_transfer_cache_entry.h",
"record_paint_canvas.cc",
@@ -79,6 +73,8 @@ cc_component("paint") {
"skia_paint_canvas.h",
"skia_paint_image_generator.cc",
"skia_paint_image_generator.h",
+ "skottie_wrapper.cc",
+ "skottie_wrapper.h",
"solid_color_analyzer.cc",
"solid_color_analyzer.h",
"transfer_cache_deserialize_helper.h",
@@ -124,19 +120,6 @@ fuzzer_test("paint_op_buffer_fuzzer") {
]
}
-fuzzer_test("paint_op_buffer_eq_fuzzer") {
- sources = [
- "paint_op_buffer_eq_fuzzer.cc",
- ]
-
- libfuzzer_options = [ "max_len=4096" ]
-
- deps = [
- "//cc:test_support",
- "//cc/paint",
- ]
-}
-
fuzzer_test("transfer_cache_fuzzer") {
sources = [
"transfer_cache_fuzzer.cc",
diff --git a/chromium/cc/paint/DEPS b/chromium/cc/paint/DEPS
index 78b223c0245..6d60ad8e8d6 100644
--- a/chromium/cc/paint/DEPS
+++ b/chromium/cc/paint/DEPS
@@ -9,4 +9,7 @@ specific_include_rules = {
"oop_pixeltest.cc": [
"+gpu/command_buffer",
],
+ "skottie_wrapper.h": [
+ "+third_party/skia",
+ ],
}
diff --git a/chromium/cc/paint/decoded_draw_image.h b/chromium/cc/paint/decoded_draw_image.h
index 3079fc48b9c..63bc1ca4e25 100644
--- a/chromium/cc/paint/decoded_draw_image.h
+++ b/chromium/cc/paint/decoded_draw_image.h
@@ -17,6 +17,11 @@
namespace cc {
+// A DecodedDrawImage is a finalized (decoded, scaled, colorspace converted,
+// possibly uploaded) version of a DrawImage. When this image is going to
+// be serialized, it uses the transfer cache entry id (see the function
+// PaintOpWriter::Write(DrawImage&) constructor. When this image is going
+// to be rastered directly, it uses the SkImage constructor.
class CC_PAINT_EXPORT DecodedDrawImage {
public:
DecodedDrawImage(sk_sp<const SkImage> image,
diff --git a/chromium/cc/paint/discardable_image_map.cc b/chromium/cc/paint/discardable_image_map.cc
index 1c53bb9b523..c9462f1595c 100644
--- a/chromium/cc/paint/discardable_image_map.cc
+++ b/chromium/cc/paint/discardable_image_map.cc
@@ -349,7 +349,7 @@ class DiscardableImageGenerator {
const gfx::Rect& image_rect,
const SkMatrix& matrix,
SkFilterQuality filter_quality) {
- if (!paint_image.IsLazyGenerated())
+ if (paint_image.IsTextureBacked())
return;
SkIRect src_irect;
@@ -452,7 +452,7 @@ DiscardableImageMap::TakeDecodingModeMap() {
void DiscardableImageMap::GetDiscardableImagesInRect(
const gfx::Rect& rect,
std::vector<const DrawImage*>* images) const {
- *images = images_rtree_.SearchRefs(rect);
+ images_rtree_.SearchRefs(rect, images);
}
const DiscardableImageMap::Rects& DiscardableImageMap::GetRectsForImage(
diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc
index 72d608b2e35..32ec754bbe1 100644
--- a/chromium/cc/paint/discardable_image_map_unittest.cc
+++ b/chromium/cc/paint/discardable_image_map_unittest.cc
@@ -55,17 +55,16 @@ class DiscardableImageMapTest : public testing::Test {
const DiscardableImageMap& image_map,
const gfx::Rect& rect) {
std::vector<const DrawImage*> draw_image_ptrs;
- // Choose a not-SRGB-and-not-invalid target color space to verify that it
- // is passed correctly to the resulting DrawImages.
- gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
image_map.GetDiscardableImagesInRect(rect, &draw_image_ptrs);
std::vector<DrawImage> draw_images;
for (const auto* image : draw_image_ptrs)
- draw_images.push_back(DrawImage(
- *image, 1.f, PaintImage::kDefaultFrameIndex, target_color_space));
+ draw_images.push_back(
+ DrawImage(*image, 1.f, PaintImage::kDefaultFrameIndex));
std::vector<PositionScaleDrawImage> position_draw_images;
- for (DrawImage& image : image_map.images_rtree_.Search(rect)) {
+ std::vector<DrawImage> results;
+ image_map.images_rtree_.Search(rect, &results);
+ for (DrawImage& image : results) {
auto image_id = image.paint_image().stable_id();
position_draw_images.push_back(PositionScaleDrawImage(
image.paint_image(),
@@ -77,7 +76,6 @@ class DiscardableImageMapTest : public testing::Test {
for (size_t i = 0; i < draw_images.size(); ++i) {
EXPECT_TRUE(draw_images[i].paint_image() ==
position_draw_images[i].image);
- EXPECT_EQ(draw_images[i].target_color_space(), target_color_space);
}
return position_draw_images;
}
diff --git a/chromium/cc/paint/display_item_list.cc b/chromium/cc/paint/display_item_list.cc
index cc8db474af3..cacbe80e5a5 100644
--- a/chromium/cc/paint/display_item_list.cc
+++ b/chromium/cc/paint/display_item_list.cc
@@ -9,7 +9,7 @@
#include <string>
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
#include "cc/debug/picture_debug_util.h"
#include "cc/paint/solid_color_analyzer.h"
@@ -51,7 +51,8 @@ void DisplayItemList::Raster(SkCanvas* canvas,
if (!GetCanvasClipBounds(canvas, &canvas_playback_rect))
return;
- std::vector<size_t> offsets = rtree_.Search(canvas_playback_rect);
+ std::vector<size_t> offsets;
+ rtree_.Search(canvas_playback_rect, &offsets);
paint_op_buffer_.Playback(canvas, PlaybackParams(image_provider), &offsets);
}
@@ -196,7 +197,7 @@ bool DisplayItemList::GetColorIfSolidInRect(const gfx::Rect& rect,
std::vector<size_t>* offsets_to_use = nullptr;
std::vector<size_t> offsets;
if (!rect.Contains(rtree_.GetBounds())) {
- offsets = rtree_.Search(rect);
+ rtree_.Search(rect, &offsets);
offsets_to_use = &offsets;
}
diff --git a/chromium/cc/paint/display_item_list_unittest.cc b/chromium/cc/paint/display_item_list_unittest.cc
index 5bcca13606d..0abe50d535c 100644
--- a/chromium/cc/paint/display_item_list_unittest.cc
+++ b/chromium/cc/paint/display_item_list_unittest.cc
@@ -8,7 +8,7 @@
#include <vector>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/paint/filter_operation.h"
#include "cc/paint/filter_operations.h"
diff --git a/chromium/cc/paint/draw_image.cc b/chromium/cc/paint/draw_image.cc
index a1a78af3b6c..984ccd5c87d 100644
--- a/chromium/cc/paint/draw_image.cc
+++ b/chromium/cc/paint/draw_image.cc
@@ -32,28 +32,24 @@ DrawImage::DrawImage(PaintImage image,
const SkIRect& src_rect,
SkFilterQuality filter_quality,
const SkMatrix& matrix,
- base::Optional<size_t> frame_index,
- const base::Optional<gfx::ColorSpace>& color_space)
+ base::Optional<size_t> frame_index)
: paint_image_(std::move(image)),
src_rect_(src_rect),
filter_quality_(filter_quality),
- frame_index_(frame_index),
- target_color_space_(color_space) {
+ frame_index_(frame_index) {
matrix_is_decomposable_ = ExtractScale(matrix, &scale_);
}
DrawImage::DrawImage(const DrawImage& other,
float scale_adjustment,
- size_t frame_index,
- const gfx::ColorSpace& color_space)
+ size_t frame_index)
: paint_image_(other.paint_image_),
src_rect_(other.src_rect_),
filter_quality_(other.filter_quality_),
scale_(SkSize::Make(other.scale_.width() * scale_adjustment,
other.scale_.height() * scale_adjustment)),
matrix_is_decomposable_(other.matrix_is_decomposable_),
- frame_index_(frame_index),
- target_color_space_(color_space) {}
+ frame_index_(frame_index) {}
DrawImage::DrawImage(const DrawImage& other) = default;
DrawImage::DrawImage(DrawImage&& other) = default;
@@ -65,8 +61,7 @@ DrawImage& DrawImage::operator=(const DrawImage& other) = default;
bool DrawImage::operator==(const DrawImage& other) const {
return paint_image_ == other.paint_image_ && src_rect_ == other.src_rect_ &&
filter_quality_ == other.filter_quality_ && scale_ == other.scale_ &&
- matrix_is_decomposable_ == other.matrix_is_decomposable_ &&
- target_color_space_ == other.target_color_space_;
+ matrix_is_decomposable_ == other.matrix_is_decomposable_;
}
} // namespace cc
diff --git a/chromium/cc/paint/draw_image.h b/chromium/cc/paint/draw_image.h
index 81c45d1cfd2..615b25eac11 100644
--- a/chromium/cc/paint/draw_image.h
+++ b/chromium/cc/paint/draw_image.h
@@ -13,11 +13,14 @@
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size_f.h"
namespace cc {
+// A DrawImage is a logical snapshot in time and space of a PaintImage. It
+// includes decisions about scaling, animation frame, etc.
+// It has not been decoded yet. DrawImage turns into DecodedDrawImage via
+// ImageDecodeCache::GetDecodedImageForDraw during playback.
class CC_PAINT_EXPORT DrawImage {
public:
DrawImage();
@@ -25,14 +28,9 @@ class CC_PAINT_EXPORT DrawImage {
const SkIRect& src_rect,
SkFilterQuality filter_quality,
const SkMatrix& matrix,
- base::Optional<size_t> frame_index = base::nullopt,
- const base::Optional<gfx::ColorSpace>& color_space = base::nullopt);
- // Constructs a DrawImage from |other| by adjusting its scale and setting a
- // new color_space.
- DrawImage(const DrawImage& other,
- float scale_adjustment,
- size_t frame_index,
- const gfx::ColorSpace& color_space);
+ base::Optional<size_t> frame_index = base::nullopt);
+ // Constructs a DrawImage from |other| by adjusting its scale and frame.
+ DrawImage(const DrawImage& other, float scale_adjustment, size_t frame_index);
DrawImage(const DrawImage& other);
DrawImage(DrawImage&& other);
~DrawImage();
@@ -47,10 +45,6 @@ class CC_PAINT_EXPORT DrawImage {
const SkIRect& src_rect() const { return src_rect_; }
SkFilterQuality filter_quality() const { return filter_quality_; }
bool matrix_is_decomposable() const { return matrix_is_decomposable_; }
- const gfx::ColorSpace& target_color_space() const {
- DCHECK(target_color_space_.has_value());
- return *target_color_space_;
- }
PaintImage::FrameKey frame_key() const {
return paint_image_.GetKeyForFrame(frame_index());
}
@@ -66,7 +60,6 @@ class CC_PAINT_EXPORT DrawImage {
SkSize scale_;
bool matrix_is_decomposable_;
base::Optional<size_t> frame_index_;
- base::Optional<gfx::ColorSpace> target_color_space_;
};
} // namespace cc
diff --git a/chromium/cc/paint/filter_operation.cc b/chromium/cc/paint/filter_operation.cc
index 221dd572fb7..3357afb235c 100644
--- a/chromium/cc/paint/filter_operation.cc
+++ b/chromium/cc/paint/filter_operation.cc
@@ -9,7 +9,7 @@
#include "cc/paint/filter_operation.h"
#include "base/numerics/ranges.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/base/math_util.h"
#include "ui/gfx/animation/tween.h"
diff --git a/chromium/cc/paint/filter_operations.cc b/chromium/cc/paint/filter_operations.cc
index cc2dcc5f7e6..a7e7312c381 100644
--- a/chromium/cc/paint/filter_operations.cc
+++ b/chromium/cc/paint/filter_operations.cc
@@ -9,7 +9,7 @@
#include <cmath>
#include <numeric>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/paint/filter_operation.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index c902b642b66..dedc9add23c 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -104,7 +104,7 @@ bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
// We don't need to populate the SerializeOptions here since the writer is
// only used for serializing primitives.
PaintOp::SerializeOptions options(nullptr, nullptr, nullptr, nullptr, nullptr,
- false, false, 0, 0, SkMatrix::I());
+ nullptr, false, false, 0, 0, SkMatrix::I());
PaintOpWriter writer(data.data(), data.size(), options);
writer.Write(pixmap_->colorType());
writer.Write(pixmap_->width());
@@ -144,7 +144,7 @@ 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);
+ PaintOp::DeserializeOptions options(nullptr, nullptr, nullptr);
PaintOpReader reader(data.data(), data.size(), options);
SkColorType color_type;
reader.Read(&color_type);
diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc
index d79fa1c341c..f86a674a381 100644
--- a/chromium/cc/paint/oop_pixeltest.cc
+++ b/chromium/cc/paint/oop_pixeltest.cc
@@ -14,7 +14,6 @@
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_image_builder.h"
-#include "cc/paint/paint_text_blob_builder.h"
#include "cc/raster/playback_image_provider.h"
#include "cc/raster/raster_source.h"
#include "cc/test/pixel_test_utils.h"
@@ -22,9 +21,12 @@
#include "cc/tiles/gpu_image_decode_cache.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_implementation.h"
#include "gpu/command_buffer/client/raster_implementation_gles.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/gr_shader_cache.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/ipc/gl_in_process_context.h"
@@ -74,22 +76,11 @@ class OopPixelTest : public testing::Test,
void SetUp() override {
InitializeOOPContext();
- const int raster_max_texture_size =
- raster_context_provider_->ContextCapabilities().max_texture_size;
-
gles2_context_provider_ =
base::MakeRefCounted<TestInProcessContextProvider>(
/*enable_oop_rasterization=*/false, /*support_locking=*/true);
gpu::ContextResult result = gles2_context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
- const int gles2_max_texture_size =
- raster_context_provider_->ContextCapabilities().max_texture_size;
- gpu_image_cache_.reset(new GpuImageDecodeCache(
- gles2_context_provider_.get(), false, kRGBA_8888_SkColorType,
- kWorkingSetSize, gles2_max_texture_size,
- PaintImage::kDefaultGeneratorClientId));
-
- ASSERT_EQ(raster_max_texture_size, gles2_max_texture_size);
}
// gpu::raster::GrShaderCache::Client implementation.
@@ -106,12 +97,24 @@ class OopPixelTest : public testing::Test,
&gr_shader_cache_, &activity_flags_);
gpu::ContextResult result = raster_context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
+ }
+
+ void CreateGpuImageCache(const gfx::ColorSpace& color_space) {
+ const int gles2_max_texture_size =
+ raster_context_provider_->ContextCapabilities().max_texture_size;
+ gpu_image_cache_.reset(new GpuImageDecodeCache(
+ gles2_context_provider_.get(), false, kRGBA_8888_SkColorType,
+ kWorkingSetSize, gles2_max_texture_size,
+ PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace()));
+ }
+
+ void CreateOopImageCache(const gfx::ColorSpace& color_space) {
const int raster_max_texture_size =
raster_context_provider_->ContextCapabilities().max_texture_size;
oop_image_cache_.reset(new GpuImageDecodeCache(
raster_context_provider_.get(), true, kRGBA_8888_SkColorType,
kWorkingSetSize, raster_max_texture_size,
- PaintImage::kDefaultGeneratorClientId));
+ PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace()));
}
class RasterOptions {
@@ -140,6 +143,7 @@ class OopPixelTest : public testing::Test,
SkColor preclear_color;
ImageDecodeCache* image_cache = nullptr;
std::vector<scoped_refptr<DisplayItemList>> additional_lists;
+ PaintShader* shader_with_animated_images = nullptr;
};
SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
@@ -150,36 +154,33 @@ class OopPixelTest : public testing::Test,
SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
+ CreateOopImageCache(options.color_space);
+
GURL url("https://example.com/foo");
TestInProcessContextProvider::ScopedRasterContextLock lock(
raster_context_provider_.get(), url.possibly_invalid_spec().c_str());
PlaybackImageProvider image_provider(oop_image_cache_.get(),
- options.color_space,
PlaybackImageProvider::Settings());
gpu::gles2::GLES2Interface* gl = gles2_context_provider_->ContextGL();
int width = options.resource_size.width();
int height = options.resource_size.height();
- // Create and allocate a texture on the raster interface.
- GLuint raster_texture_id;
-
+ // Create and allocate a shared image on the raster interface.
auto* raster_implementation = raster_context_provider_->RasterInterface();
- raster_texture_id = raster_implementation->CreateTexture(
- false, gfx::BufferUsage::GPU_READ, viz::ResourceFormat::RGBA_8888);
- raster_implementation->TexStorage2D(raster_texture_id, width, height);
- raster_implementation->TexParameteri(raster_texture_id,
- GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- EXPECT_EQ(raster_implementation->GetError(),
- static_cast<unsigned>(GL_NO_ERROR));
+ auto* sii = raster_context_provider_->SharedImageInterface();
+ uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
+ gpu::Mailbox mailbox = sii->CreateSharedImage(
+ viz::ResourceFormat::RGBA_8888, gfx::Size(width, height),
+ options.color_space, flags);
+ EXPECT_TRUE(mailbox.Verify());
+ raster_implementation->WaitSyncTokenCHROMIUM(
+ sii->GenUnverifiedSyncToken().GetConstData());
RasterColorSpace color_space(options.color_space, ++color_space_id_);
- gpu::Mailbox mailbox;
- raster_implementation->ProduceTextureDirect(raster_texture_id,
- mailbox.name);
if (options.preclear) {
raster_implementation->BeginRasterCHROMIUM(
options.preclear_color, options.msaa_sample_count,
@@ -224,8 +225,9 @@ class OopPixelTest : public testing::Test,
gl->DeleteTextures(1, &gl_texture_id);
gl->DeleteFramebuffers(1, &fbo_id);
- gl->OrderingBarrierCHROMIUM();
- raster_implementation->DeleteTextures(1, &raster_texture_id);
+ gpu::SyncToken sync_token;
+ gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
+ sii->DestroySharedImage(sync_token, mailbox);
// Swizzle rgba->bgra if needed.
std::vector<SkPMColor> colors;
@@ -258,6 +260,8 @@ class OopPixelTest : public testing::Test,
SkBitmap RasterExpectedBitmap(
scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
+ CreateGpuImageCache(options.color_space);
+
TestInProcessContextProvider::ScopedRasterContextLock lock(
gles2_context_provider_.get());
gles2_context_provider_->GrContext()->resetContext();
@@ -275,8 +279,10 @@ class OopPixelTest : public testing::Test,
layer_rect);
recording.SetRequiresClear(options.requires_clear);
+ if (options.shader_with_animated_images)
+ options.shader_with_animated_images->set_has_animated_images(true);
+
PlaybackImageProvider image_provider(gpu_image_cache_.get(),
- options.color_space,
PlaybackImageProvider::Settings());
auto raster_source = recording.CreateRasterSource();
@@ -605,9 +611,6 @@ TEST_P(OopImagePixelTest, DrawRecordShaderWithImageScaled) {
auto paint_record_shader = PaintShader::MakePaintRecord(
paint_record, gfx::RectToSkRect(rect), SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode, nullptr);
- // Set the shader has animated images so gpu also goes through cc's image
- // upload stack, instead of using skia.
- paint_record_shader->set_has_animated_images(true);
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
@@ -620,7 +623,11 @@ TEST_P(OopImagePixelTest, DrawRecordShaderWithImageScaled) {
display_item_list->Finalize();
auto actual = Raster(display_item_list, rect.size());
- auto expected = RasterExpectedBitmap(display_item_list, rect.size());
+ // Set the shader has animated images so gpu also goes through cc's image
+ // upload stack, instead of using skia.
+ RasterOptions expected_options(rect.size());
+ expected_options.shader_with_animated_images = paint_record_shader.get();
+ auto expected = RasterExpectedBitmap(display_item_list, expected_options);
ExpectEquals(actual, expected);
}
@@ -1202,8 +1209,11 @@ TEST_F(OopPixelTest, ClearingTransparentInternalTile) {
options.preclear = true;
options.preclear_color = SK_ColorRED;
- // Make a non-empty but noop display list to avoid early outs.
- auto display_item_list = MakeNoopDisplayItemList();
+ // Note that clearing of the tile should supersede any early outs due to an
+ // empty display list. This is due to the fact that partial raster may in fact
+ // result in no items being generated, in which case a clear should still
+ // happen. See crbug.com/901897.
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
auto oop_result = Raster(display_item_list, options);
auto gpu_result = RasterExpectedBitmap(display_item_list, options);
@@ -1386,33 +1396,31 @@ TEST_F(OopPixelTest, DrawRectColorSpace) {
ExpectEquals(actual, expected);
}
-scoped_refptr<PaintTextBlob> BuildTextBlob(
+sk_sp<SkTextBlob> BuildTextBlob(
sk_sp<SkTypeface> typeface = SkTypeface::MakeDefault(),
bool use_lcd_text = false) {
if (!typeface) {
typeface = SkTypeface::MakeFromName("monospace", SkFontStyle());
}
- PaintFont font;
- font.SetTypeface(typeface);
- font.SetTextEncoding(SkPaint::kGlyphID_TextEncoding);
- font.SetHinting(SkPaint::kNormal_Hinting);
- font.SetTextSize(1u);
+ SkFont font;
+ font.setTypeface(typeface);
+ font.setHinting(SkFontHinting::kNormal);
+ font.setSize(1u);
if (use_lcd_text) {
- font.SetAntiAlias(true);
- font.SetSubpixelText(true);
- font.SetLcdRenderText(true);
+ font.setSubpixel(true);
+ font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
}
- PaintTextBlobBuilder builder;
+ SkTextBlobBuilder builder;
SkRect bounds = SkRect::MakeWH(100, 100);
const int glyphCount = 10;
- const auto& runBuffer = builder.AllocRunPosH(font, glyphCount, 0, &bounds);
+ const auto& runBuffer = builder.allocRunPosH(font, glyphCount, 0, &bounds);
for (int i = 0; i < glyphCount; i++) {
runBuffer.glyphs[i] = static_cast<SkGlyphID>(i);
runBuffer.pos[i] = SkIntToScalar(i);
}
- return builder.TakeTextBlob();
+ return builder.make();
}
TEST_F(OopPixelTest, DrawTextBlob) {
@@ -1439,87 +1447,87 @@ TEST_F(OopPixelTest, DrawTextBlob) {
class OopRecordShaderPixelTest : public OopPixelTest,
public ::testing::WithParamInterface<bool> {
- public:
- bool UseLcdText() const { return GetParam(); }
- void RunTest() {
- ScopedEnableLCDText enable_lcd;
-
- RasterOptions options;
- options.resource_size = gfx::Size(100, 100);
- options.content_size = options.resource_size;
- options.full_raster_rect = gfx::Rect(options.content_size);
- options.playback_rect = options.full_raster_rect;
- options.color_space = gfx::ColorSpace::CreateSRGB();
- options.use_lcd_text = UseLcdText();
-
- auto paint_record = sk_make_sp<PaintOpBuffer>();
- PaintFlags flags;
- flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
- paint_record->push<DrawTextBlobOp>(
- BuildTextBlob(SkTypeface::MakeDefault(), UseLcdText()), 0u, 0u, flags);
- auto paint_record_shader = PaintShader::MakePaintRecord(
+ public:
+ bool UseLcdText() const { return GetParam(); }
+ void RunTest() {
+ ScopedEnableLCDText enable_lcd;
+
+ RasterOptions options;
+ options.resource_size = gfx::Size(100, 100);
+ options.content_size = options.resource_size;
+ options.full_raster_rect = gfx::Rect(options.content_size);
+ options.playback_rect = options.full_raster_rect;
+ options.color_space = gfx::ColorSpace::CreateSRGB();
+ options.use_lcd_text = UseLcdText();
+
+ auto paint_record = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ paint_record->push<DrawTextBlobOp>(
+ BuildTextBlob(SkTypeface::MakeDefault(), UseLcdText()), 0u, 0u, flags);
+ auto paint_record_shader = PaintShader::MakePaintRecord(
paint_record, SkRect::MakeWH(25, 25), SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode, nullptr);
- auto display_item_list = base::MakeRefCounted<DisplayItemList>();
- display_item_list->StartPaint();
- display_item_list->push<ScaleOp>(2.f, 2.f);
- PaintFlags shader_flags;
- shader_flags.setShader(paint_record_shader);
- display_item_list->push<DrawRectOp>(SkRect::MakeWH(50, 50), shader_flags);
- display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
- display_item_list->Finalize();
-
- auto actual = Raster(display_item_list, options);
- auto expected = RasterExpectedBitmap(display_item_list, options);
- ExpectEquals(actual, expected);
- }
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+ display_item_list->StartPaint();
+ display_item_list->push<ScaleOp>(2.f, 2.f);
+ PaintFlags shader_flags;
+ shader_flags.setShader(paint_record_shader);
+ display_item_list->push<DrawRectOp>(SkRect::MakeWH(50, 50), shader_flags);
+ display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
+ display_item_list->Finalize();
+
+ auto actual = Raster(display_item_list, options);
+ auto expected = RasterExpectedBitmap(display_item_list, options);
+ ExpectEquals(actual, expected);
+ }
};
-
+
TEST_P(OopRecordShaderPixelTest, ShaderWithTextScaled) {
RunTest();
}
-
+
class OopRecordFilterPixelTest : public OopPixelTest,
public ::testing::WithParamInterface<bool> {
- public:
- bool UseLcdText() const { return GetParam(); }
- void RunTest() {
- ScopedEnableLCDText enable_lcd;
-
- RasterOptions options;
- options.resource_size = gfx::Size(100, 100);
- options.content_size = options.resource_size;
- options.full_raster_rect = gfx::Rect(options.content_size);
- options.playback_rect = options.full_raster_rect;
- options.color_space = gfx::ColorSpace::CreateSRGB();
- options.use_lcd_text = UseLcdText();
-
- auto paint_record = sk_make_sp<PaintOpBuffer>();
- PaintFlags flags;
- flags.setStyle(PaintFlags::kFill_Style);
- flags.setColor(SK_ColorGREEN);
- paint_record->push<DrawTextBlobOp>(
- BuildTextBlob(SkTypeface::MakeDefault(), UseLcdText()), 0u, 0u, flags);
- auto paint_record_filter =
+ public:
+ bool UseLcdText() const { return GetParam(); }
+ void RunTest() {
+ ScopedEnableLCDText enable_lcd;
+
+ RasterOptions options;
+ options.resource_size = gfx::Size(100, 100);
+ options.content_size = options.resource_size;
+ options.full_raster_rect = gfx::Rect(options.content_size);
+ options.playback_rect = options.full_raster_rect;
+ options.color_space = gfx::ColorSpace::CreateSRGB();
+ options.use_lcd_text = UseLcdText();
+
+ auto paint_record = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ paint_record->push<DrawTextBlobOp>(
+ BuildTextBlob(SkTypeface::MakeDefault(), UseLcdText()), 0u, 0u, flags);
+ auto paint_record_filter =
sk_make_sp<RecordPaintFilter>(paint_record, SkRect::MakeWH(100, 100));
- auto display_item_list = base::MakeRefCounted<DisplayItemList>();
- display_item_list->StartPaint();
- display_item_list->push<ScaleOp>(2.f, 2.f);
- PaintFlags shader_flags;
- shader_flags.setImageFilter(paint_record_filter);
- display_item_list->push<DrawRectOp>(SkRect::MakeWH(50, 50), shader_flags);
- display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
- display_item_list->Finalize();
-
- auto actual = Raster(display_item_list, options);
- auto expected = RasterExpectedBitmap(display_item_list, options);
- ExpectEquals(actual, expected);
- }
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+ display_item_list->StartPaint();
+ display_item_list->push<ScaleOp>(2.f, 2.f);
+ PaintFlags shader_flags;
+ shader_flags.setImageFilter(paint_record_filter);
+ display_item_list->push<DrawRectOp>(SkRect::MakeWH(50, 50), shader_flags);
+ display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
+ display_item_list->Finalize();
+
+ auto actual = Raster(display_item_list, options);
+ auto expected = RasterExpectedBitmap(display_item_list, options);
+ ExpectEquals(actual, expected);
+ }
};
-
+
TEST_P(OopRecordFilterPixelTest, FilterWithTextScaled) {
RunTest();
}
@@ -1601,10 +1609,53 @@ TEST_F(OopPixelTest, DrawTextBlobPersistentShaderCache) {
ExpectEquals(actual, expected);
}
+class OopPathPixelTest : public OopPixelTest,
+ public ::testing::WithParamInterface<bool> {
+ public:
+ bool AllowInlining() const { return GetParam(); }
+ 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;
+ ri->set_max_inlined_entry_size_for_testing(max_inlined_entry_size);
+
+ RasterOptions options;
+ options.resource_size = gfx::Size(100, 100);
+ options.content_size = options.resource_size;
+ options.full_raster_rect = gfx::Rect(options.content_size);
+ options.playback_rect = options.full_raster_rect;
+ options.color_space = gfx::ColorSpace::CreateSRGB();
+
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+ display_item_list->StartPaint();
+ display_item_list->push<DrawColorOp>(SK_ColorWHITE, SkBlendMode::kSrc);
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ SkPath path;
+ path.addCircle(20, 20, 10);
+ display_item_list->push<DrawPathOp>(path, flags);
+ flags.setColor(SK_ColorBLUE);
+ display_item_list->push<DrawRectOp>(SkRect::MakeWH(10, 10), flags);
+ display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
+ display_item_list->Finalize();
+
+ auto expected = RasterExpectedBitmap(display_item_list, options);
+ auto actual = Raster(display_item_list, options);
+ ExpectEquals(actual, expected);
+ }
+};
+
+TEST_P(OopPathPixelTest, Basic) {
+ RunTest();
+}
+
INSTANTIATE_TEST_CASE_P(P, OopImagePixelTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(P, OopClearPixelTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(P, OopRecordShaderPixelTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(P, OopRecordFilterPixelTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(P, OopPathPixelTest, ::testing::Bool());
} // namespace
} // namespace cc
diff --git a/chromium/cc/paint/paint_cache.cc b/chromium/cc/paint/paint_cache.cc
new file mode 100644
index 00000000000..b3fad275dba
--- /dev/null
+++ b/chromium/cc/paint/paint_cache.cc
@@ -0,0 +1,126 @@
+// 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/paint/paint_cache.h"
+
+#include "base/containers/flat_set.h"
+#include "base/no_destructor.h"
+#include "base/synchronization/lock.h"
+
+namespace cc {
+namespace {
+
+template <typename T>
+void EraseFromMap(T* map, size_t n, const volatile PaintCacheId* ids) {
+ for (size_t i = 0; i < n; ++i) {
+ auto id = ids[i];
+ map->erase(id);
+ }
+}
+
+} // namespace
+
+ClientPaintCache::ClientPaintCache(size_t max_budget_bytes)
+ : cache_map_(CacheMap::NO_AUTO_EVICT), max_budget_(max_budget_bytes) {}
+ClientPaintCache::~ClientPaintCache() = default;
+
+bool ClientPaintCache::Get(PaintCacheDataType type, PaintCacheId id) {
+ return cache_map_.Get(std::make_pair(type, id)) != cache_map_.end();
+}
+
+void ClientPaintCache::Put(PaintCacheDataType type,
+ PaintCacheId id,
+ size_t size) {
+ auto key = std::make_pair(type, id);
+ DCHECK(cache_map_.Peek(key) == cache_map_.end());
+
+ pending_entries_->push_back(key);
+ cache_map_.Put(key, size);
+ bytes_used_ += size;
+}
+
+template <typename Iterator>
+void ClientPaintCache::EraseFromMap(Iterator it) {
+ DCHECK_GE(bytes_used_, it->second);
+ bytes_used_ -= it->second;
+ cache_map_.Erase(it);
+}
+
+void ClientPaintCache::FinalizePendingEntries() {
+ pending_entries_->clear();
+}
+
+void ClientPaintCache::AbortPendingEntries() {
+ for (const auto& entry : pending_entries_.container()) {
+ auto it = cache_map_.Peek(entry);
+ DCHECK(it != cache_map_.end());
+ EraseFromMap(it);
+ }
+ pending_entries_->clear();
+}
+
+void ClientPaintCache::Purge(PurgedData* purged_data) {
+ DCHECK(pending_entries_->empty());
+
+ while (bytes_used_ > max_budget_) {
+ auto it = cache_map_.rbegin();
+ PaintCacheDataType type = it->first.first;
+ PaintCacheId id = it->first.second;
+
+ EraseFromMap(it);
+ (*purged_data)[static_cast<uint32_t>(type)].push_back(id);
+ }
+}
+
+bool ClientPaintCache::PurgeAll() {
+ DCHECK(pending_entries_->empty());
+
+ bool has_data = !cache_map_.empty();
+ cache_map_.Clear();
+ bytes_used_ = 0u;
+ return has_data;
+}
+
+ServicePaintCache::ServicePaintCache() = default;
+ServicePaintCache::~ServicePaintCache() = default;
+
+void ServicePaintCache::PutTextBlob(PaintCacheId id, sk_sp<SkTextBlob> blob) {
+ cached_blobs_.emplace(id, std::move(blob));
+}
+
+sk_sp<SkTextBlob> ServicePaintCache::GetTextBlob(PaintCacheId id) {
+ auto it = cached_blobs_.find(id);
+ return it == cached_blobs_.end() ? nullptr : it->second;
+}
+
+void ServicePaintCache::PutPath(PaintCacheId id, SkPath path) {
+ cached_paths_.emplace(id, std::move(path));
+}
+
+SkPath* ServicePaintCache::GetPath(PaintCacheId id) {
+ auto it = cached_paths_.find(id);
+ return it == cached_paths_.end() ? nullptr : &it->second;
+}
+
+void ServicePaintCache::Purge(PaintCacheDataType type,
+ size_t n,
+ const volatile PaintCacheId* ids) {
+ switch (type) {
+ case PaintCacheDataType::kTextBlob:
+ EraseFromMap(&cached_blobs_, n, ids);
+ return;
+ case PaintCacheDataType::kPath:
+ EraseFromMap(&cached_paths_, n, ids);
+ return;
+ }
+
+ NOTREACHED();
+}
+
+void ServicePaintCache::PurgeAll() {
+ cached_blobs_.clear();
+ cached_paths_.clear();
+}
+
+} // namespace cc
diff --git a/chromium/cc/paint/paint_cache.h b/chromium/cc/paint/paint_cache.h
new file mode 100644
index 00000000000..10356eee5cb
--- /dev/null
+++ b/chromium/cc/paint/paint_cache.h
@@ -0,0 +1,119 @@
+// 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_CACHE_H_
+#define CC_PAINT_PAINT_CACHE_H_
+
+#include <map>
+#include <set>
+
+#include "base/containers/mru_cache.h"
+#include "base/containers/stack_container.h"
+#include "cc/paint/paint_export.h"
+#include "third_party/skia/include/core/SkPath.h"
+#include "third_party/skia/include/core/SkTextBlob.h"
+
+namespace cc {
+
+// PaintCache is used to cache high frequency small paint data types, like
+// SkTextBlob and SkPath in the GPU service. The ClientPaintCache budgets and
+// controls the cache state in the ServicePaintCache, regularly purging old
+// entries returned in ClientPaintCache::Purge from the service side cache. In
+// addition to this, the complete cache is cleared during the raster context
+// idle cleanup. This effectively means that the cache budget is used as working
+// memory that is only kept while we are actively rasterizing.
+//
+// The entries are serialized by the caller during paint op serialization, and
+// the cache assumes the deserialization and purging to be done in order for
+// accurately tracking the service side state in ServicePaintCache.
+//
+// Note that while TransferCache should be used for large data types that would
+// benefit from a shared cache budgeted across all clients, using a client
+// controlled PaintCache with a tighter budget is better for these data types
+// since it avoids the need for cross-process ref-counting required by the
+// TransferCache.
+
+using PaintCacheId = uint32_t;
+using PaintCacheIds = std::vector<PaintCacheId>;
+enum class PaintCacheDataType : uint32_t { kTextBlob, kPath, kLast = kPath };
+constexpr size_t PaintCacheDataTypeCount =
+ static_cast<uint32_t>(PaintCacheDataType::kLast) + 1u;
+
+class CC_PAINT_EXPORT ClientPaintCache {
+ public:
+ explicit ClientPaintCache(size_t max_budget_bytes);
+ ~ClientPaintCache();
+
+ bool Get(PaintCacheDataType type, PaintCacheId id);
+ void Put(PaintCacheDataType type, PaintCacheId id, size_t size);
+
+ // Populates |purged_data| with the list of ids which should be purged from
+ // the ServicePaintCache.
+ using PurgedData = PaintCacheIds[PaintCacheDataTypeCount];
+ void Purge(PurgedData* purged_data);
+
+ // Finalize the state of pending entries, which were sent to the service-side
+ // cache.
+ void FinalizePendingEntries();
+
+ // Notifies that the pending entries were not sent to the service-side cache
+ // and should be discarded.
+ void AbortPendingEntries();
+
+ // Notifies that all entries should be purged from the ServicePaintCache.
+ // Returns true if any entries were evicted from this call.
+ bool PurgeAll();
+
+ size_t bytes_used() const { return bytes_used_; }
+
+ private:
+ using CacheKey = std::pair<PaintCacheDataType, PaintCacheId>;
+ using CacheMap = base::MRUCache<CacheKey, size_t>;
+
+ template <typename Iterator>
+ void EraseFromMap(Iterator it);
+
+ CacheMap cache_map_;
+ const size_t max_budget_;
+ size_t bytes_used_ = 0u;
+
+ // List of entries added to the map but not committed since we might fail to
+ // send them to the service-side cache. This is necessary to ensure we
+ // maintain an accurate mirror of the service-side state.
+ base::StackVector<CacheKey, 1> pending_entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClientPaintCache);
+};
+
+class CC_PAINT_EXPORT ServicePaintCache {
+ public:
+ ServicePaintCache();
+ ~ServicePaintCache();
+
+ // Stores the |blob| received from the client in the cache.
+ void PutTextBlob(PaintCacheId id, sk_sp<SkTextBlob> blob);
+
+ // Retrieves an entry for |id| stored in the cache. Or nullptr if the entry
+ // is not found.
+ sk_sp<SkTextBlob> GetTextBlob(PaintCacheId id);
+
+ void PutPath(PaintCacheId, SkPath path);
+ SkPath* GetPath(PaintCacheId id);
+
+ void Purge(PaintCacheDataType type,
+ size_t n,
+ const volatile PaintCacheId* ids);
+ void PurgeAll();
+ bool empty() const { return cached_blobs_.empty() && cached_paths_.empty(); }
+
+ private:
+ using BlobMap = std::map<PaintCacheId, sk_sp<SkTextBlob>>;
+ BlobMap cached_blobs_;
+ using PathMap = std::map<PaintCacheId, SkPath>;
+ PathMap cached_paths_;
+};
+
+} // namespace cc
+
+#endif // CC_PAINT_PAINT_CACHE_H_
diff --git a/chromium/cc/paint/paint_cache_unittest.cc b/chromium/cc/paint/paint_cache_unittest.cc
new file mode 100644
index 00000000000..ea4e9b6175f
--- /dev/null
+++ b/chromium/cc/paint/paint_cache_unittest.cc
@@ -0,0 +1,131 @@
+// 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/paint/paint_cache.h"
+
+#include "base/stl_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+constexpr size_t kDefaultBudget = 1024u;
+
+sk_sp<SkTextBlob> CreateBlob() {
+ SkFont font;
+ font.setTypeface(SkTypeface::MakeDefault());
+
+ SkTextBlobBuilder builder;
+ int glyph_count = 5;
+ const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f, nullptr);
+ // allocRun() allocates only the glyph buffer.
+ std::fill(run.glyphs, run.glyphs + glyph_count, 0);
+ return builder.make();
+}
+
+SkPath CreatePath() {
+ SkPath path;
+ path.addCircle(2, 2, 5);
+ return path;
+}
+
+class PaintCacheTest : public ::testing::TestWithParam<uint32_t> {
+ public:
+ PaintCacheDataType GetType() {
+ return static_cast<PaintCacheDataType>(GetParam());
+ }
+};
+
+TEST_P(PaintCacheTest, ClientBasic) {
+ ClientPaintCache client_cache(kDefaultBudget);
+ EXPECT_FALSE(client_cache.Get(GetType(), 1u));
+ client_cache.Put(GetType(), 1u, 1u);
+ EXPECT_TRUE(client_cache.Get(GetType(), 1u));
+}
+
+TEST_P(PaintCacheTest, ClientPurgeForBudgeting) {
+ ClientPaintCache client_cache(kDefaultBudget);
+ client_cache.Put(GetType(), 1u, kDefaultBudget - 100);
+ client_cache.Put(GetType(), 2u, kDefaultBudget);
+ client_cache.Put(GetType(), 3u, kDefaultBudget);
+ EXPECT_EQ(client_cache.bytes_used(), 3 * kDefaultBudget - 100);
+ client_cache.FinalizePendingEntries();
+
+ ClientPaintCache::PurgedData purged_data;
+ client_cache.Purge(&purged_data);
+ EXPECT_EQ(client_cache.bytes_used(), kDefaultBudget);
+ const auto& ids = purged_data[static_cast<uint32_t>(GetType())];
+ ASSERT_EQ(ids.size(), 2u);
+ EXPECT_EQ(ids[0], 1u);
+ EXPECT_EQ(ids[1], 2u);
+
+ EXPECT_FALSE(client_cache.Get(GetType(), 1u));
+ EXPECT_FALSE(client_cache.Get(GetType(), 2u));
+ EXPECT_TRUE(client_cache.Get(GetType(), 3u));
+}
+
+TEST_P(PaintCacheTest, ClientPurgeAll) {
+ ClientPaintCache client_cache(kDefaultBudget);
+ client_cache.Put(GetType(), 1u, 1u);
+ EXPECT_EQ(client_cache.bytes_used(), 1u);
+ client_cache.FinalizePendingEntries();
+
+ EXPECT_TRUE(client_cache.PurgeAll());
+ EXPECT_EQ(client_cache.bytes_used(), 0u);
+ EXPECT_FALSE(client_cache.PurgeAll());
+}
+
+TEST_P(PaintCacheTest, CommitPendingEntries) {
+ ClientPaintCache client_cache(kDefaultBudget);
+
+ client_cache.Put(GetType(), 1u, 1u);
+ EXPECT_TRUE(client_cache.Get(GetType(), 1u));
+ client_cache.AbortPendingEntries();
+ EXPECT_FALSE(client_cache.Get(GetType(), 1u));
+
+ client_cache.Put(GetType(), 1u, 1u);
+ client_cache.FinalizePendingEntries();
+ EXPECT_TRUE(client_cache.Get(GetType(), 1u));
+}
+
+TEST_P(PaintCacheTest, ServiceBasic) {
+ ServicePaintCache service_cache;
+ switch (GetType()) {
+ case PaintCacheDataType::kTextBlob: {
+ auto blob = CreateBlob();
+ auto id = blob->uniqueID();
+ EXPECT_EQ(nullptr, service_cache.GetTextBlob(id));
+ service_cache.PutTextBlob(id, blob);
+ EXPECT_EQ(blob, service_cache.GetTextBlob(id));
+ service_cache.Purge(GetType(), 1, &id);
+ EXPECT_EQ(nullptr, service_cache.GetTextBlob(id));
+
+ service_cache.PutTextBlob(id, blob);
+ } break;
+ case PaintCacheDataType::kPath: {
+ auto path = CreatePath();
+ auto id = path.getGenerationID();
+ EXPECT_EQ(nullptr, service_cache.GetPath(id));
+ service_cache.PutPath(id, path);
+ EXPECT_EQ(path, *service_cache.GetPath(id));
+ service_cache.Purge(GetType(), 1, &id);
+ EXPECT_EQ(nullptr, service_cache.GetPath(id));
+
+ service_cache.PutPath(id, path);
+ } break;
+ }
+
+ EXPECT_FALSE(service_cache.empty());
+ service_cache.PurgeAll();
+ EXPECT_TRUE(service_cache.empty());
+}
+
+INSTANTIATE_TEST_CASE_P(
+ P,
+ PaintCacheTest,
+ ::testing::Range(static_cast<uint32_t>(0),
+ static_cast<uint32_t>(PaintCacheDataType::kLast)));
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/paint/paint_canvas.h b/chromium/cc/paint/paint_canvas.h
index 53bde682c34..80a6915472d 100644
--- a/chromium/cc/paint/paint_canvas.h
+++ b/chromium/cc/paint/paint_canvas.h
@@ -11,16 +11,29 @@
#include "build/build_config.h"
#include "cc/paint/paint_export.h"
#include "cc/paint/paint_image.h"
-#include "cc/paint/paint_text_blob.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkTextBlob.h"
namespace cc {
-
+class SkottieWrapper;
class PaintFlags;
class PaintOpBuffer;
using PaintRecord = PaintOpBuffer;
+// PaintCanvas is the cc/paint wrapper of SkCanvas. It has a more restricted
+// interface than SkCanvas (trimmed back to only what Chrome uses). Its reason
+// for existence is so that it can do custom serialization logic into a
+// PaintOpBuffer which (unlike SkPicture) is mutable, handles image replacement,
+// and can be serialized in custom ways (such as using the transfer cache).
+//
+// PaintCanvas is usually implemented by either:
+// (1) SkiaPaintCanvas, which is backed by an SkCanvas, usually for rasterizing.
+// (2) RecordPaintCanvas, which records paint commands into a PaintOpBuffer.
+//
+// SkiaPaintCanvas allows callers to go from PaintCanvas to SkCanvas (or
+// PaintRecord to SkPicture), but this is a one way trip. There is no way to go
+// from SkCanvas to PaintCanvas or from SkPicture back into PaintRecord.
class CC_PAINT_EXPORT PaintCanvas {
public:
PaintCanvas() {}
@@ -133,7 +146,14 @@ class CC_PAINT_EXPORT PaintCanvas {
const PaintFlags* flags,
SrcRectConstraint constraint) = 0;
- virtual void drawTextBlob(scoped_refptr<PaintTextBlob> blob,
+ // Draws the frame of the |skottie| animation specified by the normalized time
+ // t [0->first frame..1->last frame] at the destination bounds given by |dst|
+ // onto the canvas.
+ virtual void drawSkottie(scoped_refptr<SkottieWrapper> skottie,
+ const SkRect& dst,
+ float t) = 0;
+
+ virtual void drawTextBlob(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags) = 0;
diff --git a/chromium/cc/paint/paint_filter.cc b/chromium/cc/paint/paint_filter.cc
index 0e0bd00822e..2cd34c8beec 100644
--- a/chromium/cc/paint/paint_filter.cc
+++ b/chromium/cc/paint/paint_filter.cc
@@ -668,7 +668,7 @@ ImagePaintFilter::ImagePaintFilter(PaintImage image,
const SkRect& src_rect,
const SkRect& dst_rect,
SkFilterQuality filter_quality)
- : PaintFilter(kType, nullptr, image.IsLazyGenerated()),
+ : PaintFilter(kType, nullptr, !image.IsTextureBacked()),
image_(std::move(image)),
src_rect_(src_rect),
dst_rect_(dst_rect),
diff --git a/chromium/cc/paint/paint_filter_unittest.cc b/chromium/cc/paint/paint_filter_unittest.cc
index de1ea45132c..a83438648b4 100644
--- a/chromium/cc/paint/paint_filter_unittest.cc
+++ b/chromium/cc/paint/paint_filter_unittest.cc
@@ -33,7 +33,7 @@ sk_sp<PaintFilter> CreateTestFilter(PaintFilter::Type filter_type,
if (has_discardable_images)
image = CreateDiscardablePaintImage(gfx::Size(100, 100));
else
- image = CreateBitmapImage(gfx::Size(100, 100));
+ image = CreateNonDiscardablePaintImage(gfx::Size(100, 100));
auto image_filter = sk_make_sp<ImagePaintFilter>(
image, SkRect::MakeWH(100.f, 100.f), SkRect::MakeWH(100.f, 100.f),
diff --git a/chromium/cc/paint/paint_flags.cc b/chromium/cc/paint/paint_flags.cc
index 41b561ff738..c0ff3a6aa47 100644
--- a/chromium/cc/paint/paint_flags.cc
+++ b/chromium/cc/paint/paint_flags.cc
@@ -25,7 +25,7 @@ PaintFlags::PaintFlags() {
bitfields_.join_type_ = SkPaint::kDefault_Join;
bitfields_.style_ = SkPaint::kFill_Style;
bitfields_.text_encoding_ = SkPaint::kUTF8_TextEncoding;
- bitfields_.hinting_ = SkPaint::kNormal_Hinting;
+ bitfields_.hinting_ = static_cast<unsigned>(SkFontHinting::kNormal);
bitfields_.filter_quality_ = SkFilterQuality::kNone_SkFilterQuality;
static_assert(sizeof(bitfields_) <= sizeof(bitfields_uint_),
@@ -146,11 +146,30 @@ SkPaint PaintFlags::ToSkPaint() const {
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<SkPaint::Hinting>(getHinting()));
+ 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());
}
diff --git a/chromium/cc/paint/paint_flags.h b/chromium/cc/paint/paint_flags.h
index a132fd702bd..fda9cc5ba8d 100644
--- a/chromium/cc/paint/paint_flags.h
+++ b/chromium/cc/paint/paint_flags.h
@@ -11,6 +11,8 @@
#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"
@@ -18,8 +20,6 @@
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkTypeface.h"
-class SkPaint;
-
namespace cc {
class PaintFilter;
@@ -62,12 +62,6 @@ class CC_PAINT_EXPORT PaintFlags {
ALWAYS_INLINE void setAntiAlias(bool aa) {
SetInternalFlag(aa, SkPaint::kAntiAlias_Flag);
}
- ALWAYS_INLINE bool isVerticalText() const {
- return !!(bitfields_.flags_ & SkPaint::kVerticalText_Flag);
- }
- ALWAYS_INLINE void setVerticalText(bool vertical) {
- SetInternalFlag(vertical, SkPaint::kVerticalText_Flag);
- }
ALWAYS_INLINE bool isSubpixelText() const {
return !!(bitfields_.flags_ & SkPaint::kSubpixelText_Flag);
}
@@ -81,10 +75,11 @@ class CC_PAINT_EXPORT PaintFlags {
SetInternalFlag(lcd_text, SkPaint::kLCDRenderText_Flag);
}
enum Hinting {
- kNo_Hinting = SkPaint::kNo_Hinting,
- kSlight_Hinting = SkPaint::kSlight_Hinting,
- kNormal_Hinting = SkPaint::kNormal_Hinting, //!< this is the default
- kFull_Hinting = SkPaint::kFull_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_);
@@ -214,6 +209,7 @@ class CC_PAINT_EXPORT PaintFlags {
bool SupportsFoldingAlpha() const;
SkPaint ToSkPaint() const;
+ SkFont ToSkFont() const;
bool IsValid() const;
bool operator==(const PaintFlags& other) const;
diff --git a/chromium/cc/paint/paint_font.cc b/chromium/cc/paint/paint_font.cc
deleted file mode 100644
index 96818286705..00000000000
--- a/chromium/cc/paint/paint_font.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 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/paint/paint_font.h"
-
-#include "cc/paint/paint_export.h"
-#include "third_party/skia/include/core/SkPaint.h"
-
-namespace cc {
-
-PaintFont::PaintFont() = default;
-PaintFont::~PaintFont() = default;
-
-void PaintFont::SetTextEncoding(SkPaint::TextEncoding encoding) {
- sk_paint_.setTextEncoding(encoding);
-}
-
-void PaintFont::SetAntiAlias(bool use_anti_alias) {
- sk_paint_.setAntiAlias(use_anti_alias);
-}
-
-void PaintFont::SetHinting(SkPaint::Hinting hinting) {
- sk_paint_.setHinting(hinting);
-}
-
-void PaintFont::SetEmbeddedBitmapText(bool use_bitmaps) {
- sk_paint_.setEmbeddedBitmapText(use_bitmaps);
-}
-
-void PaintFont::SetAutohinted(bool use_auto_hint) {
- sk_paint_.setAutohinted(use_auto_hint);
-}
-
-void PaintFont::SetLcdRenderText(bool lcd_text) {
- sk_paint_.setLCDRenderText(lcd_text);
-}
-
-void PaintFont::SetSubpixelText(bool subpixel_text) {
- sk_paint_.setSubpixelText(subpixel_text);
-}
-
-void PaintFont::SetTextSize(SkScalar size) {
- sk_paint_.setTextSize(size);
-}
-
-void PaintFont::SetTypeface(sk_sp<SkTypeface> typeface) {
- typeface_ = typeface;
- sk_paint_.setTypeface(typeface);
-}
-
-void PaintFont::SetFakeBoldText(bool bold_text) {
- sk_paint_.setFakeBoldText(bold_text);
-}
-
-void PaintFont::SetTextSkewX(SkScalar skew) {
- sk_paint_.setTextSkewX(skew);
-}
-
-void PaintFont::SetFlags(uint32_t flags) {
- sk_paint_.setFlags(flags);
-}
-
-} // namespace cc
diff --git a/chromium/cc/paint/paint_font.h b/chromium/cc/paint/paint_font.h
deleted file mode 100644
index 3b34ac404fb..00000000000
--- a/chromium/cc/paint/paint_font.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 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_FONT_H_
-#define CC_PAINT_PAINT_FONT_H_
-
-#include "cc/paint/paint_export.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
-namespace cc {
-
-class CC_PAINT_EXPORT PaintFont {
- public:
- PaintFont();
- ~PaintFont();
-
- void SetTextEncoding(SkPaint::TextEncoding encoding);
- void SetAntiAlias(bool use_anti_alias);
- void SetHinting(SkPaint::Hinting hinting);
- void SetEmbeddedBitmapText(bool use_bitmaps);
- void SetAutohinted(bool use_auto_hint);
- void SetLcdRenderText(bool lcd_text);
- void SetSubpixelText(bool subpixel_text);
- void SetTextSize(SkScalar size);
- void SetTypeface(sk_sp<SkTypeface> typeface);
- void SetFakeBoldText(bool bold_text);
- void SetTextSkewX(SkScalar skew);
- void SetFlags(uint32_t flags);
-
- uint32_t flags() const { return sk_paint_.getFlags(); }
-
- const sk_sp<SkTypeface> typeface() const { return typeface_; }
- const SkPaint& ToSkPaint() const { return sk_paint_; }
-
- private:
- sk_sp<SkTypeface> typeface_;
- SkPaint sk_paint_;
-};
-
-} // namespace cc
-
-#endif // CC_PAINT_PAINT_FONT_H_
diff --git a/chromium/cc/paint/paint_image.h b/chromium/cc/paint/paint_image.h
index efde11152ae..0684c2d80c6 100644
--- a/chromium/cc/paint/paint_image.h
+++ b/chromium/cc/paint/paint_image.h
@@ -21,9 +21,23 @@ class PaintImageGenerator;
class PaintOpBuffer;
using PaintRecord = PaintOpBuffer;
-// A representation of an image for the compositor.
-// Note that aside from default construction, it can only be constructed using a
-// PaintImageBuilder, or copied/moved into using operator=.
+// A representation of an image for the compositor. This is the most abstract
+// form of images, and represents what is known at paint time. Note that aside
+// from default construction, it can only be constructed using a
+// PaintImageBuilder, or copied/moved into using operator=. PaintImage can
+// be backed by different kinds of content, such as a lazy generator, a paint
+// record, a bitmap, or a texture.
+//
+// If backed by a generator, this image may not be decoded and information like
+// the animation frame, the target colorspace, or the scale at which it will be
+// used are not known yet. A DrawImage is a PaintImage with those decisions
+// known but that might not have been decoded yet. A DecodedDrawImage is a
+// DrawImage that has been decoded/scaled/uploaded with all of those parameters
+// applied.
+//
+// The PaintImage -> DrawImage -> DecodedDrawImage -> PaintImage (via SkImage)
+// path can be used to create a PaintImage that is snapshotted at a particular
+// scale or animation frame.
class CC_PAINT_EXPORT PaintImage {
public:
using Id = int;
@@ -162,6 +176,7 @@ class CC_PAINT_EXPORT PaintImage {
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(); }
diff --git a/chromium/cc/paint/paint_image_generator.h b/chromium/cc/paint/paint_image_generator.h
index 95189c7da90..d0ce1c75c02 100644
--- a/chromium/cc/paint/paint_image_generator.h
+++ b/chromium/cc/paint/paint_image_generator.h
@@ -14,7 +14,8 @@
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSize.h"
-#include "third_party/skia/include/core/SkYUVSizeInfo.h"
+#include "third_party/skia/include/core/SkYUVAIndex.h"
+#include "third_party/skia/include/core/SkYUVASizeInfo.h"
namespace cc {
@@ -44,21 +45,25 @@ class CC_PAINT_EXPORT PaintImageGenerator : public SkRefCnt {
// Returns true if the generator supports YUV decoding, providing the output
// information in |info| and |color_space|.
- virtual bool QueryYUV8(SkYUVSizeInfo* info,
- SkYUVColorSpace* color_space) const = 0;
+ virtual bool QueryYUVA8(SkYUVASizeInfo* info,
+ SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ SkYUVColorSpace* color_space) const = 0;
// Decodes to YUV into the provided |planes| for each of the Y, U, and V
// planes, and returns true on success. The method should only be used if
- // QueryYUV8 returns true.
- // |info| needs to exactly match the values returned by the query, except the
- // WidthBytes may be larger than the recommendation (but not smaller).
+ // QueryYUVA8 returns true.
+ // |info| and |indices| need to exactly match the values returned by the
+ // query, except the info.fWidthBytes may be larger than the recommendation
+ // (but not smaller).
//
// TODO(khushalsagar): |lazy_pixel_ref| is only present for
// DecodingImageGenerator tracing needs. Remove it.
- virtual bool GetYUV8Planes(const SkYUVSizeInfo& info,
- void* planes[3],
- size_t frame_index,
- uint32_t lazy_pixel_ref) = 0;
+ virtual bool GetYUVA8Planes(
+ const SkYUVASizeInfo& info,
+ const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ void* planes[3],
+ size_t frame_index,
+ uint32_t lazy_pixel_ref) = 0;
// Returns the smallest size that is at least as big as the requested size,
// such that we can decode to exactly that scale.
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 13867d477a2..7ae8135f509 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -65,6 +65,7 @@ SkRect AdjustSrcRectForScale(SkRect original, SkSize scale_adjustment) {
M(DrawRecordOp) \
M(DrawRectOp) \
M(DrawRRectOp) \
+ M(DrawSkottieOp) \
M(DrawTextBlobOp) \
M(NoopOp) \
M(RestoreOp) \
@@ -263,6 +264,8 @@ std::string PaintOpTypeToString(PaintOpType type) {
return "DrawRect";
case PaintOpType::DrawRRect:
return "DrawRRect";
+ case PaintOpType::DrawSkottie:
+ return "DrawSkottie";
case PaintOpType::DrawTextBlob:
return "DrawTextBlob";
case PaintOpType::Noop:
@@ -323,6 +326,7 @@ PlaybackParams& PlaybackParams::operator=(const PlaybackParams& other) =
PaintOp::SerializeOptions::SerializeOptions(
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkCanvas* canvas,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
@@ -333,6 +337,7 @@ PaintOp::SerializeOptions::SerializeOptions(
const SkMatrix& original_ctm)
: image_provider(image_provider),
transfer_cache(transfer_cache),
+ paint_cache(paint_cache),
canvas(canvas),
strike_server(strike_server),
color_space(color_space),
@@ -349,8 +354,11 @@ PaintOp::SerializeOptions& PaintOp::SerializeOptions::operator=(
PaintOp::DeserializeOptions::DeserializeOptions(
TransferCacheDeserializeHelper* transfer_cache,
+ ServicePaintCache* paint_cache,
SkStrikeClient* strike_client)
- : transfer_cache(transfer_cache), strike_client(strike_client) {}
+ : transfer_cache(transfer_cache),
+ paint_cache(paint_cache),
+ strike_client(strike_client) {}
size_t AnnotateOp::Serialize(const PaintOp* base_op,
void* memory,
@@ -578,6 +586,16 @@ size_t DrawRRectOp::Serialize(const PaintOp* base_op,
return helper.size();
}
+size_t DrawSkottieOp::Serialize(const PaintOp* op,
+ void* memory,
+ size_t size,
+ const SerializeOptions& options) {
+ // TODO(malaykeshav): these must be flattened. Serializing this will not do
+ // anything. See https://crbug.com/894635
+ NOTREACHED();
+ return 0u;
+}
+
size_t DrawTextBlobOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
@@ -987,6 +1005,16 @@ PaintOp* DrawRRectOp::Deserialize(const volatile void* input,
return op;
}
+PaintOp* DrawSkottieOp::Deserialize(const volatile void* input,
+ size_t input_size,
+ void* output,
+ size_t output_size,
+ const DeserializeOptions& options) {
+ // TODO(malaykeshav): these must be flattened and not sent directly.
+ // See https://crbug.com/894635
+ return nullptr;
+}
+
PaintOp* DrawTextBlobOp::Deserialize(const volatile void* input,
size_t input_size,
void* output,
@@ -1318,12 +1346,18 @@ void DrawRRectOp::RasterWithFlags(const DrawRRectOp* op,
canvas->drawRRect(op->rrect, paint);
}
+void DrawSkottieOp::Raster(const DrawSkottieOp* op,
+ SkCanvas* canvas,
+ const PlaybackParams& params) {
+ op->skottie->Draw(canvas, op->t, op->dst);
+}
+
void DrawTextBlobOp::RasterWithFlags(const DrawTextBlobOp* op,
const PaintFlags* flags,
SkCanvas* canvas,
const PlaybackParams& params) {
SkPaint paint = flags->ToSkPaint();
- canvas->drawTextBlob(op->blob->ToSkTextBlob().get(), op->x, op->y, paint);
+ canvas->drawTextBlob(op->blob.get(), op->x, op->y, paint);
}
void RestoreOp::Raster(const RestoreOp* op,
@@ -1702,6 +1736,21 @@ bool DrawRRectOp::AreEqual(const PaintOp* base_left,
return true;
}
+bool DrawSkottieOp::AreEqual(const PaintOp* base_left,
+ const PaintOp* base_right) {
+ auto* left = static_cast<const DrawSkottieOp*>(base_left);
+ auto* right = static_cast<const DrawSkottieOp*>(base_right);
+ DCHECK(left->IsValid());
+ DCHECK(right->IsValid());
+ // TODO(malaykeshav): Verify the skottie objects of each PaintOb are equal
+ // based on the serialized bytes.
+ if (left->t != right->t)
+ return false;
+ if (!AreSkRectsEqual(left->dst, right->dst))
+ return false;
+ return true;
+}
+
bool DrawTextBlobOp::AreEqual(const PaintOp* base_left,
const PaintOp* base_right) {
auto* left = static_cast<const DrawTextBlobOp*>(base_left);
@@ -1715,13 +1764,9 @@ bool DrawTextBlobOp::AreEqual(const PaintOp* base_left,
if (!AreEqualEvenIfNaN(left->y, right->y))
return false;
- DCHECK(*left->blob);
- DCHECK(*right->blob);
-
SkSerialProcs default_procs;
- return left->blob->ToSkTextBlob()
- ->serialize(default_procs)
- ->equals(right->blob->ToSkTextBlob()->serialize(default_procs).get());
+ return left->blob->serialize(default_procs)
+ ->equals(right->blob->serialize(default_procs).get());
}
bool NoopOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) {
@@ -1947,10 +1992,15 @@ bool PaintOp::GetBounds(const PaintOp* op, SkRect* rect) {
}
case PaintOpType::DrawRecord:
return false;
+ case PaintOpType::DrawSkottie: {
+ auto* skottie_op = static_cast<const DrawSkottieOp*>(op);
+ *rect = skottie_op->dst;
+ rect->sort();
+ return true;
+ }
case PaintOpType::DrawTextBlob: {
auto* text_op = static_cast<const DrawTextBlobOp*>(op);
- *rect = text_op->blob->ToSkTextBlob()->bounds().makeOffset(text_op->x,
- text_op->y);
+ *rect = text_op->blob->bounds().makeOffset(text_op->x, text_op->y);
rect->sort();
return true;
}
@@ -2087,9 +2137,7 @@ DrawImageOp::DrawImageOp(const PaintImage& image,
top(top) {}
bool DrawImageOp::HasDiscardableImages() const {
- // TODO(khushalsagar): Callers should not be able to change the lazy generated
- // state for a PaintImage.
- return image && image.IsLazyGenerated();
+ return image && !image.IsTextureBacked();
}
DrawImageOp::~DrawImageOp() = default;
@@ -2108,7 +2156,7 @@ DrawImageRectOp::DrawImageRectOp(const PaintImage& image,
constraint(constraint) {}
bool DrawImageRectOp::HasDiscardableImages() const {
- return image && image.IsLazyGenerated();
+ return image && !image.IsTextureBacked();
}
DrawImageRectOp::~DrawImageRectOp() = default;
@@ -2126,17 +2174,26 @@ size_t DrawRecordOp::AdditionalOpCount() const {
return record->total_op_count();
}
+DrawSkottieOp::DrawSkottieOp(scoped_refptr<SkottieWrapper> skottie,
+ SkRect dst,
+ float t)
+ : PaintOp(kType), skottie(std::move(skottie)), dst(dst), t(t) {}
+
+DrawSkottieOp::DrawSkottieOp() : PaintOp(kType) {}
+
+DrawSkottieOp::~DrawSkottieOp() = default;
+
bool DrawRecordOp::HasDiscardableImages() const {
return record->HasDiscardableImages();
}
DrawTextBlobOp::DrawTextBlobOp() : PaintOpWithFlags(kType) {}
-DrawTextBlobOp::DrawTextBlobOp(scoped_refptr<PaintTextBlob> paint_blob,
+DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags)
- : PaintOpWithFlags(kType, flags), blob(std::move(paint_blob)), x(x), y(y) {}
+ : PaintOpWithFlags(kType, flags), blob(std::move(blob)), x(x), y(y) {}
DrawTextBlobOp::~DrawTextBlobOp() = default;
diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h
index b65491d6ac1..a4a3ae89f72 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -22,6 +22,7 @@
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_export.h"
#include "cc/paint/paint_flags.h"
+#include "cc/paint/skottie_wrapper.h"
#include "cc/paint/transfer_cache_deserialize_helper.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -38,6 +39,8 @@ class SkStrikeServer;
// PaintOpBuffer is a reimplementation of SkLiteDL.
// See: third_party/skia/src/core/SkLiteDL.h.
namespace cc {
+class ClientPaintCache;
+class ServicePaintCache;
class CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix {
public:
@@ -82,6 +85,7 @@ enum class PaintOpType : uint8_t {
DrawRecord,
DrawRect,
DrawRRect,
+ DrawSkottie,
DrawTextBlob,
Noop,
Restore,
@@ -143,6 +147,7 @@ class CC_PAINT_EXPORT PaintOp {
struct CC_PAINT_EXPORT SerializeOptions {
SerializeOptions(ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkCanvas* canvas,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
@@ -157,6 +162,7 @@ class CC_PAINT_EXPORT PaintOp {
// Required.
ImageProvider* image_provider = nullptr;
TransferCacheSerializeHelper* transfer_cache = nullptr;
+ ClientPaintCache* paint_cache = nullptr;
SkCanvas* canvas = nullptr;
SkStrikeServer* strike_server = nullptr;
SkColorSpace* color_space = nullptr;
@@ -174,10 +180,14 @@ class CC_PAINT_EXPORT PaintOp {
struct CC_PAINT_EXPORT DeserializeOptions {
DeserializeOptions(TransferCacheDeserializeHelper* transfer_cache,
+ ServicePaintCache* paint_cache,
SkStrikeClient* strike_client);
TransferCacheDeserializeHelper* transfer_cache = nullptr;
- uint32_t raster_color_space_id = gfx::ColorSpace::kInvalidId;
+ 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;
};
// Indicates how PaintImages are serialized.
@@ -695,11 +705,34 @@ class CC_PAINT_EXPORT DrawRRectOp final : public PaintOpWithFlags {
DrawRRectOp() : PaintOpWithFlags(kType) {}
};
+class CC_PAINT_EXPORT DrawSkottieOp final : public PaintOp {
+ public:
+ static constexpr PaintOpType kType = PaintOpType::DrawSkottie;
+ static constexpr bool kIsDrawOp = true;
+ DrawSkottieOp(scoped_refptr<SkottieWrapper> skottie, SkRect dst, float t);
+ ~DrawSkottieOp();
+ static void Raster(const DrawSkottieOp* op,
+ SkCanvas* canvas,
+ const PlaybackParams& params);
+ bool IsValid() const {
+ return !!skottie && !dst.isEmpty() && t >= 0 && t <= 1.f;
+ }
+ static bool AreEqual(const PaintOp* left, const PaintOp* right);
+ HAS_SERIALIZATION_FUNCTIONS();
+
+ scoped_refptr<SkottieWrapper> skottie;
+ SkRect dst;
+ float t;
+
+ private:
+ DrawSkottieOp();
+};
+
class CC_PAINT_EXPORT DrawTextBlobOp final : public PaintOpWithFlags {
public:
static constexpr PaintOpType kType = PaintOpType::DrawTextBlob;
static constexpr bool kIsDrawOp = true;
- DrawTextBlobOp(scoped_refptr<PaintTextBlob> blob,
+ DrawTextBlobOp(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags);
@@ -712,7 +745,7 @@ class CC_PAINT_EXPORT DrawTextBlobOp final : public PaintOpWithFlags {
static bool AreEqual(const PaintOp* left, const PaintOp* right);
HAS_SERIALIZATION_FUNCTIONS();
- scoped_refptr<PaintTextBlob> blob;
+ sk_sp<SkTextBlob> blob;
SkScalar x;
SkScalar y;
diff --git a/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc
deleted file mode 100644
index 081744b7e7e..00000000000
--- a/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/test/paint_op_helper.h"
-#include "cc/test/test_options_provider.h"
-#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
-
-// paint_op_buffer_eq_fuzzer deserializes and reserializes paint ops to
-// make sure that this does not modify or incorrectly serialize them.
-// This is intended to be a fuzzing correctness test.
-//
-// Compare this to paint_op_buffer_fuzzer which makes sure that deserializing
-// ops and rasterizing those ops is safe.
-//
-// This test performs the following operation:
-//
-// serialized1 -> deserialized1 -> serialized2 -> deserialized2 -> serialized3
-//
-// Ideally this test would compare serialized1 to serialized2, however:
-// (1) Deserializing is a destructive process on bad input, e.g. SkMatrix
-// that says it is identity will be clobbered to have identity values.
-// (2) Padding for alignment is skipped and so serialized1 may have garbage.
-// serialized2 and serialized3 are cleared to zero first.
-// (3) Any internal allocated memory (e.g. DrawRecord ops) also will not
-// be initialized to zero, and some ops memcpy when serializing or
-// deserializing, and may copy some of this garbage.
-//
-// It'd be nice to be able to binary compare, but because of all the above
-// reasons, this is impossible to do for all ops, so this test only does
-// a logical comparison of deserialized1 and deserialized2, and verifies
-// that serialized2 and serialized3 wrote the exact same number of bytes.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- const size_t kMaxSerializedSize = 1000000;
-
- SkNoDrawCanvas canvas(100, 100);
- cc::TestOptionsProvider test_options_provider;
-
- // Need 4 bytes to be able to read the type/skip.
- if (size < 4)
- return 0;
-
- size_t serialized_size = reinterpret_cast<const cc::PaintOp*>(data)->skip;
- if (serialized_size > kMaxSerializedSize)
- return 0;
-
- // If the op has a skip that runs off the end of the input, then ignore.
- if (serialized_size > size)
- return 0;
-
- std::unique_ptr<char, base::AlignedFreeDeleter> deserialized1(
- static_cast<char*>(base::AlignedAlloc(sizeof(cc::LargestPaintOp),
- cc::PaintOpBuffer::PaintOpAlign)));
- size_t bytes_read1 = 0;
- cc::PaintOp* deserialized_op1 = cc::PaintOp::Deserialize(
- data, size, deserialized1.get(), sizeof(cc::LargestPaintOp), &bytes_read1,
- test_options_provider.deserialize_options());
-
- // Failed to deserialize, so abort.
- if (!deserialized_op1)
- return 0;
-
- // DrawTextBlob ops contain two pieces of information: a text blob, and a
- // vector of typefaces that are used in the blob. However, during
- // deserialization we never need to reconstruct the vector of typefaces, since
- // it is only used to reconstruct the blob directly. This, however, poses a
- // problem for this fuzzer since we will then try to serialize the op again,
- // resulting in an assert. The assert says that we don't have typefaces
- // (serialized from the vector) that are required to serialize the text blob.
- // The solution is to skip the equality fuzzer for DrawTextBlob ops.
- //
- // Normally the initial deserialization would also fail and we would early out
- // above, since the transfer cache doesn't have any entries to reconstruct the
- // text blob. However, Skia, given some data, seems to be able to construct an
- // SkTextBlob without accessing the given cataloger. See crbug.com/798939 for
- // an example of such a test case.
- if (deserialized_op1->GetType() == cc::PaintOpType::DrawTextBlob) {
- deserialized_op1->DestroyThis();
- return 0;
- }
-
- // If we get to this point, then the op should be ok to serialize/deserialize
- // and any failure is a dcheck.
- std::unique_ptr<char, base::AlignedFreeDeleter> serialized2(
- static_cast<char*>(base::AlignedAlloc(serialized_size,
- cc::PaintOpBuffer::PaintOpAlign)));
- memset(serialized2.get(), 0, serialized_size);
- size_t written_bytes2 =
- deserialized_op1->Serialize(serialized2.get(), serialized_size,
- test_options_provider.serialize_options());
- CHECK_LE(written_bytes2, serialized_size);
-
- std::unique_ptr<char, base::AlignedFreeDeleter> deserialized2(
- static_cast<char*>(base::AlignedAlloc(sizeof(cc::LargestPaintOp),
- cc::PaintOpBuffer::PaintOpAlign)));
- size_t bytes_read2 = 0;
- cc::PaintOp* deserialized_op2 = cc::PaintOp::Deserialize(
- data, size, deserialized2.get(), sizeof(cc::LargestPaintOp), &bytes_read2,
- test_options_provider.deserialize_options());
- CHECK(deserialized_op2);
- CHECK_EQ(bytes_read1, bytes_read2);
-
- std::unique_ptr<char, base::AlignedFreeDeleter> serialized3(
- static_cast<char*>(
- base::AlignedAlloc(written_bytes2, cc::PaintOpBuffer::PaintOpAlign)));
- memset(serialized3.get(), 0, written_bytes2);
- size_t written_bytes3 =
- deserialized_op2->Serialize(serialized3.get(), written_bytes2,
- test_options_provider.serialize_options());
- CHECK_EQ(written_bytes2, written_bytes3);
-
- CHECK(*deserialized_op1 == *deserialized_op2)
- << "\n1: " << cc::PaintOpHelper::ToString(deserialized_op1)
- << "\n2: " << cc::PaintOpHelper::ToString(deserialized_op2);
-
- deserialized_op1->DestroyThis();
- deserialized_op2->DestroyThis();
-
- return 0;
-}
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index 9c82f148556..c91d62fbfa8 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
#include "base/command_line.h"
+#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "components/viz/test/test_context_provider.h"
@@ -52,6 +53,7 @@ class FontSupport : public gpu::ServiceFontManager::Client {
void Raster(scoped_refptr<viz::TestContextProvider> context_provider,
SkStrikeClient* strike_client,
+ cc::ServicePaintCache* paint_cache,
const uint8_t* data,
size_t size) {
const size_t kRasterDimension = 32;
@@ -66,8 +68,8 @@ void Raster(scoped_refptr<viz::TestContextProvider> context_provider,
cc::PlaybackParams params(nullptr, canvas->getTotalMatrix());
cc::TransferCacheTestHelper transfer_cache_helper;
- cc::PaintOp::DeserializeOptions deserialize_options(&transfer_cache_helper,
- strike_client);
+ cc::PaintOp::DeserializeOptions deserialize_options(
+ &transfer_cache_helper, paint_cache, strike_client);
// Need 4 bytes to be able to read the type/skip.
while (size >= 4) {
@@ -116,6 +118,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FontSupport font_support;
scoped_refptr<gpu::ServiceFontManager> font_manager(
new gpu::ServiceFontManager(&font_support));
+ cc::ServicePaintCache paint_cache;
std::vector<SkDiscardableHandleId> locked_handles;
if (bytes_for_fonts > 0u) {
font_manager->Deserialize(reinterpret_cast<const char*>(data),
@@ -127,16 +130,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
auto context_provider_no_support = viz::TestContextProvider::Create();
context_provider_no_support->BindToCurrentThread();
CHECK(!context_provider_no_support->GrContext()->supportsDistanceFieldText());
- Raster(context_provider_no_support, font_manager->strike_client(), data,
- size);
+ Raster(context_provider_no_support, font_manager->strike_client(),
+ &paint_cache, data, size);
auto context_provider_with_support = viz::TestContextProvider::Create(
std::string("GL_OES_standard_derivatives"));
context_provider_with_support->BindToCurrentThread();
CHECK(
context_provider_with_support->GrContext()->supportsDistanceFieldText());
- Raster(context_provider_with_support, font_manager->strike_client(), data,
- size);
+ Raster(context_provider_with_support, font_manager->strike_client(),
+ &paint_cache, data, size);
font_manager->Unlock(locked_handles);
font_manager->Destroy();
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.cc b/chromium/cc/paint/paint_op_buffer_serializer.cc
index 0c56de338da..5802b3c369d 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.cc
+++ b/chromium/cc/paint/paint_op_buffer_serializer.cc
@@ -66,6 +66,7 @@ PaintOpBufferSerializer::PaintOpBufferSerializer(
SerializeCallback serialize_cb,
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
bool can_use_lcd_text,
@@ -75,6 +76,7 @@ PaintOpBufferSerializer::PaintOpBufferSerializer(
: serialize_cb_(std::move(serialize_cb)),
image_provider_(image_provider),
transfer_cache_(transfer_cache),
+ paint_cache_(paint_cache),
strike_server_(strike_server),
color_space_(color_space),
can_use_lcd_text_(can_use_lcd_text),
@@ -385,8 +387,8 @@ void PaintOpBufferSerializer::RestoreToCount(
PaintOp::SerializeOptions PaintOpBufferSerializer::MakeSerializeOptions() {
return PaintOp::SerializeOptions(
- image_provider_, transfer_cache_, canvas_, strike_server_, color_space_,
- can_use_lcd_text_, context_supports_distance_field_text_,
+ image_provider_, transfer_cache_, paint_cache_, canvas_, strike_server_,
+ color_space_, can_use_lcd_text_, context_supports_distance_field_text_,
max_texture_size_, max_texture_bytes_, canvas_->getTotalMatrix());
}
@@ -395,6 +397,7 @@ SimpleBufferSerializer::SimpleBufferSerializer(
size_t size,
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
bool can_use_lcd_text,
@@ -406,6 +409,7 @@ SimpleBufferSerializer::SimpleBufferSerializer(
base::Unretained(this)),
image_provider,
transfer_cache,
+ paint_cache,
strike_server,
color_space,
can_use_lcd_text,
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.h b/chromium/cc/paint/paint_op_buffer_serializer.h
index b12ba632d39..4dfd6c13c97 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.h
+++ b/chromium/cc/paint/paint_op_buffer_serializer.h
@@ -11,8 +11,9 @@
#include "ui/gfx/geometry/rect_f.h"
namespace cc {
-
+class ClientPaintCache;
class TransferCacheSerializeHelper;
+
class CC_PAINT_EXPORT PaintOpBufferSerializer {
public:
using SerializeCallback =
@@ -21,6 +22,7 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
PaintOpBufferSerializer(SerializeCallback serialize_cb,
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
bool can_use_lcd_text,
@@ -102,6 +104,7 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
SerializeCallback serialize_cb_;
ImageProvider* image_provider_;
TransferCacheSerializeHelper* transfer_cache_;
+ ClientPaintCache* paint_cache_;
SkStrikeServer* strike_server_;
SkColorSpace* color_space_;
bool can_use_lcd_text_;
@@ -122,6 +125,7 @@ class CC_PAINT_EXPORT SimpleBufferSerializer : public PaintOpBufferSerializer {
size_t size,
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
+ ClientPaintCache* paint_cache,
SkStrikeServer* strike_server,
SkColorSpace* color_space,
bool can_use_lcd_text,
diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc
index 557a1187a17..8e007c409db 100644
--- a/chromium/cc/paint/paint_op_buffer_unittest.cc
+++ b/chromium/cc/paint/paint_op_buffer_unittest.cc
@@ -1160,10 +1160,9 @@ std::vector<std::vector<sk_sp<SkTypeface>>> test_typefaces = {
}(),
};
-std::vector<scoped_refptr<PaintTextBlob>> test_paint_blobs = {
+std::vector<sk_sp<SkTextBlob>> test_paint_blobs = {
[] {
- SkPaint font;
- font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkFont font;
font.setTypeface(test_typefaces[0][0]);
SkTextBlobBuilder builder;
@@ -1172,12 +1171,10 @@ std::vector<scoped_refptr<PaintTextBlob>> test_paint_blobs = {
builder.allocRun(font, glyph_count, 1.2f, 2.3f, &test_rects[0]);
// allocRun() allocates only the glyph buffer.
std::fill(run.glyphs, run.glyphs + glyph_count, 0);
- return base::MakeRefCounted<PaintTextBlob>(builder.make(),
- test_typefaces[0]);
+ return builder.make();
}(),
[] {
- SkPaint font;
- font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkFont font;
font.setTypeface(test_typefaces[1][0]);
SkTextBlobBuilder builder;
@@ -1202,8 +1199,7 @@ std::vector<scoped_refptr<PaintTextBlob>> test_paint_blobs = {
// pos buffer.
std::fill(run3.glyphs, run3.glyphs + glyph_count, 0);
std::fill(run3.pos, run3.pos + glyph_count, 0);
- return base::MakeRefCounted<PaintTextBlob>(builder.make(),
- test_typefaces[1]);
+ return builder.make();
}(),
};
@@ -1216,6 +1212,16 @@ std::vector<PaintImage> test_images = {
CreateDiscardablePaintImage(gfx::Size(50, 50)),
};
+std::vector<scoped_refptr<SkottieWrapper>> test_skotties = {
+ CreateSkottie(gfx::Size(10, 20), 4), CreateSkottie(gfx::Size(100, 40), 5),
+ CreateSkottie(gfx::Size(80, 70), 6)};
+
+std::vector<float> test_skottie_floats = {0, 0.1f, 1.f};
+
+std::vector<SkRect> test_skottie_rects = {SkRect::MakeXYWH(10, 20, 30, 40),
+ SkRect::MakeXYWH(0, 5, 10, 20),
+ SkRect::MakeXYWH(6, 0, 3, 50)};
+
// Writes as many ops in |buffer| as can fit in |output_size| to |output|.
// Records the numbers of bytes written for each op.
class SimpleSerializer {
@@ -1498,6 +1504,15 @@ void PushDrawRRectOps(PaintOpBuffer* buffer) {
ValidateOps<DrawRRectOp>(buffer);
}
+void PushDrawSkottieOps(PaintOpBuffer* buffer) {
+ size_t len = std::min(test_skotties.size(), test_flags.size());
+ for (size_t i = 0; i < len; i++) {
+ buffer->push<DrawSkottieOp>(test_skotties[i], test_skottie_rects[i],
+ test_skottie_floats[i]);
+ }
+ ValidateOps<DrawSkottieOp>(buffer);
+}
+
void PushDrawTextBlobOps(PaintOpBuffer* buffer) {
size_t len = std::min(std::min(test_paint_blobs.size(), test_flags.size()),
test_floats.size() - 1);
@@ -1637,6 +1652,10 @@ class PaintOpSerializationTest : public ::testing::TestWithParam<uint8_t> {
case PaintOpType::DrawRRect:
PushDrawRRectOps(&buffer_);
break;
+ case PaintOpType::DrawSkottie:
+ // Not supported
+ // TODO(malaykeshav): Add test when Drawable supports serialization.
+ break;
case PaintOpType::DrawTextBlob:
PushDrawTextBlobOps(&buffer_);
break;
@@ -1679,9 +1698,11 @@ class PaintOpSerializationTest : public ::testing::TestWithParam<uint8_t> {
}
bool IsTypeSupported() {
- // DrawRecordOps must be flattened and are not currently serialized.
- // All other types must push non-zero amounts of ops in PushTestOps.
- return GetParamType() != PaintOpType::DrawRecord;
+ // DrawRecordOps and DrawSkottieOps must be flattened and are not currently
+ // serialized. All other types must push non-zero amounts of ops in
+ // PushTestOps.
+ return GetParamType() != PaintOpType::DrawRecord &&
+ GetParamType() != PaintOpType::DrawSkottie;
}
protected:
@@ -1718,12 +1739,9 @@ TEST_P(PaintOpSerializationTest, SmokeTest) {
PaintOpBuffer::Iterator iter(&buffer_);
size_t i = 0;
- PaintOp::DeserializeOptions deserialize_options(
- serializer.options_provider()->transfer_cache_helper(),
- serializer.options_provider()->strike_client());
- for (auto* base_written :
- DeserializerIterator(output_.get(), serializer.TotalBytesWritten(),
- deserialize_options)) {
+ for (auto* base_written : DeserializerIterator(
+ output_.get(), serializer.TotalBytesWritten(),
+ serializer.options_provider()->deserialize_options())) {
SCOPED_TRACE(base::StringPrintf(
"%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), i));
ASSERT_EQ(!*iter, !base_written);
@@ -1761,6 +1779,7 @@ TEST_P(PaintOpSerializationTest, SerializationFailures) {
// Attempt to write op into a buffer of size |i|, and only expect
// it to succeed if the buffer is large enough.
for (size_t i = 0; i < bytes_written[op_idx] + 2; ++i) {
+ options_provider.ClearPaintCache();
size_t written_bytes = iter->Serialize(
output_.get(), i, options_provider.serialize_options());
if (i >= expected_bytes) {
@@ -1932,8 +1951,8 @@ TEST(PaintOpSerializationTest, CompleteBufferSerialization) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2012,8 +2031,8 @@ TEST(PaintOpSerializationTest, Preamble) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2115,8 +2134,8 @@ TEST(PaintOpSerializationTest, SerializesNestedRecords) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2192,8 +2211,8 @@ TEST(PaintOpBufferTest, ClipsImagesDuringSerialization) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2258,8 +2277,8 @@ TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2660,6 +2679,19 @@ TEST(PaintOpBufferTest, BoundingRect_DrawDRRectOp) {
}
}
+TEST(PaintOpBufferTest, BoundingRect_DrawSkottieOp) {
+ PaintOpBuffer buffer;
+ PushDrawSkottieOps(&buffer);
+
+ SkRect rect;
+ for (auto* base_op : PaintOpBuffer::Iterator(&buffer)) {
+ auto* op = static_cast<DrawSkottieOp*>(base_op);
+
+ ASSERT_TRUE(PaintOp::GetBounds(op, &rect));
+ EXPECT_EQ(rect, op->dst.makeSorted());
+ }
+}
+
TEST(PaintOpBufferTest, BoundingRect_DrawTextBlobOp) {
PaintOpBuffer buffer;
PushDrawTextBlobOps(&buffer);
@@ -2669,10 +2701,7 @@ TEST(PaintOpBufferTest, BoundingRect_DrawTextBlobOp) {
auto* op = static_cast<DrawTextBlobOp*>(base_op);
ASSERT_TRUE(PaintOp::GetBounds(op, &rect));
- EXPECT_EQ(rect, op->blob->ToSkTextBlob()
- ->bounds()
- .makeOffset(op->x, op->y)
- .makeSorted());
+ EXPECT_EQ(rect, op->blob->bounds().makeOffset(op->x, op->y).makeSorted());
}
}
@@ -2880,8 +2909,8 @@ TEST(PaintOpBufferTest, ReplacesImagesFromProviderOOP) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -2999,11 +3028,8 @@ TEST_P(PaintFilterSerializationTest, Basic) {
ASSERT_GT(writer.size(), 0u) << PaintFilter::TypeToString(filter->type());
sk_sp<PaintFilter> deserialized_filter;
- PaintOp::DeserializeOptions deserialize_options(
- options_provider.transfer_cache_helper(),
- options_provider.strike_client());
- PaintOpReader reader(memory.data(), writer.size(), deserialize_options,
- GetParam());
+ PaintOpReader reader(memory.data(), writer.size(),
+ options_provider.deserialize_options(), GetParam());
reader.Read(&deserialized_filter);
ASSERT_TRUE(deserialized_filter);
EXPECT_TRUE(*filter == *deserialized_filter);
@@ -3029,8 +3055,8 @@ TEST(PaintOpBufferTest, PaintRecordShaderSerialization) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3121,10 +3147,8 @@ TEST(PaintOpBufferTest, SecurityConstrainedImageSerialization) {
writer.Write(filter.get());
sk_sp<PaintFilter> out_filter;
- PaintOp::DeserializeOptions deserialize_options(
- options_provider.transfer_cache_helper(),
- options_provider.strike_client());
- PaintOpReader reader(memory.get(), writer.size(), deserialize_options,
+ PaintOpReader reader(memory.get(), writer.size(),
+ options_provider.deserialize_options(),
enable_security_constraints);
reader.Read(&out_filter);
EXPECT_TRUE(*filter == *out_filter);
@@ -3150,8 +3174,8 @@ TEST(PaintOpBufferTest, DrawImageRectSerializeScaledImages) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3187,8 +3211,8 @@ TEST(PaintOpBufferTest, RecordShadersSerializeScaledImages) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3227,8 +3251,8 @@ TEST(PaintOpBufferTest, RecordShadersCached) {
SimpleBufferSerializer serializer(
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(), transfer_cache,
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3253,8 +3277,8 @@ TEST(PaintOpBufferTest, RecordShadersCached) {
SimpleBufferSerializer serializer(
memory_scaled.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(), transfer_cache,
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3266,7 +3290,8 @@ TEST(PaintOpBufferTest, RecordShadersCached) {
sk_sp<PaintRecord> records[5];
const SkShader* last_shader = nullptr;
PaintOp::DeserializeOptions deserialize_options(
- transfer_cache, options_provider.strike_client());
+ transfer_cache, options_provider.service_paint_cache(),
+ options_provider.strike_client());
// Several deserialization test cases:
// (0) deserialize once, verify cached is the same as deserialized version
@@ -3358,8 +3383,8 @@ TEST(PaintOpBufferTest, RecordShadersCachedSize) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
@@ -3367,7 +3392,8 @@ TEST(PaintOpBufferTest, RecordShadersCachedSize) {
serializer.Serialize(buffer.get());
PaintOp::DeserializeOptions deserialize_options(
- transfer_cache, options_provider.strike_client());
+ transfer_cache, options_provider.service_paint_cache(),
+ options_provider.strike_client());
auto record = PaintOpBuffer::MakeFromMemory(
memory.get(), serializer.written(), deserialize_options);
auto* shader_entry =
@@ -3409,8 +3435,8 @@ TEST(PaintOpBufferTest, NullImages) {
memory.get(), PaintOpBuffer::kInitialBufferSize,
options_provider.image_provider(),
options_provider.transfer_cache_helper(),
- options_provider.strike_server(), options_provider.color_space(),
- options_provider.can_use_lcd_text(),
+ options_provider.client_paint_cache(), options_provider.strike_server(),
+ options_provider.color_space(), options_provider.can_use_lcd_text(),
options_provider.context_supports_distance_field_text(),
options_provider.max_texture_size(),
options_provider.max_texture_bytes());
diff --git a/chromium/cc/paint/paint_op_helper_unittest.cc b/chromium/cc/paint/paint_op_helper_unittest.cc
index d94f2541ff4..eac6e4ddc62 100644
--- a/chromium/cc/paint/paint_op_helper_unittest.cc
+++ b/chromium/cc/paint/paint_op_helper_unittest.cc
@@ -65,7 +65,7 @@ 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, isVerticalText=false, "
+ "blendMode=kSrcOver, isAntiAlias=false, "
"isSubpixelText=false, isLCDRenderText=false, hinting=kNormal_Hinting, "
"isAutohinted=false, isDither=false, textEncoding=kUTF8_TextEncoding, "
"textSize=12.000, filterQuality=kNone_SkFilterQuality, "
@@ -84,7 +84,7 @@ 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, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -105,7 +105,7 @@ 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, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -121,7 +121,7 @@ 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, isVerticalText=false, "
+ "blendMode=kSrcOver, isAntiAlias=false, "
"isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
@@ -141,7 +141,7 @@ TEST(PaintOpHelper, DrawLineToString) {
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, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -159,7 +159,7 @@ TEST(PaintOpHelper, DrawOvalToString) {
str,
"DrawOvalOp(oval=[100.000,200.000 300.000x400.000], flags=[color=rgba(0, "
"0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -176,7 +176,7 @@ 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, isVerticalText=false, "
+ "blendMode=kSrcOver, isAntiAlias=false, "
"isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
@@ -201,7 +201,7 @@ TEST(PaintOpHelper, DrawRectToString) {
EXPECT_EQ(
str,
"DrawRectOp(rect=[-1.000,-2.000 -3.000x-4.000], flags=[color=rgba(0, 0, "
- "0, 255), blendMode=kSrcOver, isAntiAlias=false, isVerticalText=false, "
+ "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, "
@@ -221,7 +221,7 @@ 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, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -239,7 +239,7 @@ TEST(PaintOpHelper, DrawTextBlobToString) {
str,
"DrawTextBlobOp(blob=(nil), x=100.000, y=-222.000, flags=[color=rgba(0, "
"0, 0, 255), blendMode=kSrcOver, isAntiAlias=false, "
- "isVerticalText=false, isSubpixelText=false, isLCDRenderText=false, "
+ "isSubpixelText=false, isLCDRenderText=false, "
"hinting=kNormal_Hinting, isAutohinted=false, isDither=false, "
"textEncoding=kUTF8_TextEncoding, textSize=12.000, "
"filterQuality=kNone_SkFilterQuality, strokeWidth=0.000, "
@@ -281,7 +281,7 @@ 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, isVerticalText=false, "
+ "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, "
diff --git a/chromium/cc/paint/paint_op_perftest.cc b/chromium/cc/paint/paint_op_perftest.cc
index 2f9220f2ae1..8a4e78df588 100644
--- a/chromium/cc/paint/paint_op_perftest.cc
+++ b/chromium/cc/paint/paint_op_perftest.cc
@@ -51,6 +51,7 @@ class PaintOpPerfTest : public testing::Test {
serialized_data_.get(), kMaxSerializedBufferBytes,
test_options_provider.image_provider(),
test_options_provider.transfer_cache_helper(),
+ test_options_provider.client_paint_cache(),
test_options_provider.strike_server(),
test_options_provider.color_space(),
test_options_provider.can_use_lcd_text(),
@@ -59,6 +60,9 @@ class PaintOpPerfTest : public testing::Test {
test_options_provider.max_texture_bytes());
serializer.Serialize(&buffer, nullptr, preamble);
bytes_written = serializer.written();
+
+ // Force client paint cache entries to be written every time.
+ test_options_provider.client_paint_cache()->PurgeAll();
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
CHECK_GT(bytes_written, 0u);
@@ -80,6 +84,7 @@ class PaintOpPerfTest : public testing::Test {
to_read, remaining_read_bytes, deserialized_data_.get(),
sizeof(LargestPaintOp), &bytes_read,
test_options_provider.deserialize_options());
+ CHECK(deserialized_op);
deserialized_op->DestroyThis();
DCHECK_GE(remaining_read_bytes, bytes_read);
@@ -159,8 +164,7 @@ TEST_F(PaintOpPerfTest, TextOps) {
auto typeface = SkTypeface::MakeDefault();
- SkPaint font;
- font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkFont font;
font.setTypeface(typeface);
SkTextBlobBuilder builder;
@@ -168,8 +172,7 @@ TEST_F(PaintOpPerfTest, TextOps) {
SkRect rect = SkRect::MakeXYWH(1, 1, 1, 1);
const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f, &rect);
std::fill(run.glyphs, run.glyphs + glyph_count, 0);
- std::vector<sk_sp<SkTypeface>> typefaces = {typeface};
- auto blob = base::MakeRefCounted<PaintTextBlob>(builder.make(), typefaces);
+ auto blob = builder.make();
PaintFlags flags;
for (size_t i = 0; i < 100; ++i)
diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc
index f5a344fd349..9805e9c8149 100644
--- a/chromium/cc/paint/paint_op_reader.cc
+++ b/chromium/cc/paint/paint_op_reader.cc
@@ -7,13 +7,15 @@
#include <stddef.h>
#include <algorithm>
+#include "base/bits.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/stl_util.h"
#include "cc/paint/image_transfer_cache_entry.h"
+#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_image_builder.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/paint_shader.h"
-#include "cc/paint/path_transfer_cache_entry.h"
#include "cc/paint/shader_transfer_cache_entry.h"
#include "cc/paint/transfer_cache_deserialize_helper.h"
#include "third_party/skia/include/core/SkPath.h"
@@ -100,7 +102,12 @@ template <typename T>
void PaintOpReader::ReadSimple(T* val) {
static_assert(base::is_trivially_copyable<T>::value,
"Not trivially copyable");
- if (remaining_bytes_ < sizeof(T))
+
+ // Align everything to 4 bytes, as the writer does.
+ static constexpr size_t kAlign = 4;
+ size_t size = base::bits::Align(sizeof(T), kAlign);
+
+ if (remaining_bytes_ < size)
SetInvalid();
if (!valid_)
return;
@@ -111,8 +118,8 @@ void PaintOpReader::ReadSimple(T* val) {
// use assignment.
*val = *reinterpret_cast<const T*>(const_cast<const char*>(memory_));
- memory_ += sizeof(T);
- remaining_bytes_ -= sizeof(T);
+ memory_ += size;
+ remaining_bytes_ -= size;
}
template <typename T>
@@ -194,18 +201,38 @@ void PaintOpReader::Read(SkRRect* rect) {
}
void PaintOpReader::Read(SkPath* path) {
- uint32_t transfer_cache_entry_id;
- ReadSimple(&transfer_cache_entry_id);
+ uint32_t path_id;
+ ReadSimple(&path_id);
if (!valid_)
return;
- auto* entry =
- options_.transfer_cache->GetEntryAs<ServicePathTransferCacheEntry>(
- transfer_cache_entry_id);
- if (entry) {
- *path = entry->path();
- } else {
- valid_ = false;
+
+ size_t path_bytes = 0u;
+ ReadSize(&path_bytes);
+ if (path_bytes > remaining_bytes_)
+ SetInvalid();
+ if (!valid_)
+ return;
+
+ if (path_bytes != 0u) {
+ size_t bytes_read =
+ path->readFromMemory(const_cast<const char*>(memory_), path_bytes);
+ if (bytes_read == 0u) {
+ SetInvalid();
+ return;
+ }
+
+ options_.paint_cache->PutPath(path_id, *path);
+ memory_ += path_bytes;
+ remaining_bytes_ -= path_bytes;
+ return;
}
+
+ auto* cached_path = options_.paint_cache->GetPath(path_id);
+ if (!cached_path) {
+ SetInvalid();
+ return;
+ }
+ *path = *cached_path;
}
void PaintOpReader::Read(PaintFlags* flags) {
@@ -374,28 +401,45 @@ void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
remaining_bytes_ -= size;
}
-void PaintOpReader::Read(scoped_refptr<PaintTextBlob>* paint_blob) {
+void PaintOpReader::Read(sk_sp<SkTextBlob>* blob) {
+ AlignMemory(4);
+ uint32_t blob_id = 0u;
+ Read(&blob_id);
+ if (!valid_)
+ return;
+
size_t data_bytes = 0u;
ReadSize(&data_bytes);
- if (remaining_bytes_ < data_bytes || data_bytes == 0u)
+ if (remaining_bytes_ < data_bytes)
SetInvalid();
if (!valid_)
return;
+ if (data_bytes == 0u) {
+ auto cached_blob = options_.paint_cache->GetTextBlob(blob_id);
+ if (!cached_blob) {
+ SetInvalid();
+ return;
+ }
+
+ *blob = std::move(cached_blob);
+ return;
+ }
+
DCHECK(options_.strike_client);
SkDeserialProcs procs;
TypefaceCtx typeface_ctx(options_.strike_client);
procs.fTypefaceProc = &DeserializeTypeface;
procs.fTypefaceCtx = &typeface_ctx;
- sk_sp<SkTextBlob> blob = SkTextBlob::Deserialize(
+ sk_sp<SkTextBlob> deserialized_blob = SkTextBlob::Deserialize(
const_cast<const char*>(memory_), data_bytes, procs);
- if (!blob || typeface_ctx.invalid_typeface) {
+ if (!deserialized_blob || typeface_ctx.invalid_typeface) {
SetInvalid();
return;
}
+ options_.paint_cache->PutTextBlob(blob_id, deserialized_blob);
- *paint_blob = base::MakeRefCounted<PaintTextBlob>(
- std::move(blob), std::vector<sk_sp<SkTypeface>>());
+ *blob = std::move(deserialized_blob);
memory_ += data_bytes;
remaining_bytes_ -= data_bytes;
}
@@ -570,6 +614,10 @@ 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();
+ }
valid_ = false;
}
diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h
index 0188c8d54da..6a9c8de4193 100644
--- a/chromium/cc/paint/paint_op_reader.h
+++ b/chromium/cc/paint/paint_op_reader.h
@@ -60,7 +60,7 @@ class CC_PAINT_EXPORT PaintOpReader {
void Read(PaintFlags* flags);
void Read(PaintImage* image);
void Read(sk_sp<SkData>* data);
- void Read(scoped_refptr<PaintTextBlob>* blob);
+ void Read(sk_sp<SkTextBlob>* blob);
void Read(sk_sp<PaintFilter>* filter);
void Read(sk_sp<PaintShader>* shader);
void Read(SkMatrix* matrix);
diff --git a/chromium/cc/paint/paint_op_writer.cc b/chromium/cc/paint/paint_op_writer.cc
index ceaf05e6cdb..f933da967e4 100644
--- a/chromium/cc/paint/paint_op_writer.cc
+++ b/chromium/cc/paint/paint_op_writer.cc
@@ -4,13 +4,14 @@
#include "cc/paint/paint_op_writer.h"
+#include "base/bits.h"
#include "cc/paint/draw_image.h"
#include "cc/paint/image_provider.h"
#include "cc/paint/image_transfer_cache_entry.h"
+#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/paint_shader.h"
-#include "cc/paint/path_transfer_cache_entry.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkTextBlob.h"
@@ -92,30 +93,31 @@ PaintOpWriter::~PaintOpWriter() = default;
template <typename T>
void PaintOpWriter::WriteSimple(const T& val) {
static_assert(base::is_trivially_copyable<T>::value, "");
- EnsureBytes(sizeof(T));
+
+ // Round up each write to 4 bytes. This is not technically perfect alignment,
+ // but it is about 30% faster to post-align each write to 4 bytes than it is
+ // to pre-align memory to the correct alignment.
+ // TODO(enne): maybe we should do this correctly and DCHECK alignment.
+ static constexpr size_t kAlign = 4;
+ size_t size = base::bits::Align(sizeof(T), kAlign);
+ EnsureBytes(size);
if (!valid_)
return;
reinterpret_cast<T*>(memory_)[0] = val;
- memory_ += sizeof(T);
- remaining_bytes_ -= sizeof(T);
+ memory_ += size;
+ remaining_bytes_ -= size;
}
-
void PaintOpWriter::WriteFlattenable(const SkFlattenable* val) {
- AlignMemory(8);
if (!val) {
WriteSize(static_cast<size_t>(0u));
return;
}
- size_t size_offset = sizeof(uint64_t);
- EnsureBytes(size_offset);
+ uint64_t* size_memory = WriteSize(0u);
if (!valid_)
return;
- char* size_memory = memory_;
- memory_ += size_offset;
- remaining_bytes_ -= size_offset;
size_t bytes_written = val->serialize(
memory_, RoundDownToAlignment(remaining_bytes_, kSkiaAlignment));
@@ -123,14 +125,16 @@ void PaintOpWriter::WriteFlattenable(const SkFlattenable* val) {
valid_ = false;
return;
}
- reinterpret_cast<uint64_t*>(size_memory)[0] = bytes_written;
+ *size_memory = bytes_written;
memory_ += bytes_written;
remaining_bytes_ -= bytes_written;
}
-void PaintOpWriter::WriteSize(size_t size) {
+uint64_t* PaintOpWriter::WriteSize(size_t size) {
AlignMemory(8);
+ uint64_t* memory = reinterpret_cast<uint64_t*>(memory_);
WriteSimple<uint64_t>(size);
+ return memory;
}
void PaintOpWriter::Write(SkScalar data) {
@@ -167,13 +171,26 @@ void PaintOpWriter::Write(const SkRRect& rect) {
void PaintOpWriter::Write(const SkPath& path) {
auto id = path.getGenerationID();
- auto locked =
- options_.transfer_cache->LockEntry(TransferCacheEntryType::kPath, id);
- if (!locked) {
- options_.transfer_cache->CreateEntry(ClientPathTransferCacheEntry(path));
- options_.transfer_cache->AssertLocked(TransferCacheEntryType::kPath, id);
- }
Write(id);
+
+ uint64_t* bytes_to_skip = WriteSize(0u);
+ if (!valid_)
+ return;
+
+ if (options_.paint_cache->Get(PaintCacheDataType::kPath, id))
+ return;
+ uint64_t bytes_required = path.writeToMemory(nullptr);
+ if (bytes_required > remaining_bytes_) {
+ valid_ = false;
+ return;
+ }
+
+ size_t bytes_written = path.writeToMemory(memory_);
+ DCHECK_EQ(bytes_written, bytes_required);
+ options_.paint_cache->Put(PaintCacheDataType::kPath, id, bytes_written);
+ *bytes_to_skip = bytes_written;
+ memory_ += bytes_written;
+ remaining_bytes_ -= bytes_written;
}
void PaintOpWriter::Write(const PaintFlags& flags) {
@@ -289,22 +306,20 @@ void PaintOpWriter::Write(const SkColorSpace* color_space) {
remaining_bytes_ -= written;
}
-void PaintOpWriter::Write(const scoped_refptr<PaintTextBlob>& paint_blob) {
- DCHECK(paint_blob);
+void PaintOpWriter::Write(const sk_sp<SkTextBlob>& blob) {
+ DCHECK(blob);
if (!valid_)
return;
- AlignMemory(8);
-
- const auto& blob = paint_blob->ToSkTextBlob();
- size_t size_offset = sizeof(uint64_t);
- EnsureBytes(size_offset);
+ AlignMemory(4);
+ uint32_t blob_id = blob->uniqueID();
+ Write(blob_id);
+ uint64_t* size_memory = WriteSize(0u);
if (!valid_)
return;
- char* size_memory = memory_;
- memory_ += size_offset;
- remaining_bytes_ -= size_offset;
+ if (options_.paint_cache->Get(PaintCacheDataType::kTextBlob, blob_id))
+ return;
auto encodeTypeface = [](SkTypeface* tf, void* ctx) -> sk_sp<SkData> {
return static_cast<SkStrikeServer*>(ctx)->serializeTypeface(tf);
@@ -320,7 +335,10 @@ void PaintOpWriter::Write(const scoped_refptr<PaintTextBlob>& paint_blob) {
valid_ = false;
return;
}
- reinterpret_cast<uint64_t*>(size_memory)[0] = bytes_written;
+
+ options_.paint_cache->Put(PaintCacheDataType::kTextBlob, blob_id,
+ bytes_written);
+ *size_memory = bytes_written;
memory_ += bytes_written;
remaining_bytes_ -= bytes_written;
}
@@ -342,9 +360,8 @@ sk_sp<PaintShader> PaintOpWriter::TransformShaderIfNecessary(
&quality, paint_image_needs_mips);
}
- if (type == PaintShader::Type::kPaintRecord) {
+ if (type == PaintShader::Type::kPaintRecord)
return original->CreateScaledPaintRecord(ctm, paint_record_post_scale);
- }
return sk_ref_sp<PaintShader>(original);
}
@@ -484,7 +501,7 @@ void PaintOpWriter::Write(const PaintFilter* filter) {
if (!valid_)
return;
- AlignMemory(4);
+ AlignMemory(kSkiaAlignment);
switch (filter->type()) {
case PaintFilter::Type::kNullFilter:
NOTREACHED();
@@ -748,16 +765,12 @@ void PaintOpWriter::Write(const PaintRecord* record,
if (!valid_)
return;
- char* size_memory = memory_;
-
- memory_ += size_offset;
- remaining_bytes_ -= size_offset;
+ uint64_t* size_memory = WriteSize(0u);
if (!valid_)
return;
if (enable_security_constraints_) {
// We don't serialize PaintRecords when security constraints are enabled.
- reinterpret_cast<size_t*>(size_memory)[0] = 0u;
return;
}
@@ -767,9 +780,10 @@ void PaintOpWriter::Write(const PaintRecord* record,
const bool can_use_lcd_text = false;
SimpleBufferSerializer serializer(
memory_, remaining_bytes_, options_.image_provider,
- options_.transfer_cache, options_.strike_server, options_.color_space,
- can_use_lcd_text, options_.context_supports_distance_field_text,
- options_.max_texture_size, options_.max_texture_bytes);
+ options_.transfer_cache, options_.paint_cache, options_.strike_server,
+ options_.color_space, can_use_lcd_text,
+ options_.context_supports_distance_field_text, options_.max_texture_size,
+ options_.max_texture_bytes);
serializer.Serialize(record, playback_rect, post_scale,
post_matrix_for_analysis);
@@ -784,7 +798,7 @@ void PaintOpWriter::Write(const PaintRecord* record,
// Write the size to the size memory, which preceeds the memory for the
// record.
- reinterpret_cast<uint64_t*>(size_memory)[0] = serializer.written();
+ *size_memory = serializer.written();
// The serializer should have failed if it ran out of space. DCHECK to verify
// that it wrote at most as many bytes as we had left.
diff --git a/chromium/cc/paint/paint_op_writer.h b/chromium/cc/paint/paint_op_writer.h
index 87071bbd8e7..2b7121c181b 100644
--- a/chromium/cc/paint/paint_op_writer.h
+++ b/chromium/cc/paint/paint_op_writer.h
@@ -42,7 +42,7 @@ class CC_PAINT_EXPORT PaintOpWriter {
size_t size() const { return valid_ ? size_ - remaining_bytes_ : 0u; }
- void WriteSize(size_t size);
+ uint64_t* WriteSize(size_t size);
void Write(SkScalar data);
void Write(SkMatrix data);
@@ -60,7 +60,7 @@ class CC_PAINT_EXPORT PaintOpWriter {
void Write(const SkColorSpace* data);
void Write(const PaintShader* shader, SkFilterQuality quality);
void Write(const PaintFilter* filter);
- void Write(const scoped_refptr<PaintTextBlob>& blob);
+ void Write(const sk_sp<SkTextBlob>& blob);
void Write(SkColorType color_type);
void Write(SkClipOp op) { Write(static_cast<uint8_t>(op)); }
diff --git a/chromium/cc/paint/paint_shader.cc b/chromium/cc/paint/paint_shader.cc
index c9b0c8d38d7..9c5ce1c746b 100644
--- a/chromium/cc/paint/paint_shader.cc
+++ b/chromium/cc/paint/paint_shader.cc
@@ -52,6 +52,13 @@ bool CompareMatrices(const SkMatrix& a,
const PaintShader::RecordShaderId PaintShader::kInvalidRecordShaderId = -1;
+sk_sp<PaintShader> PaintShader::MakeEmpty() {
+ sk_sp<PaintShader> shader(new PaintShader(Type::kEmpty));
+
+ shader->CreateSkShader();
+ return shader;
+}
+
sk_sp<PaintShader> PaintShader::MakeColor(SkColor color) {
sk_sp<PaintShader> shader(new PaintShader(Type::kColor));
@@ -214,7 +221,7 @@ PaintShader::PaintShader(Type type) : shader_type_(type) {}
PaintShader::~PaintShader() = default;
bool PaintShader::has_discardable_images() const {
- return (image_ && image_.IsLazyGenerated()) ||
+ return (image_ && !image_.IsTextureBacked()) ||
(record_ && record_->HasDiscardableImages());
}
@@ -269,6 +276,12 @@ sk_sp<PaintShader> PaintShader::CreateScaledPaintRecord(
gfx::SizeF* raster_scale) const {
DCHECK_EQ(shader_type_, Type::kPaintRecord);
+ // If this is already fixed scale, then this is already good to go.
+ if (scaling_behavior_ == ScalingBehavior::kFixedScale) {
+ *raster_scale = gfx::SizeF(1.f, 1.f);
+ return sk_ref_sp<PaintShader>(this);
+ }
+
// For creating a decoded PaintRecord shader, we need to do the following:
// 1) Figure out the scale at which the record should be rasterization given
// the ctm and local_matrix on the shader.
@@ -367,6 +380,9 @@ void PaintShader::CreateSkShader(const gfx::SizeF* raster_scale,
DCHECK(!cached_shader_);
switch (shader_type_) {
+ case Type::kEmpty:
+ cached_shader_ = SkShader::MakeEmptyShader();
+ break;
case Type::kColor:
// This will be handled by the fallback check below.
break;
@@ -481,6 +497,7 @@ bool PaintShader::IsValid() const {
return true;
switch (shader_type_) {
+ case Type::kEmpty:
case Type::kColor:
return true;
case Type::kSweepGradient:
@@ -539,6 +556,7 @@ bool PaintShader::operator==(const PaintShader& other) const {
// Variables that only some shaders use.
switch (shader_type_) {
+ case Type::kEmpty:
case Type::kColor:
break;
case Type::kSweepGradient:
diff --git a/chromium/cc/paint/paint_shader.h b/chromium/cc/paint/paint_shader.h
index b0444bbfd96..17cbd1f88b8 100644
--- a/chromium/cc/paint/paint_shader.h
+++ b/chromium/cc/paint/paint_shader.h
@@ -27,6 +27,7 @@ using PaintRecord = PaintOpBuffer;
class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
public:
enum class Type : uint8_t {
+ kEmpty,
kColor,
kLinearGradient,
kRadialGradient,
@@ -45,6 +46,8 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
// shader that is backed by the paint record.
enum class ScalingBehavior : uint8_t { kRasterAtScale, kFixedScale };
+ static sk_sp<PaintShader> MakeEmpty();
+
static sk_sp<PaintShader> MakeColor(SkColor color);
static sk_sp<PaintShader> MakeLinearGradient(
diff --git a/chromium/cc/paint/paint_text_blob.cc b/chromium/cc/paint/paint_text_blob.cc
deleted file mode 100644
index d82d1b7b927..00000000000
--- a/chromium/cc/paint/paint_text_blob.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 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/paint/paint_text_blob.h"
-
-#include <vector>
-
-#include "third_party/skia/include/core/SkTextBlob.h"
-
-namespace cc {
-
-PaintTextBlob::PaintTextBlob() = default;
-PaintTextBlob::PaintTextBlob(sk_sp<SkTextBlob> blob,
- std::vector<sk_sp<SkTypeface>> typefaces)
- : sk_blob_(std::move(blob)), typefaces_(std::move(typefaces)) {}
-PaintTextBlob::~PaintTextBlob() = default;
-
-} // namespace cc
diff --git a/chromium/cc/paint/paint_text_blob.h b/chromium/cc/paint/paint_text_blob.h
deleted file mode 100644
index cbe9ed1ba64..00000000000
--- a/chromium/cc/paint/paint_text_blob.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 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_TEXT_BLOB_H_
-#define CC_PAINT_PAINT_TEXT_BLOB_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "cc/paint/paint_export.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
-namespace cc {
-
-class CC_PAINT_EXPORT PaintTextBlob
- : public base::RefCountedThreadSafe<PaintTextBlob> {
- public:
- PaintTextBlob();
- PaintTextBlob(sk_sp<SkTextBlob> blob,
- std::vector<sk_sp<SkTypeface>> typefaces);
-
- const sk_sp<SkTextBlob>& ToSkTextBlob() const { return sk_blob_; }
- const std::vector<sk_sp<SkTypeface>>& typefaces() const { return typefaces_; }
-
- operator bool() const { return !!sk_blob_; }
-
- private:
- friend base::RefCountedThreadSafe<PaintTextBlob>;
-
- ~PaintTextBlob();
-
- sk_sp<SkTextBlob> sk_blob_;
- std::vector<sk_sp<SkTypeface>> typefaces_;
-
- DISALLOW_COPY_AND_ASSIGN(PaintTextBlob);
-};
-
-} // namespace cc
-
-#endif // CC_PAINT_PAINT_TEXT_BLOB_H_
diff --git a/chromium/cc/paint/paint_text_blob_builder.cc b/chromium/cc/paint/paint_text_blob_builder.cc
deleted file mode 100644
index 2f4550a06be..00000000000
--- a/chromium/cc/paint/paint_text_blob_builder.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 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/paint/paint_text_blob_builder.h"
-
-namespace cc {
-
-PaintTextBlobBuilder::PaintTextBlobBuilder() = default;
-PaintTextBlobBuilder::~PaintTextBlobBuilder() = default;
-
-scoped_refptr<PaintTextBlob> PaintTextBlobBuilder::TakeTextBlob() {
- auto result = base::MakeRefCounted<PaintTextBlob>(sk_builder_.make(),
- std::move(typefaces_));
- typefaces_.clear();
- return result;
-}
-
-const PaintTextBlobBuilder::RunBuffer& PaintTextBlobBuilder::AllocRunPosH(
- const PaintFont& font,
- int count,
- SkScalar y,
- const SkRect* bounds) {
- typefaces_.push_back(font.typeface());
- return sk_builder_.allocRunPosH(font.ToSkPaint(), count, y, bounds);
-}
-
-const PaintTextBlobBuilder::RunBuffer& PaintTextBlobBuilder::AllocRunPos(
- const PaintFont& font,
- int count,
- const SkRect* bounds) {
- typefaces_.push_back(font.typeface());
- return sk_builder_.allocRunPos(font.ToSkPaint(), count, bounds);
-}
-
-} // namespace cc
diff --git a/chromium/cc/paint/paint_text_blob_builder.h b/chromium/cc/paint/paint_text_blob_builder.h
deleted file mode 100644
index 8c87f9b5cfa..00000000000
--- a/chromium/cc/paint/paint_text_blob_builder.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 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_TEXT_BLOB_BUILDER_H_
-#define CC_PAINT_PAINT_TEXT_BLOB_BUILDER_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "cc/paint/paint_export.h"
-#include "cc/paint/paint_font.h"
-#include "cc/paint/paint_text_blob.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkScalar.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
-
-namespace cc {
-
-class CC_PAINT_EXPORT PaintTextBlobBuilder {
- public:
- using RunBuffer = SkTextBlobBuilder::RunBuffer;
-
- PaintTextBlobBuilder();
- ~PaintTextBlobBuilder();
-
- scoped_refptr<PaintTextBlob> TakeTextBlob();
-
- // These functions pass the calls through to SkTextBlobBuilder, see its
- // interface for details.
- const RunBuffer& AllocRunPosH(const PaintFont& font,
- int count,
- SkScalar y,
- const SkRect* bounds = nullptr);
-
- const RunBuffer& AllocRunPos(const PaintFont& font,
- int count,
- const SkRect* bounds = nullptr);
-
- private:
- std::vector<sk_sp<SkTypeface>> typefaces_;
- SkTextBlobBuilder sk_builder_;
-
- DISALLOW_COPY_AND_ASSIGN(PaintTextBlobBuilder);
-};
-
-} // namespace cc
-
-#endif // CC_PAINT_PAINT_TEXT_BLOB_BUILDER_H_
diff --git a/chromium/cc/paint/path_transfer_cache_entry.cc b/chromium/cc/paint/path_transfer_cache_entry.cc
deleted file mode 100644
index c1490109c05..00000000000
--- a/chromium/cc/paint/path_transfer_cache_entry.cc
+++ /dev/null
@@ -1,54 +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.
-
-#include "cc/paint/path_transfer_cache_entry.h"
-
-namespace cc {
-
-ClientPathTransferCacheEntry::ClientPathTransferCacheEntry(const SkPath& path)
- : path_(path) {
- size_ = path_.writeToMemory(nullptr);
-}
-
-ClientPathTransferCacheEntry::~ClientPathTransferCacheEntry() = default;
-
-uint32_t ClientPathTransferCacheEntry::Id() const {
- return path_.getGenerationID();
-}
-
-size_t ClientPathTransferCacheEntry::SerializedSize() const {
- return size_;
-}
-
-bool ClientPathTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
- DCHECK_EQ(data.size(), size_);
-
- size_t bytes_written = path_.writeToMemory(data.data());
- CHECK_LE(bytes_written, size_);
- return true;
-}
-
-ServicePathTransferCacheEntry::ServicePathTransferCacheEntry() = default;
-
-ServicePathTransferCacheEntry::~ServicePathTransferCacheEntry() = default;
-
-size_t ServicePathTransferCacheEntry::CachedSize() const {
- return size_;
-}
-
-bool ServicePathTransferCacheEntry::Deserialize(
- GrContext* context,
- base::span<const uint8_t> data) {
- size_t read_bytes = path_.readFromMemory(data.data(), data.size());
- // Invalid path.
- if (read_bytes == 0)
- return false;
- if (read_bytes > data.size())
- return false;
- size_ = read_bytes;
-
- return true;
-}
-
-} // namespace cc
diff --git a/chromium/cc/paint/path_transfer_cache_entry.h b/chromium/cc/paint/path_transfer_cache_entry.h
deleted file mode 100644
index b1282e3c11f..00000000000
--- a/chromium/cc/paint/path_transfer_cache_entry.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 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_PATH_TRANSFER_CACHE_ENTRY_H_
-#define CC_PAINT_PATH_TRANSFER_CACHE_ENTRY_H_
-
-#include "base/containers/span.h"
-#include "cc/paint/paint_export.h"
-#include "cc/paint/transfer_cache_entry.h"
-#include "third_party/skia/include/core/SkPath.h"
-
-namespace cc {
-
-class CC_PAINT_EXPORT ClientPathTransferCacheEntry
- : public ClientTransferCacheEntryBase<TransferCacheEntryType::kPath> {
- public:
- explicit ClientPathTransferCacheEntry(const SkPath& path);
- ~ClientPathTransferCacheEntry() final;
- uint32_t Id() const final;
- size_t SerializedSize() const final;
- bool Serialize(base::span<uint8_t> data) const final;
-
- private:
- SkPath path_;
- size_t size_ = 0u;
-};
-
-class CC_PAINT_EXPORT ServicePathTransferCacheEntry
- : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kPath> {
- public:
- ServicePathTransferCacheEntry();
- ~ServicePathTransferCacheEntry() final;
- size_t CachedSize() const final;
- bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
-
- const SkPath& path() const { return path_; }
-
- private:
- SkPath path_;
- size_t size_ = 0;
-};
-
-} // namespace cc
-
-#endif // CC_PAINT_PATH_TRANSFER_CACHE_ENTRY_H_
diff --git a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
index 2c41fabd9d9..aa6fb645733 100644
--- a/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/chromium/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -27,10 +27,10 @@ uint32_t ClientRawMemoryTransferCacheEntry::Id() const {
bool ClientRawMemoryTransferCacheEntry::Serialize(
base::span<uint8_t> data) const {
- if (data.size() != data_.size())
+ if (data.size() < data_.size())
return false;
- memcpy(data.data(), data_.data(), data.size());
+ memcpy(data.data(), data_.data(), data_.size());
return true;
}
diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc
index 2250b26e803..2d9b4e4eb40 100644
--- a/chromium/cc/paint/record_paint_canvas.cc
+++ b/chromium/cc/paint/record_paint_canvas.cc
@@ -8,6 +8,7 @@
#include "cc/paint/paint_image_builder.h"
#include "cc/paint/paint_record.h"
#include "cc/paint/paint_recorder.h"
+#include "cc/paint/skottie_wrapper.h"
#include "third_party/skia/include/core/SkAnnotation.h"
#include "third_party/skia/include/core/SkMetaData.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
@@ -263,7 +264,13 @@ void RecordPaintCanvas::drawImageRect(const PaintImage& image,
list_->push<DrawImageRectOp>(image, src, dst, flags, constraint);
}
-void RecordPaintCanvas::drawTextBlob(scoped_refptr<PaintTextBlob> blob,
+void RecordPaintCanvas::drawSkottie(scoped_refptr<SkottieWrapper> skottie,
+ const SkRect& dst,
+ float t) {
+ list_->push<DrawSkottieOp>(std::move(skottie), dst, t);
+}
+
+void RecordPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags) {
@@ -308,7 +315,7 @@ SkNoDrawCanvas* RecordPaintCanvas::GetCanvas() {
return &*canvas_;
// Size the canvas to be large enough to contain the |recording_bounds|, which
- // may not be positioned at th origin.
+ // may not be positioned at the origin.
SkIRect enclosing_rect = recording_bounds_.roundOut();
canvas_.emplace(enclosing_rect.right(), enclosing_rect.bottom());
diff --git a/chromium/cc/paint/record_paint_canvas.h b/chromium/cc/paint/record_paint_canvas.h
index fb39721603f..cfa24116f45 100644
--- a/chromium/cc/paint/record_paint_canvas.h
+++ b/chromium/cc/paint/record_paint_canvas.h
@@ -15,7 +15,6 @@
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_record.h"
-#include "cc/paint/paint_text_blob.h"
#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
namespace cc {
@@ -84,8 +83,10 @@ class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas {
const SkRect& dst,
const PaintFlags* flags,
SrcRectConstraint constraint) override;
-
- void drawTextBlob(scoped_refptr<PaintTextBlob> blob,
+ void drawSkottie(scoped_refptr<SkottieWrapper> skottie,
+ const SkRect& dst,
+ float t) override;
+ void drawTextBlob(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags) override;
diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc
index ea360c2b630..4bb07e76333 100644
--- a/chromium/cc/paint/skia_paint_canvas.cc
+++ b/chromium/cc/paint/skia_paint_canvas.cc
@@ -303,7 +303,13 @@ void SkiaPaintCanvas::drawImageRect(const PaintImage& image,
FlushAfterDrawIfNeeded();
}
-void SkiaPaintCanvas::drawTextBlob(scoped_refptr<PaintTextBlob> blob,
+void SkiaPaintCanvas::drawSkottie(scoped_refptr<SkottieWrapper> skottie,
+ const SkRect& dst,
+ float t) {
+ skottie->Draw(canvas_, t, dst);
+}
+
+void SkiaPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags) {
@@ -312,7 +318,7 @@ void SkiaPaintCanvas::drawTextBlob(scoped_refptr<PaintTextBlob> blob,
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
- canvas_->drawTextBlob(blob->ToSkTextBlob(), x, y, paint);
+ canvas_->drawTextBlob(blob, x, y, paint);
FlushAfterDrawIfNeeded();
}
diff --git a/chromium/cc/paint/skia_paint_canvas.h b/chromium/cc/paint/skia_paint_canvas.h
index c514017abd1..458bf99d4da 100644
--- a/chromium/cc/paint/skia_paint_canvas.h
+++ b/chromium/cc/paint/skia_paint_canvas.h
@@ -14,7 +14,6 @@
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_record.h"
-#include "cc/paint/paint_text_blob.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace cc {
@@ -107,8 +106,10 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas {
const SkRect& dst,
const PaintFlags* flags,
SrcRectConstraint constraint) override;
-
- void drawTextBlob(scoped_refptr<PaintTextBlob> blob,
+ void drawSkottie(scoped_refptr<SkottieWrapper> skottie,
+ const SkRect& dst,
+ float t) override;
+ void drawTextBlob(sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y,
const PaintFlags& flags) override;
diff --git a/chromium/cc/paint/skia_paint_image_generator.cc b/chromium/cc/paint/skia_paint_image_generator.cc
index fc42d24b40f..3eb864f12cf 100644
--- a/chromium/cc/paint/skia_paint_image_generator.cc
+++ b/chromium/cc/paint/skia_paint_image_generator.cc
@@ -31,15 +31,19 @@ bool SkiaPaintImageGenerator::onGetPixels(const SkImageInfo& info,
info, pixels, row_bytes, frame_index_, client_id_, uniqueID());
}
-bool SkiaPaintImageGenerator::onQueryYUV8(SkYUVSizeInfo* size_info,
- SkYUVColorSpace* color_space) const {
- return paint_image_generator_->QueryYUV8(size_info, color_space);
+bool SkiaPaintImageGenerator::onQueryYUVA8(
+ SkYUVASizeInfo* size_info,
+ SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ SkYUVColorSpace* color_space) const {
+ return paint_image_generator_->QueryYUVA8(size_info, indices, color_space);
}
-bool SkiaPaintImageGenerator::onGetYUV8Planes(const SkYUVSizeInfo& size_info,
- void* planes[3]) {
- return paint_image_generator_->GetYUV8Planes(size_info, planes, frame_index_,
- uniqueID());
+bool SkiaPaintImageGenerator::onGetYUVA8Planes(
+ const SkYUVASizeInfo& size_info,
+ const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ void* planes[4]) {
+ return paint_image_generator_->GetYUVA8Planes(size_info, indices, planes,
+ frame_index_, uniqueID());
}
} // namespace cc
diff --git a/chromium/cc/paint/skia_paint_image_generator.h b/chromium/cc/paint/skia_paint_image_generator.h
index c93e03b0a99..55068c2f988 100644
--- a/chromium/cc/paint/skia_paint_image_generator.h
+++ b/chromium/cc/paint/skia_paint_image_generator.h
@@ -25,10 +25,12 @@ class CC_PAINT_EXPORT SkiaPaintImageGenerator final : public SkImageGenerator {
void* pixels,
size_t row_bytes,
const Options& options) override;
- bool onQueryYUV8(SkYUVSizeInfo* size_info,
- SkYUVColorSpace* color_space) const override;
- bool onGetYUV8Planes(const SkYUVSizeInfo& size_info,
- void* planes[3]) override;
+ bool onQueryYUVA8(SkYUVASizeInfo* size_info,
+ SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ SkYUVColorSpace* color_space) const override;
+ bool onGetYUVA8Planes(const SkYUVASizeInfo& size_info,
+ const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
+ void* planes[3]) override;
private:
sk_sp<PaintImageGenerator> paint_image_generator_;
diff --git a/chromium/cc/paint/skottie_wrapper.cc b/chromium/cc/paint/skottie_wrapper.cc
new file mode 100644
index 00000000000..ad5fb740898
--- /dev/null
+++ b/chromium/cc/paint/skottie_wrapper.cc
@@ -0,0 +1,34 @@
+// 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/paint/skottie_wrapper.h"
+
+#include "base/memory/ref_counted_memory.h"
+#include "base/trace_event/trace_event.h"
+#include "third_party/skia/include/core/SkStream.h"
+
+namespace cc {
+
+SkottieWrapper::SkottieWrapper(
+ const scoped_refptr<base::RefCountedMemory>& data_stream) {
+ TRACE_EVENT0("cc", "SkottieWrapper Parse");
+ SkMemoryStream sk_stream(data_stream->front(), data_stream->size());
+ animation_ = skottie::Animation::Make(&sk_stream);
+ DCHECK(animation_);
+}
+
+SkottieWrapper::SkottieWrapper(std::unique_ptr<SkMemoryStream> stream)
+ : animation_(skottie::Animation::Make(stream.get())) {
+ DCHECK(animation_);
+}
+
+SkottieWrapper::~SkottieWrapper() {}
+
+void SkottieWrapper::Draw(SkCanvas* canvas, float t, const SkRect& rect) {
+ base::AutoLock lock(lock_);
+ animation_->seek(t);
+ animation_->render(canvas, &rect);
+}
+
+} // namespace cc
diff --git a/chromium/cc/paint/skottie_wrapper.h b/chromium/cc/paint/skottie_wrapper.h
new file mode 100644
index 00000000000..f4e312ec029
--- /dev/null
+++ b/chromium/cc/paint/skottie_wrapper.h
@@ -0,0 +1,55 @@
+// 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_SKOTTIE_WRAPPER_H_
+#define CC_PAINT_SKOTTIE_WRAPPER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "cc/paint/paint_export.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "third_party/skia/modules/skottie/include/Skottie.h"
+
+class SkCanvas;
+class SkMemoryStream;
+
+namespace base {
+class RefCountedMemory;
+} // namespace base
+
+namespace cc {
+
+// A wrapper over Skia's Skottie object that can be shared by multiple
+// SkiaVectorAnimation objects. This class is thread safe when performing a draw
+// on an SkCanvas.
+class CC_PAINT_EXPORT SkottieWrapper
+ : public base::RefCountedThreadSafe<SkottieWrapper> {
+ public:
+ explicit SkottieWrapper(
+ const scoped_refptr<base::RefCountedMemory>& data_stream);
+ explicit SkottieWrapper(std::unique_ptr<SkMemoryStream> stream);
+
+ // A thread safe call that will draw an image with bounds |rect| for the
+ // frame at normalized time instant |t| onto the |canvas|.
+ void Draw(SkCanvas* canvas, float t, const SkRect& rect);
+
+ float duration() const { return animation_->duration(); }
+ SkSize size() const { return animation_->size(); }
+
+ private:
+ friend class base::RefCountedThreadSafe<SkottieWrapper>;
+ ~SkottieWrapper();
+
+ base::Lock lock_;
+ sk_sp<skottie::Animation> animation_;
+
+ DISALLOW_COPY_AND_ASSIGN(SkottieWrapper);
+};
+
+} // namespace cc
+
+#endif // CC_PAINT_SKOTTIE_WRAPPER_H_
diff --git a/chromium/cc/paint/solid_color_analyzer.cc b/chromium/cc/paint/solid_color_analyzer.cc
index 2ecc07bb767..12ad8e46f1d 100644
--- a/chromium/cc/paint/solid_color_analyzer.cc
+++ b/chromium/cc/paint/solid_color_analyzer.cc
@@ -213,6 +213,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
&is_transparent, &color);
break;
}
+ case PaintOpType::DrawSkottie:
case PaintOpType::DrawTextBlob:
// Anything that has to do a save layer is probably not solid. As it will
// likely need more than one draw op.
diff --git a/chromium/cc/paint/transfer_cache_entry.cc b/chromium/cc/paint/transfer_cache_entry.cc
index bb34a4cada8..d87ac461b87 100644
--- a/chromium/cc/paint/transfer_cache_entry.cc
+++ b/chromium/cc/paint/transfer_cache_entry.cc
@@ -9,7 +9,6 @@
#include "base/logging.h"
#include "cc/paint/color_space_transfer_cache_entry.h"
#include "cc/paint/image_transfer_cache_entry.h"
-#include "cc/paint/path_transfer_cache_entry.h"
#include "cc/paint/raw_memory_transfer_cache_entry.h"
#include "cc/paint/shader_transfer_cache_entry.h"
@@ -24,11 +23,9 @@ std::unique_ptr<ServiceTransferCacheEntry> ServiceTransferCacheEntry::Create(
return std::make_unique<ServiceImageTransferCacheEntry>();
case TransferCacheEntryType::kColorSpace:
return std::make_unique<ServiceColorSpaceTransferCacheEntry>();
- case TransferCacheEntryType::kPath:
- return std::make_unique<ServicePathTransferCacheEntry>();
case TransferCacheEntryType::kShader:
- // ServiceShaderTransferCache is only created via CreateLocalEntry
- // and is never serialized/deserialized.
+ // ServiceShader/TextBlobTransferCache is only created via
+ // CreateLocalEntry and is never serialized/deserialized.
return nullptr;
}
@@ -50,7 +47,6 @@ bool ServiceTransferCacheEntry::UsesGrContext(TransferCacheEntryType type) {
switch (type) {
case TransferCacheEntryType::kRawMemory:
case TransferCacheEntryType::kColorSpace:
- case TransferCacheEntryType::kPath:
case TransferCacheEntryType::kShader:
return false;
case TransferCacheEntryType::kImage:
diff --git a/chromium/cc/paint/transfer_cache_entry.h b/chromium/cc/paint/transfer_cache_entry.h
index 55f1ce7dba3..374607e2497 100644
--- a/chromium/cc/paint/transfer_cache_entry.h
+++ b/chromium/cc/paint/transfer_cache_entry.h
@@ -23,7 +23,6 @@ enum class TransferCacheEntryType : uint32_t {
kRawMemory,
kImage,
kColorSpace,
- kPath,
kShader,
// Add new entries above this line, make sure to update kLast.
kLast = kShader,
diff --git a/chromium/cc/paint/transfer_cache_serialize_helper.cc b/chromium/cc/paint/transfer_cache_serialize_helper.cc
index 1baec7dddec..f50f150f7c7 100644
--- a/chromium/cc/paint/transfer_cache_serialize_helper.cc
+++ b/chromium/cc/paint/transfer_cache_serialize_helper.cc
@@ -27,13 +27,14 @@ bool TransferCacheSerializeHelper::LockEntry(TransferCacheEntryType type,
return true;
}
-void TransferCacheSerializeHelper::CreateEntry(
- const ClientTransferCacheEntry& entry) {
+size_t TransferCacheSerializeHelper::CreateEntry(
+ const ClientTransferCacheEntry& entry,
+ char* memory) {
// We shouldn't be creating entries if they were already created or locked.
EntryKey key(entry.Type(), entry.Id());
DCHECK_EQ(added_entries_.count(key), 0u);
- CreateEntryInternal(entry);
added_entries_.insert(key);
+ return CreateEntryInternal(entry, memory);
}
void TransferCacheSerializeHelper::FlushEntries() {
diff --git a/chromium/cc/paint/transfer_cache_serialize_helper.h b/chromium/cc/paint/transfer_cache_serialize_helper.h
index 7fd947aaec8..1a204407538 100644
--- a/chromium/cc/paint/transfer_cache_serialize_helper.h
+++ b/chromium/cc/paint/transfer_cache_serialize_helper.h
@@ -19,7 +19,10 @@ class CC_PAINT_EXPORT TransferCacheSerializeHelper {
virtual ~TransferCacheSerializeHelper();
bool LockEntry(TransferCacheEntryType type, uint32_t id);
- void CreateEntry(const ClientTransferCacheEntry& entry);
+ // 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);
void FlushEntries();
void AssertLocked(TransferCacheEntryType type, uint32_t id);
@@ -28,7 +31,8 @@ class CC_PAINT_EXPORT TransferCacheSerializeHelper {
using EntryKey = std::pair<TransferCacheEntryType, uint32_t>;
virtual bool LockEntryInternal(const EntryKey& key) = 0;
- virtual void CreateEntryInternal(const ClientTransferCacheEntry& entry) = 0;
+ virtual size_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 f003d24f80e..f24917ab29d 100644
--- a/chromium/cc/paint/transfer_cache_unittest.cc
+++ b/chromium/cc/paint/transfer_cache_unittest.cc
@@ -20,6 +20,7 @@
#include "gpu/command_buffer/service/service_transfer_cache.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/ipc/raster_in_process_context.h"
+#include "gpu/ipc/test_gpu_thread_holder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImage.h"
#include "ui/gl/gl_implementation.h"
@@ -47,8 +48,8 @@ class TransferCacheTest : public testing::Test {
context_ = std::make_unique<gpu::RasterInProcessContext>();
auto result = context_->Initialize(
- /*service=*/nullptr, attribs, gpu::SharedMemoryLimits(),
- &gpu_memory_buffer_manager_, &image_factory_,
+ gpu::GetTestGpuThreadHolder()->GetTaskExecutor(), attribs,
+ gpu::SharedMemoryLimits(), &gpu_memory_buffer_manager_, &image_factory_,
/*gpu_channel_manager_delegate=*/nullptr, nullptr, nullptr);
ASSERT_EQ(result, gpu::ContextResult::kSuccess);
@@ -177,7 +178,9 @@ TEST_F(TransferCacheTest, CountEviction) {
EXPECT_EQ(service_cache->cache_size_for_testing(), 20u);
}
-TEST_F(TransferCacheTest, RawMemoryTransfer) {
+// This tests a size that is small enough that the transfer buffer is used
+// inside of RasterImplementation::MapTransferCacheEntry.
+TEST_F(TransferCacheTest, RawMemoryTransferSmall) {
auto* service_cache = ServiceTransferCache();
// Create an entry with some initialized data.
@@ -202,6 +205,33 @@ TEST_F(TransferCacheTest, RawMemoryTransfer) {
EXPECT_EQ(data, service_data);
}
+// This tests a size that is large enough that mapped memory is used inside
+// of RasterImplementation::MapTransferCacheEntry.
+TEST_F(TransferCacheTest, RawMemoryTransferLarge) {
+ auto* service_cache = ServiceTransferCache();
+
+ // Create an entry with some initialized data.
+ std::vector<uint8_t> data;
+ data.resize(1500);
+ for (size_t i = 0; i < data.size(); ++i) {
+ data[i] = i;
+ }
+
+ // Add the entry to the transfer cache
+ ClientRawMemoryTransferCacheEntry client_entry(data);
+ CreateEntry(client_entry);
+ ri()->Finish();
+
+ // Validate service-side data matches.
+ ServiceTransferCacheEntry* service_entry =
+ service_cache->GetEntry(gpu::ServiceTransferCache::EntryKey(
+ decoder_id(), client_entry.Type(), client_entry.Id()));
+ EXPECT_EQ(service_entry->Type(), client_entry.Type());
+ const std::vector<uint8_t> service_data =
+ static_cast<ServiceRawMemoryTransferCacheEntry*>(service_entry)->data();
+ EXPECT_EQ(data, service_data);
+}
+
TEST_F(TransferCacheTest, ImageMemoryTransfer) {
// TODO(ericrk): This test doesn't work. crbug.com/859619
return;
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index 1e4e21bb134..fc981249cd6 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -13,7 +13,7 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/raster/raster_source.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "components/viz/common/resources/bitmap_allocation.h"
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index 2b9b386ee08..2a731285a2c 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -134,7 +134,8 @@ static void RasterizeSourceOOP(
if (mailbox->IsZero()) {
DCHECK(!sync_token.HasData());
auto* sii = context_provider->SharedImageInterface();
- uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER;
+ uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
if (texture_is_overlay_candidate)
flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
*mailbox = sii->CreateSharedImage(resource_format, resource_size,
@@ -144,10 +145,6 @@ static void RasterizeSourceOOP(
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
- GLuint texture_id = ri->CreateAndConsumeTexture(
- texture_is_overlay_candidate, gfx::BufferUsage::SCANOUT, resource_format,
- mailbox->name);
-
// TODO(enne): Use the |texture_target|? GpuMemoryBuffer backed textures don't
// use GL_TEXTURE_2D.
ri->BeginRasterCHROMIUM(raster_source->background_color(), msaa_sample_count,
@@ -171,8 +168,6 @@ static void RasterizeSourceOOP(
// TODO(ericrk): Handle unpremultiply+dither for 4444 cases.
// https://crbug.com/789153
-
- ri->DeleteTextures(1, &texture_id);
}
static void RasterizeSource(
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index 562d2e21bfe..75e11544218 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -366,61 +366,50 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
bool mailbox_texture_is_overlay_candidate,
const gpu::SyncToken& sync_token,
const gfx::ColorSpace& color_space) {
- viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
- worker_context_provider_);
- gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
- DCHECK(ri);
+ auto* sii = worker_context_provider_->SharedImageInterface();
+ DCHECK(sii);
+
+ if (!staging_buffer->gpu_memory_buffer.get()) {
+ // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
+ // we don't have anything to give to copy into the resource. We report a
+ // zero mailbox that will result in checkerboarding, and be treated as OOM
+ // which should retry.
+ if (!mailbox->IsZero()) {
+ sii->DestroySharedImage(sync_token, *mailbox);
+ mailbox->SetZero();
+ }
+ return gpu::SyncToken();
+ }
if (mailbox->IsZero()) {
- auto* sii = worker_context_provider_->SharedImageInterface();
uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER;
if (mailbox_texture_is_overlay_candidate)
flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
*mailbox = sii->CreateSharedImage(resource_format, resource_size,
color_space, flags);
- ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
+ }
+
+ // Create staging shared image.
+ if (staging_buffer->mailbox.IsZero()) {
+ staging_buffer->mailbox = sii->CreateSharedImage(
+ staging_buffer->gpu_memory_buffer.get(), gpu_memory_buffer_manager_,
+ color_space, gpu::SHARED_IMAGE_USAGE_RASTER);
} else {
- ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
+ sii->UpdateSharedImage(staging_buffer->sync_token, staging_buffer->mailbox);
}
+ viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
+ worker_context_provider_);
+ gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
+ 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);
-
- // Create and bind staging texture.
- if (!staging_buffer->texture_id) {
- staging_buffer->texture_id =
- ri->CreateTexture(true, StagingBufferUsage(), staging_buffer->format);
- ri->TexParameteri(staging_buffer->texture_id, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- ri->TexParameteri(staging_buffer->texture_id, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
- ri->TexParameteri(staging_buffer->texture_id, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- ri->TexParameteri(staging_buffer->texture_id, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
- }
-
- // Create and bind image.
- if (!staging_buffer->image_id) {
- if (staging_buffer->gpu_memory_buffer) {
- staging_buffer->image_id = ri->CreateImageCHROMIUM(
- staging_buffer->gpu_memory_buffer->AsClientBuffer(),
- staging_buffer->size.width(), staging_buffer->size.height(),
- GLInternalFormat(staging_buffer->format));
- ri->BindTexImage2DCHROMIUM(staging_buffer->texture_id,
- staging_buffer->image_id);
- }
- } else {
- ri->ReleaseTexImage2DCHROMIUM(staging_buffer->texture_id,
- staging_buffer->image_id);
- ri->BindTexImage2DCHROMIUM(staging_buffer->texture_id,
- staging_buffer->image_id);
- }
-
- // Unbind staging texture.
- // TODO(vmiura): Need a way to ensure we don't hold onto bindings?
- // ri->BindTexture(image_target, 0);
+ 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.
@@ -467,8 +456,8 @@ 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_buffer->texture_id, mailbox_texture_id, 0, y, 0,
- y, rect_to_copy.width(), rows_to_copy);
+ ri->CopySubTexture(staging_texture_id, mailbox_texture_id, 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
@@ -484,11 +473,20 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
if (query_target != GL_NONE)
ri->EndQueryEXT(query_target);
- ri->DeleteTextures(1, &mailbox_texture_id);
+ 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.
- return viz::ClientResourceProvider::GenerateSyncTokenHelper(ri);
+ // The same sync token is used to synchronize operations on the staging
+ // buffer. Note, the query completion is generally enough to guarantee
+ // ordering, but there are some paths (e.g.
+ // StagingBufferPool::ReduceMemoryUsage) that may destroy the staging buffer
+ // without waiting for the query completion.
+ gpu::SyncToken out_sync_token =
+ viz::ClientResourceProvider::GenerateSyncTokenHelper(ri);
+ staging_buffer->sync_token = out_sync_token;
+ return out_sync_token;
}
gfx::BufferUsage OneCopyRasterBufferProvider::StagingBufferUsage() const {
diff --git a/chromium/cc/raster/playback_image_provider.cc b/chromium/cc/raster/playback_image_provider.cc
index 50305d1b2a5..7aef7601c14 100644
--- a/chromium/cc/raster/playback_image_provider.cc
+++ b/chromium/cc/raster/playback_image_provider.cc
@@ -18,10 +18,8 @@ void UnrefImageFromCache(DrawImage draw_image,
PlaybackImageProvider::PlaybackImageProvider(
ImageDecodeCache* cache,
- const gfx::ColorSpace& target_color_space,
base::Optional<Settings>&& settings)
: cache_(cache),
- target_color_space_(target_color_space),
settings_(std::move(settings)) {
DCHECK(cache_);
}
@@ -53,7 +51,7 @@ PlaybackImageProvider::GetDecodedDrawImage(const DrawImage& draw_image) {
? PaintImage::kDefaultFrameIndex
: it->second;
- DrawImage adjusted_image(draw_image, 1.f, frame_index, target_color_space_);
+ DrawImage adjusted_image(draw_image, 1.f, frame_index);
if (!cache_->UseCacheForDrawImage(adjusted_image)) {
return ScopedDecodedDrawImage(DecodedDrawImage(
paint_image.GetSkImage(), SkSize::Make(0, 0), SkSize::Make(1.f, 1.f),
diff --git a/chromium/cc/raster/playback_image_provider.h b/chromium/cc/raster/playback_image_provider.h
index a33092d2b5b..990835c040f 100644
--- a/chromium/cc/raster/playback_image_provider.h
+++ b/chromium/cc/raster/playback_image_provider.h
@@ -35,7 +35,6 @@ class CC_EXPORT PlaybackImageProvider : public ImageProvider {
// If no settings are provided, all images are skipped during rasterization.
PlaybackImageProvider(ImageDecodeCache* cache,
- const gfx::ColorSpace& target_color_space,
base::Optional<Settings>&& settings);
~PlaybackImageProvider() override;
@@ -48,7 +47,6 @@ class CC_EXPORT PlaybackImageProvider : public ImageProvider {
private:
ImageDecodeCache* cache_;
- gfx::ColorSpace target_color_space_;
base::Optional<Settings> settings_;
DISALLOW_COPY_AND_ASSIGN(PlaybackImageProvider);
diff --git a/chromium/cc/raster/playback_image_provider_unittest.cc b/chromium/cc/raster/playback_image_provider_unittest.cc
index dd4f6a4a9e8..dbc5ba0c3e2 100644
--- a/chromium/cc/raster/playback_image_provider_unittest.cc
+++ b/chromium/cc/raster/playback_image_provider_unittest.cc
@@ -66,7 +66,7 @@ class MockDecodeCache : public StubDecodeCache {
TEST(PlaybackImageProviderTest, SkipsAllImages) {
MockDecodeCache cache;
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(), base::nullopt);
+ PlaybackImageProvider provider(&cache, base::nullopt);
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -93,8 +93,7 @@ TEST(PlaybackImageProviderTest, SkipsSomeImages) {
settings.emplace();
settings->images_to_skip = {skip_image.stable_id()};
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
- std::move(settings));
+ PlaybackImageProvider provider(&cache, std::move(settings));
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -108,8 +107,7 @@ TEST(PlaybackImageProviderTest, RefAndUnrefDecode) {
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
- std::move(settings));
+ PlaybackImageProvider provider(&cache, std::move(settings));
{
SkRect rect = SkRect::MakeWH(10, 10);
@@ -137,8 +135,7 @@ TEST(PlaybackImageProviderTest, SwapsGivenFrames) {
settings.emplace();
settings->image_to_current_frame_index = image_to_frame;
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
- std::move(settings));
+ PlaybackImageProvider provider(&cache, std::move(settings));
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -154,8 +151,7 @@ TEST(PlaybackImageProviderTest, BitmapImages) {
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
- std::move(settings));
+ PlaybackImageProvider provider(&cache, std::move(settings));
{
SkIRect rect = SkIRect::MakeWH(10, 10);
@@ -176,8 +172,7 @@ TEST(PlaybackImageProviderTest, IgnoresImagesNotSupportedByCache) {
cache.set_use_cache_for_draw_image(false);
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
- std::move(settings));
+ PlaybackImageProvider provider(&cache, std::move(settings));
{
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc
index bbdd6f57bda..63dd9fd95d1 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(), nullptr, capabilities_);
+ context_gl_.get(), capabilities_);
}
// viz::ContextProvider implementation.
diff --git a/chromium/cc/raster/raster_source_unittest.cc b/chromium/cc/raster/raster_source_unittest.cc
index 311cb5eef2b..b9100522081 100644
--- a/chromium/cc/raster/raster_source_unittest.cc
+++ b/chromium/cc/raster/raster_source_unittest.cc
@@ -211,25 +211,19 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) {
// Tile sized iterators. These should find only one pixel ref.
{
- gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB();
std::vector<const DrawImage*> images;
raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), &images);
EXPECT_EQ(1u, images.size());
- DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
- target_color_space);
+ DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex);
EXPECT_EQ(discardable_image[0][0], images[0]->paint_image());
- EXPECT_EQ(target_color_space, image.target_color_space());
}
// Shifted tile sized iterators. These should find only one pixel ref.
{
- gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
std::vector<const DrawImage*> images;
raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), &images);
EXPECT_EQ(1u, images.size());
- DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
- target_color_space);
+ DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex);
EXPECT_EQ(discardable_image[1][1], images[0]->paint_image());
- EXPECT_EQ(target_color_space, image.target_color_space());
}
// Ensure there's no discardable pixel refs in the empty cell
{
diff --git a/chromium/cc/raster/single_thread_task_graph_runner.cc b/chromium/cc/raster/single_thread_task_graph_runner.cc
index e17ec83f13f..0bb96a42a42 100644
--- a/chromium/cc/raster/single_thread_task_graph_runner.cc
+++ b/chromium/cc/raster/single_thread_task_graph_runner.cc
@@ -18,7 +18,9 @@ SingleThreadTaskGraphRunner::SingleThreadTaskGraphRunner()
: lock_(),
has_ready_to_run_tasks_cv_(&lock_),
has_namespaces_with_finished_running_tasks_cv_(&lock_),
- shutdown_(false) {}
+ shutdown_(false) {
+ has_ready_to_run_tasks_cv_.declare_only_used_while_idle();
+}
SingleThreadTaskGraphRunner::~SingleThreadTaskGraphRunner() = default;
@@ -81,7 +83,8 @@ void SingleThreadTaskGraphRunner::WaitForTasksToFinishRunning(
{
base::AutoLock lock(lock_);
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ // http://crbug.com/902823
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
auto* task_namespace = work_queue_.GetNamespaceForToken(token);
diff --git a/chromium/cc/raster/staging_buffer_pool.cc b/chromium/cc/raster/staging_buffer_pool.cc
index a24fe9a16fb..a02c43e4e98 100644
--- a/chromium/cc/raster/staging_buffer_pool.cc
+++ b/chromium/cc/raster/staging_buffer_pool.cc
@@ -12,7 +12,9 @@
#include "cc/base/container_util.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/resource_sizes.h"
+#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/raster_interface.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -68,23 +70,19 @@ StagingBuffer::StagingBuffer(const gfx::Size& size, viz::ResourceFormat format)
: size(size), format(format) {}
StagingBuffer::~StagingBuffer() {
- DCHECK_EQ(texture_id, 0u);
- DCHECK_EQ(image_id, 0u);
+ DCHECK(mailbox.IsZero());
DCHECK_EQ(query_id, 0u);
}
-void StagingBuffer::DestroyGLResources(gpu::raster::RasterInterface* ri) {
+void StagingBuffer::DestroyGLResources(gpu::raster::RasterInterface* ri,
+ gpu::SharedImageInterface* sii) {
if (query_id) {
ri->DeleteQueriesEXT(1, &query_id);
query_id = 0;
}
- if (image_id) {
- ri->DestroyImageCHROMIUM(image_id);
- image_id = 0;
- }
- if (texture_id) {
- ri->DeleteTextures(1, &texture_id);
- texture_id = 0;
+ if (!mailbox.IsZero()) {
+ sii->DestroySharedImage(sync_token, mailbox);
+ mailbox.SetZero();
}
}
@@ -94,9 +92,9 @@ void StagingBuffer::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
if (!gpu_memory_buffer)
return;
- gfx::GpuMemoryBufferId buffer_id = gpu_memory_buffer->GetId();
+ // Use |this| as the id, which works with multiple StagingBuffers.
std::string buffer_dump_name =
- base::StringPrintf("cc/one_copy/staging_memory/buffer_%d", buffer_id.id);
+ base::StringPrintf("cc/one_copy/staging_memory/buffer_%p", this);
MemoryAllocatorDump* buffer_dump = pmd->CreateAllocatorDump(buffer_dump_name);
uint64_t buffer_size_in_bytes =
@@ -248,6 +246,8 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
worker_context_provider_);
gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
+ gpu::SharedImageInterface* sii =
+ worker_context_provider_->SharedImageInterface();
DCHECK(ri);
// Check if any busy buffers have become available.
@@ -324,7 +324,7 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
if (free_buffers_.empty())
break;
- free_buffers_.front()->DestroyGLResources(ri);
+ free_buffers_.front()->DestroyGLResources(ri, sii);
MarkStagingBufferAsBusy(free_buffers_.front().get());
RemoveStagingBuffer(free_buffers_.front().get());
free_buffers_.pop_front();
@@ -395,14 +395,19 @@ void StagingBufferPool::ReleaseBuffersNotUsedSince(base::TimeTicks time) {
gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
DCHECK(ri);
+ gpu::SharedImageInterface* sii =
+ worker_context_provider_->SharedImageInterface();
+ DCHECK(sii);
+ bool destroyed_buffers = false;
// Note: Front buffer is guaranteed to be LRU so we can stop releasing
// 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;
- free_buffers_.front()->DestroyGLResources(ri);
+ destroyed_buffers = true;
+ free_buffers_.front()->DestroyGLResources(ri, sii);
MarkStagingBufferAsBusy(free_buffers_.front().get());
RemoveStagingBuffer(free_buffers_.front().get());
free_buffers_.pop_front();
@@ -412,10 +417,16 @@ void StagingBufferPool::ReleaseBuffersNotUsedSince(base::TimeTicks time) {
if (busy_buffers_.front()->last_usage > time)
return;
- busy_buffers_.front()->DestroyGLResources(ri);
+ destroyed_buffers = true;
+ busy_buffers_.front()->DestroyGLResources(ri, sii);
RemoveStagingBuffer(busy_buffers_.front().get());
busy_buffers_.pop_front();
}
+
+ if (destroyed_buffers) {
+ ri->OrderingBarrierCHROMIUM();
+ worker_context_provider_->ContextSupport()->FlushPendingWork();
+ }
}
}
diff --git a/chromium/cc/raster/staging_buffer_pool.h b/chromium/cc/raster/staging_buffer_pool.h
index 687b0066588..cfd0f3a414c 100644
--- a/chromium/cc/raster/staging_buffer_pool.h
+++ b/chromium/cc/raster/staging_buffer_pool.h
@@ -22,6 +22,8 @@
#include "cc/cc_export.h"
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/common/gl2_types.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -32,6 +34,7 @@ namespace gpu {
namespace raster {
class RasterInterface;
}
+class SharedImageInterface;
} // namespace gpu
namespace viz {
@@ -44,7 +47,8 @@ struct StagingBuffer {
StagingBuffer(const gfx::Size& size, viz::ResourceFormat format);
~StagingBuffer();
- void DestroyGLResources(gpu::raster::RasterInterface* gl);
+ void DestroyGLResources(gpu::raster::RasterInterface* gl,
+ gpu::SharedImageInterface* sii);
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
viz::ResourceFormat format,
bool is_free) const;
@@ -58,11 +62,11 @@ struct StagingBuffer {
// GpuMemoryBuffer.
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
- // Id for image used to import the GpuMemoryBuffer to command buffer.
- GLuint image_id = 0;
+ // Mailbox for the shared image bound to the GpuMemoryBuffer.
+ gpu::Mailbox mailbox;
- // Id for texture that's bound to the GpuMemoryBuffer image.
- GLuint texture_id = 0;
+ // Sync token for the last RasterInterface operations using the shared image.
+ gpu::SyncToken sync_token;
// Id of command buffer query that tracks use of this staging buffer by the
// GPU. In general, GPU synchronization is necessary for native
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
index 21010d76efd..b61b669e57e 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -9,16 +9,19 @@
#include <algorithm>
#include "base/macros.h"
+#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/resources/resource_pool.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/platform_color.h"
#include "components/viz/common/resources/resource_format_utils.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
+#include "gpu/command_buffer/common/shared_image_trace_utils.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -32,13 +35,12 @@ constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
public:
~ZeroCopyGpuBacking() override {
- gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
+ if (mailbox.IsZero())
+ return;
if (returned_sync_token.HasData())
- gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
- if (texture_id)
- gl->DeleteTextures(1, &texture_id);
- if (image_id)
- gl->DestroyImageCHROMIUM(image_id);
+ shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
+ else if (mailbox_sync_token.HasData())
+ shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
}
void OnMemoryDump(
@@ -52,16 +54,11 @@ class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
importance);
}
- // The ContextProvider used to clean up the texture and image ids.
- viz::ContextProvider* compositor_context_provider = nullptr;
+ // The SharedImageInterface used to clean up the shared image.
+ gpu::SharedImageInterface* shared_image_interface = nullptr;
// The backing for zero-copy gpu resources. The |texture_id| is bound to
// this.
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
- // The texture id bound to the GpuMemoryBuffer.
- uint32_t texture_id = 0;
- // The image id that associates the |gpu_memory_buffer| and the
- // |texture_id|.
- uint32_t image_id = 0;
};
// RasterBuffer for the zero copy upload, which is given to the raster worker
@@ -69,7 +66,6 @@ class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
class ZeroCopyRasterBufferImpl : public RasterBuffer {
public:
ZeroCopyRasterBufferImpl(
- viz::ContextProvider* context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const ResourcePool::InUsePoolResource& in_use_resource,
ZeroCopyGpuBacking* backing)
@@ -81,77 +77,33 @@ class ZeroCopyRasterBufferImpl : public RasterBuffer {
gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
~ZeroCopyRasterBufferImpl() override {
+ // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
+ // we don't have anything to give to the display compositor, so we report a
+ // zero mailbox that will result in checkerboarding.
+ if (!gpu_memory_buffer_) {
+ DCHECK(backing_->mailbox.IsZero());
+ return;
+ }
+
// This is destroyed on the compositor thread when raster is complete, but
// before the backing is prepared for export to the display compositor. So
// we can set up the texture and SyncToken here.
// TODO(danakj): This could be done with the worker context in Playback. Do
// we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
- gpu::gles2::GLES2Interface* gl =
- backing_->compositor_context_provider->ContextGL();
- const gpu::Capabilities& caps =
- backing_->compositor_context_provider->ContextCapabilities();
-
- if (backing_->returned_sync_token.HasData()) {
- gl->WaitSyncTokenCHROMIUM(backing_->returned_sync_token.GetConstData());
- backing_->returned_sync_token = gpu::SyncToken();
- }
-
- if (!backing_->texture_id) {
- // Make a texture and a mailbox for export of the GpuMemoryBuffer to the
- // display compositor.
- gl->GenTextures(1, &backing_->texture_id);
- backing_->texture_target = gpu::GetBufferTextureTarget(
- kBufferUsage, viz::BufferFormat(resource_format_), caps);
- gl->ProduceTextureDirectCHROMIUM(backing_->texture_id,
- backing_->mailbox.name);
- backing_->overlay_candidate = true;
- // This RasterBufferProvider will modify the resource outside of the
- // GL command stream. So resources should not become available for reuse
- // until they are not in use by the gpu anymore, which a fence is used to
- // determine.
- backing_->wait_on_fence_required = true;
-
- gl->BindTexture(backing_->texture_target, backing_->texture_id);
- gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MIN_FILTER,
- GL_LINEAR);
- gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MAG_FILTER,
- GL_LINEAR);
- gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
+ gpu::SharedImageInterface* sii = backing_->shared_image_interface;
+ if (backing_->mailbox.IsZero()) {
+ uint32_t usage =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ // Make a mailbox for export of the GpuMemoryBuffer to the display
+ // compositor.
+ backing_->mailbox = sii->CreateSharedImage(gpu_memory_buffer_.get(),
+ gpu_memory_buffer_manager_,
+ resource_color_space_, usage);
} else {
- gl->BindTexture(backing_->texture_target, backing_->texture_id);
+ sii->UpdateSharedImage(backing_->returned_sync_token, backing_->mailbox);
}
- if (!backing_->image_id) {
- // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
- // we don't have anything to give to the display compositor, but also no
- // way to report an error, so we just make a texture but don't bind
- // anything to it. Many blink layout tests on macOS fail to have no
- // |gpu_memory_buffer_| here, so any error reporting will spam console
- // logs (https://crbug.com/871031).
- if (gpu_memory_buffer_) {
- backing_->image_id = gl->CreateImageCHROMIUM(
- gpu_memory_buffer_->AsClientBuffer(), resource_size_.width(),
- resource_size_.height(), viz::GLInternalFormat(resource_format_));
- gl->BindTexImage2DCHROMIUM(backing_->texture_target,
- backing_->image_id);
- }
- } else {
- gl->ReleaseTexImage2DCHROMIUM(backing_->texture_target,
- backing_->image_id);
- gl->BindTexImage2DCHROMIUM(backing_->texture_target, backing_->image_id);
- }
- if (backing_->image_id && resource_color_space_.IsValid()) {
- gl->SetColorSpaceMetadataCHROMIUM(
- backing_->texture_id,
- reinterpret_cast<GLColorSpace>(&resource_color_space_));
- }
- gl->BindTexture(backing_->texture_target, 0);
-
- backing_->mailbox_sync_token =
- viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
+ backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken();
backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
}
@@ -225,15 +177,25 @@ ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
uint64_t previous_content_id) {
if (!resource.gpu_backing()) {
auto backing = std::make_unique<ZeroCopyGpuBacking>();
- backing->compositor_context_provider = compositor_context_provider_;
+ const gpu::Capabilities& caps =
+ compositor_context_provider_->ContextCapabilities();
+ backing->texture_target = gpu::GetBufferTextureTarget(
+ kBufferUsage, BufferFormat(resource.format()), caps);
+ backing->overlay_candidate = true;
+ // This RasterBufferProvider will modify the resource outside of the
+ // GL command stream. So resources should not become available for reuse
+ // until they are not in use by the gpu anymore, which a fence is used
+ // to determine.
+ backing->wait_on_fence_required = true;
+ backing->shared_image_interface =
+ compositor_context_provider_->SharedImageInterface();
resource.set_gpu_backing(std::move(backing));
}
ZeroCopyGpuBacking* backing =
static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
- return std::make_unique<ZeroCopyRasterBufferImpl>(
- compositor_context_provider_, gpu_memory_buffer_manager_, resource,
- backing);
+ return std::make_unique<ZeroCopyRasterBufferImpl>(gpu_memory_buffer_manager_,
+ resource, backing);
}
void ZeroCopyRasterBufferProvider::Flush() {}
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index 05d6fd97386..2e2fd3fab8f 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -16,6 +16,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/default_tick_clock.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "cc/base/container_util.h"
@@ -67,6 +68,7 @@ bool ResourceMeetsSizeRequirements(const gfx::Size& requested_size,
} // namespace
constexpr base::TimeDelta ResourcePool::kDefaultExpirationDelay;
+constexpr base::TimeDelta ResourcePool::kDefaultMaxFlushDelay;
void ResourcePool::GpuBacking::InitOverlayCandidateAndTextureTarget(
const viz::ResourceFormat format,
@@ -95,6 +97,8 @@ ResourcePool::ResourcePool(
resource_expiration_delay_(expiration_delay),
disallow_non_exact_reuse_(disallow_non_exact_reuse),
tracing_id_(g_next_tracing_id.GetNext()),
+ flush_evicted_resources_deadline_(base::TimeTicks::Max()),
+ clock_(base::DefaultTickClock::GetInstance()),
weak_ptr_factory_(this) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "cc::ResourcePool", task_runner_.get());
@@ -300,34 +304,40 @@ void ResourcePool::OnResourceReleased(size_t unique_id,
busy_resources_.erase(busy_it);
}
-void ResourcePool::PrepareForExport(const InUsePoolResource& resource) {
+bool ResourcePool::PrepareForExport(const InUsePoolResource& in_use_resource) {
+ PoolResource* resource = in_use_resource.resource_;
// Exactly one of gpu or software backing should exist.
- DCHECK(resource.resource_->gpu_backing() ||
- resource.resource_->software_backing());
- DCHECK(!resource.resource_->gpu_backing() ||
- !resource.resource_->software_backing());
+ DCHECK(resource->gpu_backing() || resource->software_backing());
+ DCHECK(!resource->gpu_backing() || !resource->software_backing());
viz::TransferableResource transferable;
- if (resource.resource_->gpu_backing()) {
+ if (resource->gpu_backing()) {
+ GpuBacking* gpu_backing = resource->gpu_backing();
+ if (gpu_backing->mailbox.IsZero()) {
+ // This can happen if we failed to allocate a GpuMemoryBuffer. Avoid
+ // sending an invalid resource to the parent in that case, and avoid
+ // caching/reusing the resource.
+ resource->set_resource_id(0);
+ resource->mark_avoid_reuse();
+ return false;
+ }
transferable = viz::TransferableResource::MakeGLOverlay(
- resource.resource_->gpu_backing()->mailbox, GL_LINEAR,
- resource.resource_->gpu_backing()->texture_target,
- resource.resource_->gpu_backing()->mailbox_sync_token,
- resource.resource_->size(),
- resource.resource_->gpu_backing()->overlay_candidate);
- transferable.read_lock_fences_enabled =
- resource.resource_->gpu_backing()->wait_on_fence_required;
+ gpu_backing->mailbox, GL_LINEAR, gpu_backing->texture_target,
+ gpu_backing->mailbox_sync_token, resource->size(),
+ gpu_backing->overlay_candidate);
+ transferable.read_lock_fences_enabled = gpu_backing->wait_on_fence_required;
} else {
transferable = viz::TransferableResource::MakeSoftware(
- resource.resource_->software_backing()->shared_bitmap_id,
- resource.resource_->size(), resource.resource_->format());
+ resource->software_backing()->shared_bitmap_id, resource->size(),
+ resource->format());
}
- transferable.format = resource.resource_->format();
- transferable.color_space = resource.resource_->color_space();
- resource.resource_->set_resource_id(resource_provider_->ImportResource(
+ transferable.format = resource->format();
+ transferable.color_space = resource->color_space();
+ resource->set_resource_id(resource_provider_->ImportResource(
std::move(transferable),
viz::SingleReleaseCallback::Create(base::BindOnce(
&ResourcePool::OnResourceReleased, weak_ptr_factory_.GetWeakPtr(),
- resource.resource_->unique_id()))));
+ resource->unique_id()))));
+ return true;
}
void ResourcePool::InvalidateResources() {
@@ -380,7 +390,7 @@ void ResourcePool::ReleaseResource(InUsePoolResource in_use_resource) {
// crbug.com/598286.
CHECK(it->second.get());
- pool_resource->set_last_usage(base::TimeTicks::Now());
+ pool_resource->set_last_usage(clock_->NowTicks());
in_use_memory_usage_bytes_ -=
viz::ResourceSizes::UncheckedSizeInBytes<size_t>(pool_resource->size(),
pool_resource->format());
@@ -458,6 +468,10 @@ void ResourcePool::DeleteResource(std::unique_ptr<PoolResource> resource) {
resource->size(), resource->format());
total_memory_usage_bytes_ -= resource_bytes;
--total_resource_count_;
+ if (flush_evicted_resources_deadline_ == base::TimeTicks::Max()) {
+ flush_evicted_resources_deadline_ =
+ clock_->NowTicks() + kDefaultMaxFlushDelay;
+ }
}
void ResourcePool::UpdateResourceContentIdAndInvalidation(
@@ -493,26 +507,27 @@ void ResourcePool::ScheduleEvictExpiredResourcesIn(
void ResourcePool::EvictExpiredResources() {
evict_expired_resources_pending_ = false;
- base::TimeTicks current_time = base::TimeTicks::Now();
+ base::TimeTicks current_time = clock_->NowTicks();
EvictResourcesNotUsedSince(current_time - resource_expiration_delay_);
- if (unused_resources_.empty()) {
+ if (unused_resources_.empty() ||
+ flush_evicted_resources_deadline_ <= current_time) {
// If nothing is evictable, we have deleted one (and possibly more)
// resources without any new activity. Flush to ensure these deletions are
// processed.
- if (context_provider_) {
- // Flush any ContextGL work as well as any SharedImageInterface work.
- context_provider_->ContextGL()->OrderingBarrierCHROMIUM();
- context_provider_->ContextSupport()->FlushPendingWork();
- }
- return;
+ FlushEvictedResources();
}
- // If we still have evictable resources, schedule a call to
- // EvictExpiredResources at the time when the LRU buffer expires.
- ScheduleEvictExpiredResourcesIn(GetUsageTimeForLRUResource() +
- resource_expiration_delay_ - current_time);
+ if (!unused_resources_.empty()) {
+ // If we still have evictable resources, schedule a call to
+ // EvictExpiredResources for either (a) the time when the LRU buffer expires
+ // or (b) the deadline to explicitly flush previously evicted resources.
+ ScheduleEvictExpiredResourcesIn(
+ std::min(GetUsageTimeForLRUResource() + resource_expiration_delay_,
+ flush_evicted_resources_deadline_) -
+ current_time);
+ }
}
void ResourcePool::EvictResourcesNotUsedSince(base::TimeTicks time_limit) {
@@ -538,6 +553,15 @@ base::TimeTicks ResourcePool::GetUsageTimeForLRUResource() const {
return busy_resources_.back()->last_usage();
}
+void ResourcePool::FlushEvictedResources() {
+ flush_evicted_resources_deadline_ = base::TimeTicks::Max();
+ if (context_provider_) {
+ // Flush any ContextGL work as well as any SharedImageInterface work.
+ context_provider_->ContextGL()->OrderingBarrierCHROMIUM();
+ context_provider_->ContextSupport()->FlushPendingWork();
+ }
+}
+
bool ResourcePool::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
@@ -572,6 +596,7 @@ void ResourcePool::OnMemoryPressure(
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
EvictResourcesNotUsedSince(base::TimeTicks() + base::TimeDelta::Max());
+ FlushEvictedResources();
break;
}
}
diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h
index b7928fcae8c..cd72eb84b7c 100644
--- a/chromium/cc/resources/resource_pool.h
+++ b/chromium/cc/resources/resource_pool.h
@@ -16,6 +16,7 @@
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/time/tick_clock.h"
#include "base/trace_event/memory_allocator_dump_guid.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/unguessable_token.h"
@@ -51,6 +52,9 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
// Delay before a resource is considered expired.
static constexpr base::TimeDelta kDefaultExpirationDelay =
base::TimeDelta::FromSeconds(5);
+ // Max delay before an evicted resource is flushed.
+ static constexpr base::TimeDelta kDefaultMaxFlushDelay =
+ base::TimeDelta::FromSeconds(1);
// A base class to hold ownership of gpu backed PoolResources. Allows the
// client to define destruction semantics.
@@ -217,7 +221,10 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
// acquired InUsePoolResource will be only metadata, and the backing is given
// to it by code which is aware of the expected backing type - currently by
// RasterBufferProvider::AcquireBufferForRaster().
- void PrepareForExport(const InUsePoolResource& resource);
+ // Returns false if the backing does not contain valid data, in particular
+ // a zero mailbox for GpuBacking, in which case the resource is not exported,
+ // and true otherwise.
+ bool PrepareForExport(const InUsePoolResource& resource);
// Marks any resources in the pool as invalid, preventing their reuse. Call if
// previous resources were allocated in one way, but future resources should
@@ -258,6 +265,9 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
return !disallow_non_exact_reuse_;
}
+ // Overrides internal clock for testing purposes.
+ void SetClockForTesting(const base::TickClock* clock) { clock_ = clock; }
+
private:
FRIEND_TEST_ALL_PREFIXES(ResourcePoolTest, ReuseResource);
FRIEND_TEST_ALL_PREFIXES(ResourcePoolTest, ExactRequestsRespected);
@@ -365,6 +375,7 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
void EvictResourcesNotUsedSince(base::TimeTicks time_limit);
bool HasEvictableResources() const;
base::TimeTicks GetUsageTimeForLRUResource() const;
+ void FlushEvictedResources();
viz::ClientResourceProvider* const resource_provider_;
viz::ContextProvider* const context_provider_;
@@ -391,6 +402,10 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+ base::TimeTicks flush_evicted_resources_deadline_;
+
+ const base::TickClock* clock_;
+
base::WeakPtrFactory<ResourcePool> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ResourcePool);
diff --git a/chromium/cc/resources/resource_pool_unittest.cc b/chromium/cc/resources/resource_pool_unittest.cc
index ef0ba34c2db..5f159541f0d 100644
--- a/chromium/cc/resources/resource_pool_unittest.cc
+++ b/chromium/cc/resources/resource_pool_unittest.cc
@@ -6,14 +6,16 @@
#include <stddef.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_task_runner_handle.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/common/resources/returned_resource.h"
#include "components/viz/test/test_context_provider.h"
+#include "components/viz/test/test_context_support.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -21,13 +23,17 @@ namespace cc {
class ResourcePoolTest : public testing::Test {
public:
void SetUp() override {
- context_provider_ = viz::TestContextProvider::Create();
+ auto context_support = std::make_unique<MockContextSupport>();
+ context_support_ = context_support.get();
+ context_provider_ =
+ viz::TestContextProvider::Create(std::move(context_support));
context_provider_->BindToCurrentThread();
resource_provider_ = std::make_unique<viz::ClientResourceProvider>(true);
- task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), context_provider_.get(), task_runner_,
+ resource_provider_.get(), context_provider_.get(), test_task_runner_,
ResourcePool::kDefaultExpirationDelay, false);
+ resource_pool_->SetClockForTesting(test_task_runner_->GetMockTickClock());
}
void TearDown() override {
@@ -35,6 +41,12 @@ class ResourcePoolTest : public testing::Test {
}
protected:
+ class MockContextSupport : public viz::TestContextSupport {
+ public:
+ MockContextSupport() = default;
+ MOCK_METHOD0(FlushPendingWork, void());
+ };
+
class StubGpuBacking : public ResourcePool::GpuBacking {
public:
void OnMemoryDump(
@@ -46,6 +58,7 @@ class ResourcePoolTest : public testing::Test {
void SetBackingOnResource(const ResourcePool::InUsePoolResource& resource) {
auto backing = std::make_unique<StubGpuBacking>();
+ backing->mailbox = gpu::Mailbox::Generate();
backing->mailbox_sync_token.Set(
gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(1), 1);
resource.set_gpu_backing(std::move(backing));
@@ -57,9 +70,10 @@ class ResourcePoolTest : public testing::Test {
}
viz::TestSharedBitmapManager shared_bitmap_manager_;
+ MockContextSupport* context_support_;
scoped_refptr<viz::TestContextProvider> context_provider_;
std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
std::unique_ptr<ResourcePool> resource_pool_;
};
@@ -76,6 +90,67 @@ TEST_F(ResourcePoolTest, AcquireRelease) {
resource_pool_->ReleaseResource(std::move(resource));
}
+TEST_F(ResourcePoolTest, EventuallyEvictAndFlush) {
+ gfx::Size size(100, 100);
+ viz::ResourceFormat format = viz::RGBA_8888;
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
+ ResourcePool::InUsePoolResource resource =
+ resource_pool_->AcquireResource(size, format, color_space);
+ resource_pool_->ReleaseResource(std::move(resource));
+ EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
+
+ // Expect flush after eviction and flush delay.
+ EXPECT_CALL(*context_support_, FlushPendingWork()).Times(testing::AtLeast(1));
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultExpirationDelay +
+ ResourcePool::kDefaultMaxFlushDelay);
+ EXPECT_EQ(0u, resource_pool_->GetTotalResourceCountForTesting());
+}
+
+TEST_F(ResourcePoolTest, FlushEvenIfMoreUnusedToEvict) {
+ gfx::Size size(100, 100);
+ viz::ResourceFormat format = viz::RGBA_8888;
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
+ ResourcePool::InUsePoolResource resource1 =
+ resource_pool_->AcquireResource(size, format, color_space);
+ ResourcePool::InUsePoolResource resource2 =
+ resource_pool_->AcquireResource(size, format, color_space);
+
+ // Time 0: No resources evicted yet.
+ EXPECT_EQ(2u, resource_pool_->GetTotalResourceCountForTesting());
+
+ // Space the resource last_usage out so that they don't expire at the same
+ // time. resource1 last used at time 0 (expires kDefaultExpirationDelay) and
+ // resource2 last used at last_usage_gap (expires kDefaultExpireationDelay +
+ // last_usage_gap).
+ const base::TimeDelta last_usage_gap =
+ ResourcePool::kDefaultMaxFlushDelay * 2;
+ resource_pool_->ReleaseResource(std::move(resource1));
+ test_task_runner_->FastForwardBy(last_usage_gap);
+ resource_pool_->ReleaseResource(std::move(resource2));
+
+ // Time |last_usage_gap|: No resources evicted yet.
+ EXPECT_EQ(2u, resource_pool_->GetTotalResourceCountForTesting());
+
+ // Time |kDefaultExpirationDelay|: resource1 evicted, but not resource2 yet.
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultExpirationDelay -
+ last_usage_gap);
+ EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
+
+ // Expect at least one flush kDefaultMaxFlushDelay after an eviction.
+ EXPECT_CALL(*context_support_, FlushPendingWork()).Times(testing::AtLeast(1));
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultMaxFlushDelay);
+
+ // Time |kDefaultExpirationDelay + kDefaultMaxFlushDelay|:
+ // Check that flush was called and resource2 still not evicted.
+ testing::Mock::VerifyAndClearExpectations(context_support_);
+ EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
+
+ // Wait a long time and resource2 should get evicted and flushed.
+ EXPECT_CALL(*context_support_, FlushPendingWork()).Times(testing::AtLeast(1));
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultExpirationDelay * 100);
+ EXPECT_EQ(0u, resource_pool_->GetTotalResourceCountForTesting());
+}
+
TEST_F(ResourcePoolTest, AccountingSingleResource) {
// Limits high enough to not be hit by this test.
size_t bytes_limit = 10 * 1024 * 1024;
@@ -165,7 +240,7 @@ TEST_F(ResourcePoolTest, LostResource) {
resource_pool_->AcquireResource(size, format, color_space);
SetBackingOnResource(resource);
- resource_pool_->PrepareForExport(resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(resource));
std::vector<viz::ResourceId> export_ids = {resource.resource_id_for_export()};
std::vector<viz::TransferableResource> transferable_resources;
@@ -183,12 +258,6 @@ TEST_F(ResourcePoolTest, LostResource) {
}
TEST_F(ResourcePoolTest, BusyResourcesNotFreed) {
- // Set a quick resource expiration delay so that this test doesn't take long
- // to run.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), context_provider_.get(), task_runner_,
- base::TimeDelta::FromMilliseconds(10), false);
-
// Limits high enough to not be hit by this test.
size_t bytes_limit = 10 * 1024 * 1024;
size_t count_limit = 100;
@@ -204,7 +273,7 @@ TEST_F(ResourcePoolTest, BusyResourcesNotFreed) {
EXPECT_EQ(1u, resource_pool_->resource_count());
SetBackingOnResource(resource);
- resource_pool_->PrepareForExport(resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(resource));
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
@@ -215,12 +284,9 @@ TEST_F(ResourcePoolTest, BusyResourcesNotFreed) {
EXPECT_EQ(0u, resource_pool_->memory_usage_bytes());
EXPECT_EQ(1u, resource_pool_->GetBusyResourceCountForTesting());
- // Wait for our resource pool to evict resources. We expect resources to be
- // released within 10 ms, give the thread up to 200.
- base::RunLoop run_loop;
- task_runner_->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMillisecondsD(200));
- run_loop.Run();
+ // Wait for our resource pool to evict resources. Wait 10x the expiration
+ // delay.
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultExpirationDelay * 10);
// Busy resources are still held, since they may be in flight to the display
// compositor and should not be freed.
@@ -230,12 +296,6 @@ TEST_F(ResourcePoolTest, BusyResourcesNotFreed) {
}
TEST_F(ResourcePoolTest, UnusedResourcesEventuallyFreed) {
- // Set a quick resource expiration delay so that this test doesn't take long
- // to run.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), context_provider_.get(), task_runner_,
- base::TimeDelta::FromMilliseconds(100), false);
-
// Limits high enough to not be hit by this test.
size_t bytes_limit = 10 * 1024 * 1024;
size_t count_limit = 100;
@@ -254,7 +314,7 @@ TEST_F(ResourcePoolTest, UnusedResourcesEventuallyFreed) {
// Export the resource to the display compositor.
SetBackingOnResource(resource);
- resource_pool_->PrepareForExport(resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(resource));
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
&transfers, context_provider_.get());
@@ -273,12 +333,9 @@ TEST_F(ResourcePoolTest, UnusedResourcesEventuallyFreed) {
EXPECT_EQ(0u, resource_pool_->resource_count());
EXPECT_EQ(0u, resource_pool_->GetBusyResourceCountForTesting());
- // Wait for our resource pool to evict resources. We expect resources to be
- // released within 100 ms, give the thread up to 200.
- base::RunLoop run_loop;
- task_runner_->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMillisecondsD(200));
- run_loop.Run();
+ // Wait for our resource pool to evict resources. Wait 10x the expiration
+ // delay.
+ test_task_runner_->FastForwardBy(ResourcePool::kDefaultExpirationDelay * 10);
EXPECT_EQ(0u, resource_pool_->GetTotalMemoryUsageForTesting());
}
@@ -463,7 +520,7 @@ TEST_F(ResourcePoolTest, PurgedMemory) {
ResourcePool::InUsePoolResource resource =
resource_pool_->AcquireResource(size, format, color_space);
SetBackingOnResource(resource);
- resource_pool_->PrepareForExport(resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(resource));
EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
EXPECT_EQ(0u, resource_pool_->GetBusyResourceCountForTesting());
@@ -516,7 +573,7 @@ TEST_F(ResourcePoolTest, InvalidateResources) {
ResourcePool::InUsePoolResource busy_resource =
resource_pool_->AcquireResource(size, format, color_space);
SetBackingOnResource(busy_resource);
- resource_pool_->PrepareForExport(busy_resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(busy_resource));
EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
EXPECT_EQ(0u, resource_pool_->GetBusyResourceCountForTesting());
EXPECT_EQ(1u, resource_pool_->resource_count());
@@ -582,8 +639,8 @@ TEST_F(ResourcePoolTest, ExactRequestsRespected) {
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), context_provider_.get(), task_runner_,
- base::TimeDelta::FromMilliseconds(100), true);
+ resource_provider_.get(), context_provider_.get(), test_task_runner_,
+ ResourcePool::kDefaultExpirationDelay, true);
// Create unused resource with size 100x100.
CheckAndReturnResource(resource_pool_->AcquireResource(gfx::Size(100, 100),
@@ -635,7 +692,7 @@ TEST_F(ResourcePoolTest, MetadataSentToDisplayCompositor) {
resource.gpu_backing()->wait_on_fence_required = true;
resource.gpu_backing()->overlay_candidate = true;
- resource_pool_->PrepareForExport(resource);
+ EXPECT_TRUE(resource_pool_->PrepareForExport(resource));
std::vector<viz::TransferableResource> transfer;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
@@ -657,4 +714,37 @@ TEST_F(ResourcePoolTest, MetadataSentToDisplayCompositor) {
resource_pool_->ReleaseResource(std::move(resource));
}
+TEST_F(ResourcePoolTest, InvalidResource) {
+ // Limits high enough to not be hit by this test.
+ size_t bytes_limit = 10 * 1024 * 1024;
+ size_t count_limit = 100;
+ resource_pool_->SetResourceUsageLimits(bytes_limit, count_limit);
+
+ // These values are all non-default values so we can tell they are propagated.
+ gfx::Size size(100, 101);
+ viz::ResourceFormat format = viz::RGBA_4444;
+ EXPECT_NE(gfx::BufferFormat::RGBA_8888, viz::BufferFormat(format));
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
+ uint32_t target = 5;
+
+ ResourcePool::InUsePoolResource resource =
+ resource_pool_->AcquireResource(size, format, color_space);
+
+ // Keep a zero mailbox
+ auto backing = std::make_unique<StubGpuBacking>();
+ backing->texture_target = target;
+ backing->wait_on_fence_required = true;
+ backing->overlay_candidate = true;
+ resource.set_gpu_backing(std::move(backing));
+
+ EXPECT_FALSE(resource_pool_->PrepareForExport(resource));
+
+ resource_pool_->ReleaseResource(std::move(resource));
+
+ // Acquire another resource. The resource should not be reused.
+ resource = resource_pool_->AcquireResource(size, format, color_space);
+ EXPECT_FALSE(resource.gpu_backing());
+ resource_pool_->ReleaseResource(std::move(resource));
+}
+
} // namespace cc
diff --git a/chromium/cc/scheduler/begin_frame_tracker.h b/chromium/cc/scheduler/begin_frame_tracker.h
index 33d124ad7e5..e80f7383768 100644
--- a/chromium/cc/scheduler/begin_frame_tracker.h
+++ b/chromium/cc/scheduler/begin_frame_tracker.h
@@ -10,7 +10,7 @@
#include "base/location.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/cc_export.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index fcdbde8a7c0..e930243b08e 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -10,7 +10,7 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/scheduler/compositor_timing_history.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
@@ -258,6 +258,7 @@ void Scheduler::StartOrStopBeginFrames() {
BeginImplFrameNotExpectedSoon();
devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
false);
+ client_->WillNotReceiveBeginFrame();
}
}
@@ -306,6 +307,16 @@ void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
bool Scheduler::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) {
TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
+ // If the begin frame interval is different than last frame and bigger than
+ // zero then let |client_| know about the new interval for animations. In
+ // theory the interval should always be bigger than zero but the value is
+ // provided by APIs outside our control.
+ if (args.interval != last_frame_interval_ &&
+ args.interval > base::TimeDelta()) {
+ last_frame_interval_ = args.interval;
+ client_->FrameIntervalUpdated(last_frame_interval_);
+ }
+
if (ShouldDropBeginFrame(args)) {
TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
TRACE_EVENT_SCOPE_THREAD);
@@ -729,10 +740,10 @@ void Scheduler::DrawForced() {
client_->CurrentFrameHadRAF(), client_->NextFrameHasPendingRAF());
}
-void Scheduler::SetDeferCommits(bool defer_commits) {
- TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", "defer_commits",
- defer_commits);
- state_machine_.SetDeferCommits(defer_commits);
+void Scheduler::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
+ TRACE_EVENT1("cc", "Scheduler::SetDeferMainFrameUpdate",
+ "defer_main_frame_update", defer_main_frame_update);
+ state_machine_.SetDeferMainFrameUpdate(defer_main_frame_update);
ProcessScheduledActions();
}
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index d042ec39883..06c32386641 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -40,6 +40,12 @@ class SchedulerClient {
const viz::BeginFrameArgs& args) = 0;
virtual DrawResult ScheduledActionDrawIfPossible() = 0;
virtual DrawResult ScheduledActionDrawForced() = 0;
+
+ // The Commit step occurs when the client received the BeginFrame from the
+ // source and we perform at most one commit per BeginFrame. In this step the
+ // main thread collects all updates then blocks and gives control to the
+ // compositor thread, which allows Compositor thread to update its layer tree
+ // to match the state of the layer tree on the main thread.
virtual void ScheduledActionCommit() = 0;
virtual void ScheduledActionActivateSyncTree() = 0;
virtual void ScheduledActionBeginLayerTreeFrameSinkCreation() = 0;
@@ -49,11 +55,13 @@ class SchedulerClient {
virtual void ScheduledActionPerformImplSideInvalidation() = 0;
virtual void DidFinishImplFrame() = 0;
virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack) = 0;
+ virtual void WillNotReceiveBeginFrame() = 0;
virtual void SendBeginMainFrameNotExpectedSoon() = 0;
virtual void ScheduledActionBeginMainFrameNotExpectedUntil(
base::TimeTicks time) = 0;
+ virtual void FrameIntervalUpdated(base::TimeDelta interval) = 0;
- // Functions used for reporting anmation targeting UMA, crbug.com/758439.
+ // Functions used for reporting animation targeting UMA, crbug.com/758439.
virtual size_t CompositedAnimationsCount() const = 0;
virtual size_t MainThreadAnimationsCount() const = 0;
virtual bool CurrentFrameHadRAF() const = 0;
@@ -88,10 +96,19 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
void SetVisible(bool visible);
bool visible() { return state_machine_.visible(); }
void SetCanDraw(bool can_draw);
+
+ // We have 2 copies of the layer trees on the compositor thread: pending_tree
+ // and active_tree. When we finish asynchronously rastering all tiles on
+ // pending_tree, call this method to notify that this pending tree is ready to
+ // be activated, that is to be copied to the active tree.
void NotifyReadyToActivate();
void NotifyReadyToDraw();
void SetBeginFrameSource(viz::BeginFrameSource* source);
+ // Set |needs_begin_main_frame_| to true, which will cause the BeginFrame
+ // source to be told to send BeginFrames to this client so that this client
+ // can send a CompositorFrame to the display compositor with appropriate
+ // timing.
void SetNeedsBeginMainFrame();
// Requests a single impl frame (after the current frame if there is one
// active).
@@ -123,12 +140,24 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
void SetTreePrioritiesAndScrollState(TreePriority tree_priority,
ScrollHandlerState scroll_handler_state);
+ // Commit step happens after the main thread has completed updating for a
+ // BeginMainFrame request from the compositor, and blocks the main thread
+ // to copy the layer tree to the compositor thread. Call this method when the
+ // main thread updates are completed to signal it is ready for the commmit.
void NotifyReadyToCommit();
void BeginMainFrameAborted(CommitEarlyOutReason reason);
void DidCommit();
+ // In the PrepareTiles step, compositor thread divides the layers into tiles
+ // to reduce cost of raster large layers. Then, each tile is rastered by a
+ // dedicated thread.
+ // |WillPrepareTiles| is called before PrepareTiles step to have the scheduler
+ // track when PrepareTiles starts.
void WillPrepareTiles();
+ // |DidPrepareTiles| is called after PrepareTiles step to have the scheduler
+ // track how long PrepareTiles takes.
void DidPrepareTiles();
+
void DidLoseLayerTreeFrameSink();
void DidCreateAndInitializeLayerTreeFrameSink();
@@ -156,7 +185,9 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
base::TimeTicks LastBeginImplFrameTime();
- void SetDeferCommits(bool defer_commits);
+ // Deferring BeginMainFrame prevents all document lifecycle updates, and
+ // compositor commits.
+ void SetDeferMainFrameUpdate(bool defer_main_frame_update);
// Controls whether the BeginMainFrameNotExpected messages should be sent to
// the main thread by the cc scheduler.
@@ -223,6 +254,10 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
bool stopped_ = false;
+ // Keeps track of the begin frame interval from the last BeginFrameArgs to
+ // arrive so that |client_| can be informed about changes.
+ base::TimeDelta last_frame_interval_;
+
private:
// Posts the deadline task if needed by checking
// SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode(). This only
diff --git a/chromium/cc/scheduler/scheduler_settings.cc b/chromium/cc/scheduler/scheduler_settings.cc
index de38d19ab87..9e488fc8725 100644
--- a/chromium/cc/scheduler/scheduler_settings.cc
+++ b/chromium/cc/scheduler/scheduler_settings.cc
@@ -4,7 +4,7 @@
#include "cc/scheduler/scheduler_settings.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
namespace cc {
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index d9711b24a86..57bd80ed57e 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -7,7 +7,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
namespace cc {
@@ -223,7 +223,7 @@ void SchedulerStateMachine::AsValueInto(
state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
skip_next_begin_main_frame_to_reduce_latency_);
state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_);
- state->SetBoolean("defer_commits", defer_commits_);
+ state->SetBoolean("defer_main_frame_update", defer_main_frame_update_);
state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_);
state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_);
state->SetBoolean("did_submit_in_last_frame", did_submit_in_last_frame_);
@@ -431,7 +431,7 @@ bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
return false;
// Do not make a new commits when it is deferred.
- if (defer_commits_)
+ if (defer_main_frame_update_)
return false;
return true;
@@ -714,8 +714,12 @@ bool SchedulerStateMachine::CouldCreatePendingTree() const {
if (begin_frame_source_paused_)
return false;
- // Don't create a pending tree till a frame sink is initialized.
- if (!HasInitializedLayerTreeFrameSink())
+ // Don't create a pending tree till a frame sink is fully initialized. Check
+ // for the ACTIVE state explicitly instead of calling
+ // HasInitializedLayerTreeFrameSink() because that only checks if frame sink
+ // has been recreated, but doesn't check if we're waiting for first commit or
+ // activation.
+ if (layer_tree_frame_sink_state_ != LayerTreeFrameSinkState::ACTIVE)
return false;
return true;
@@ -959,8 +963,9 @@ void SchedulerStateMachine::SetVideoNeedsBeginFrames(
video_needs_begin_frames_ = video_needs_begin_frames;
}
-void SchedulerStateMachine::SetDeferCommits(bool defer_commits) {
- defer_commits_ = defer_commits;
+void SchedulerStateMachine::SetDeferMainFrameUpdate(
+ bool defer_main_frame_update) {
+ defer_main_frame_update_ = defer_main_frame_update;
}
// These are the cases where we require a BeginFrame message to make progress
@@ -972,7 +977,7 @@ bool SchedulerStateMachine::BeginFrameRequiredForAction() const {
return true;
return needs_redraw_ || needs_one_begin_impl_frame_ ||
- (needs_begin_main_frame_ && !defer_commits_) ||
+ (needs_begin_main_frame_ && !defer_main_frame_update_) ||
needs_impl_side_invalidation_;
}
@@ -992,7 +997,8 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
// request frames when commits are disabled, because the frame requests will
// not provide the needed commit (and will wake up the process when it could
// stay idle).
- if ((begin_main_frame_state_ != BeginMainFrameState::IDLE) && !defer_commits_)
+ if ((begin_main_frame_state_ != BeginMainFrameState::IDLE) &&
+ !defer_main_frame_update_)
return true;
// If the pending tree activates quickly, we'll want a BeginImplFrame soon
@@ -1155,9 +1161,10 @@ bool SchedulerStateMachine::ShouldBlockDeadlineIndefinitely() const {
// Wait for main frame to be ready for commits if in full-pipe mode, so that
// we ensure we block during renderer initialization. In commit_to_active_tree
- // mode, we cannot block for defer_commits_, as this may negatively affect
- // animation smoothness during resize or orientation changes.
- if (defer_commits_ && settings_.wait_for_all_pipeline_stages_before_draw)
+ // mode, we cannot block for defer_main_frame_update_, as this may negatively
+ // affect animation smoothness during resize or orientation changes.
+ if (defer_main_frame_update_ &&
+ settings_.wait_for_all_pipeline_stages_before_draw)
return true;
// Wait for main frame if one is in progress or about to be started.
diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h
index bc1e83d472a..b3d2eea0d06 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.h
+++ b/chromium/cc/scheduler/scheduler_state_machine.h
@@ -295,7 +295,7 @@ class CC_EXPORT SchedulerStateMachine {
bool CouldSendBeginMainFrame() const;
- void SetDeferCommits(bool defer_commits);
+ void SetDeferMainFrameUpdate(bool defer_main_frame_update);
void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);
bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
@@ -417,7 +417,7 @@ class CC_EXPORT SchedulerStateMachine {
bool critical_begin_main_frame_to_activate_is_fast_ = true;
bool main_thread_missed_last_deadline_ = false;
bool skip_next_begin_main_frame_to_reduce_latency_ = false;
- bool defer_commits_ = false;
+ bool defer_main_frame_update_ = false;
bool video_needs_begin_frames_ = false;
bool last_commit_had_no_updates_ = false;
bool active_tree_is_ready_to_draw_ = true;
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index aa742f8a8a2..ca5ad89c12c 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -270,7 +270,7 @@ TEST(SchedulerStateMachineTest, BeginFrameNeeded) {
state.SetNeedsRedraw(false);
state.SetNeedsOneBeginImplFrame(false);
state.SetNeedsBeginMainFrameForTest(true);
- state.SetDeferCommits(true);
+ state.SetDeferMainFrameUpdate(true);
EXPECT_FALSE(state.BeginFrameNeeded());
}
@@ -1188,7 +1188,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
// When commits are deferred, we don't block the deadline.
- state.SetDeferCommits(true);
+ state.SetDeferMainFrameUpdate(true);
state.OnBeginImplFrame(0, 13, kAnimateOnly);
EXPECT_NE(SchedulerStateMachine::BeginImplFrameDeadlineMode::BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
@@ -2106,7 +2106,7 @@ TEST(SchedulerStateMachineTest, TestDeferCommit) {
StateMachine state(settings);
SET_UP_STATE(state)
- state.SetDeferCommits(true);
+ state.SetDeferMainFrameUpdate(true);
state.SetNeedsBeginMainFrame();
EXPECT_FALSE(state.BeginFrameNeeded());
@@ -2118,7 +2118,7 @@ TEST(SchedulerStateMachineTest, TestDeferCommit) {
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
- state.SetDeferCommits(false);
+ state.SetDeferMainFrameUpdate(false);
state.IssueNextBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
@@ -2310,24 +2310,63 @@ TEST(SchedulerStateMachineTest,
SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION);
}
-TEST(SchedulerStateMachineTest,
- NoImplSideInvalidationWithoutLayerTreeFrameSink) {
+TEST(SchedulerStateMachineTest, NoImplSideInvalidationUntilFrameSinkActive) {
SchedulerSettings settings;
StateMachine state(settings);
- SET_UP_STATE(state);
+ SET_UP_STATE(state)
+
+ // Prefer impl side invalidation over begin main frame.
+ state.set_should_defer_invalidation_for_fast_main_frame(false);
- // Impl-side invalidations should not be triggered till the frame sink is
- // initialized.
state.DidLoseLayerTreeFrameSink();
+
+ // Create new frame sink but don't commit or activate yet.
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION);
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
- // No impl-side invalidations should be performed during frame sink creation.
+ state.DidCreateAndInitializeLayerTreeFrameSink();
+ state.SetNeedsBeginMainFrame();
+
bool needs_first_draw_on_activation = true;
state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+
+ state.IssueNextBeginImplFrame();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+ // No impl side invalidation because we're still waiting for first commit.
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
+
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
+
+ state.OnBeginImplFrameDeadline();
+ state.OnBeginImplFrameIdle();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
+
+ state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+
state.IssueNextBeginImplFrame();
+ // No impl side invalidation because we're still waiting for first activation.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
+
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
+
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_IF_POSSIBLE);
+ state.OnBeginImplFrameIdle();
+
+ state.SetNeedsBeginMainFrame();
+ state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+
+ state.IssueNextBeginImplFrame();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
+ // Impl side invalidation only after receiving first commit and activation for
+ // new frame sink.
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION);
}
TEST(SchedulerStateMachineTest, ImplSideInvalidationWhenPendingTreeExists) {
@@ -2504,10 +2543,10 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
state.CurrentBeginImplFrameDeadlineMode());
// Even if main thread defers commits, we still need to wait for it.
- state.SetDeferCommits(true);
+ state.SetDeferMainFrameUpdate(true);
EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
- state.SetDeferCommits(false);
+ state.SetDeferMainFrameUpdate(false);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index aff1c76351c..715ecc43ca0 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -73,6 +73,8 @@ class FakeSchedulerClient : public SchedulerClient,
return posted_begin_impl_frame_deadline_;
}
+ base::TimeDelta frame_interval() const { return frame_interval_; }
+
int ActionIndex(const char* action) const {
for (size_t i = 0; i < actions_.size(); i++)
if (!strcmp(actions_[i], action))
@@ -128,6 +130,8 @@ class FakeSchedulerClient : public SchedulerClient,
last_begin_frame_ack_ = ack;
}
+ void WillNotReceiveBeginFrame() override {}
+
void ScheduledActionSendBeginMainFrame(
const viz::BeginFrameArgs& args) override {
EXPECT_FALSE(inside_action_);
@@ -135,6 +139,9 @@ class FakeSchedulerClient : public SchedulerClient,
PushAction("ScheduledActionSendBeginMainFrame");
last_begin_main_frame_args_ = args;
}
+ void FrameIntervalUpdated(base::TimeDelta interval) override {
+ frame_interval_ = interval;
+ }
const viz::BeginFrameArgs& last_begin_main_frame_args() {
return last_begin_main_frame_args_;
@@ -275,6 +282,7 @@ class FakeSchedulerClient : public SchedulerClient,
std::vector<std::unique_ptr<base::trace_event::ConvertableToTraceFormat>>
states_;
TestScheduler* scheduler_ = nullptr;
+ base::TimeDelta frame_interval_;
};
enum BeginFrameSourceType {
@@ -692,7 +700,7 @@ TEST_F(SchedulerTest, RequestCommit) {
TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
SetUpScheduler(EXTERNAL_BFS);
- scheduler_->SetDeferCommits(true);
+ scheduler_->SetDeferMainFrameUpdate(true);
scheduler_->SetNeedsBeginMainFrame();
EXPECT_NO_ACTION();
@@ -704,7 +712,7 @@ TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
EXPECT_FALSE(scheduler_->begin_frames_expected());
client_->Reset();
- scheduler_->SetDeferCommits(false);
+ scheduler_->SetDeferMainFrameUpdate(false);
EXPECT_ACTIONS("AddObserver(this)");
// Start new BeginMainFrame after defer commit is off.
@@ -717,13 +725,13 @@ TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
TEST_F(SchedulerTest, DeferCommitWithRedraw) {
SetUpScheduler(EXTERNAL_BFS);
- scheduler_->SetDeferCommits(true);
+ scheduler_->SetDeferMainFrameUpdate(true);
scheduler_->SetNeedsBeginMainFrame();
EXPECT_NO_ACTION();
- // The SetNeedsRedraw will override the SetDeferCommits(true), to allow a
- // begin frame to be needed.
+ // The SetNeedsRedraw will override the SetDeferMainFrameUpdate(true), to
+ // allow a begin frame to be needed.
client_->Reset();
scheduler_->SetNeedsRedraw();
EXPECT_ACTIONS("AddObserver(this)");
@@ -1492,6 +1500,63 @@ TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginFrame) {
"ScheduledActionDrawIfPossible");
}
+TEST_F(SchedulerTest, FrameIntervalUpdated) {
+ // Verify that the SchedulerClient gets updates when the begin frame interval
+ // changes.
+ SetUpScheduler(EXTERNAL_BFS);
+ constexpr uint64_t kSourceId = viz::BeginFrameArgs::kStartingSourceId;
+ uint64_t sequence_number = viz::BeginFrameArgs::kStartingFrameNumber;
+
+ base::TimeDelta interval = base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond / 120.0);
+
+ // Send BeginFrameArgs with 120hz refresh rate and confirm client gets update.
+ scheduler_->SetNeedsRedraw();
+ task_runner_->AdvanceMockTickClock(interval);
+ viz::BeginFrameArgs args1 = viz::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, kSourceId, sequence_number++,
+ task_runner_->NowTicks(), task_runner_->NowTicks() + interval, interval,
+ viz::BeginFrameArgs::NORMAL);
+ fake_external_begin_frame_source_->TestOnBeginFrame(args1);
+ EXPECT_EQ(client_->frame_interval(), interval);
+
+ // Send another BeginFrameArgs with 120hz refresh rate that arrives late. Even
+ // though the interval between begin frames arriving is bigger than |interval|
+ // the client only hears the interval specified in BeginFrameArgs.
+ scheduler_->SetNeedsRedraw();
+ const base::TimeDelta late_delta = base::TimeDelta::FromMilliseconds(4);
+ task_runner_->AdvanceMockTickClock(interval + late_delta);
+ viz::BeginFrameArgs args2 = viz::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args1.deadline,
+ args1.deadline + interval, interval, viz::BeginFrameArgs::NORMAL);
+ fake_external_begin_frame_source_->TestOnBeginFrame(args2);
+ EXPECT_EQ(client_->frame_interval(), interval);
+
+ // Change the interval for 90hz refresh rate.
+ interval = base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond / 90.0);
+
+ // Send BeginFrameArgs with 90hz refresh rate and confirm client gets update.
+ scheduler_->SetNeedsRedraw();
+ task_runner_->AdvanceMockTickClock(args2.deadline - task_runner_->NowTicks());
+ viz::BeginFrameArgs args3 = viz::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args2.deadline,
+ args2.deadline + interval, interval, viz::BeginFrameArgs::NORMAL);
+ fake_external_begin_frame_source_->TestOnBeginFrame(args3);
+ EXPECT_EQ(client_->frame_interval(), interval);
+
+ // Send BeginFrameArgs with zero interval. This isn't a valid interval and
+ // client shouldn't find out about it.
+ scheduler_->SetNeedsRedraw();
+ task_runner_->AdvanceMockTickClock(interval);
+ viz::BeginFrameArgs args4 = viz::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args3.deadline,
+ args3.deadline + interval, base::TimeDelta(),
+ viz::BeginFrameArgs::NORMAL);
+ fake_external_begin_frame_source_->TestOnBeginFrame(args4);
+ EXPECT_EQ(client_->frame_interval(), interval);
+}
+
TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) {
SetUpScheduler(EXTERNAL_BFS);
fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
@@ -3947,7 +4012,7 @@ TEST_F(SchedulerTest, WaitForAllPipelineStagesAlwaysObservesBeginFrames) {
EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
client_->Reset();
scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
- scheduler_->SetDeferCommits(true);
+ scheduler_->SetDeferMainFrameUpdate(true);
scheduler_->SetNeedsBeginMainFrame();
EXPECT_TRUE(scheduler_->begin_frames_expected());
EXPECT_FALSE(client_->IsInsideBeginImplFrame());
diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc
index 33385afc182..ce854bc73a1 100644
--- a/chromium/cc/tiles/checker_image_tracker.cc
+++ b/chromium/cc/tiles/checker_image_tracker.cc
@@ -387,7 +387,6 @@ void CheckerImageTracker::UpdateDecodeState(const DrawImage& draw_image,
std::max(decode_state->scale.fHeight, draw_image.scale().fHeight));
decode_state->filter_quality =
std::max(decode_state->filter_quality, draw_image.filter_quality());
- decode_state->color_space = draw_image.target_color_space();
decode_state->frame_index = draw_image.frame_index();
}
@@ -427,7 +426,7 @@ void CheckerImageTracker::ScheduleNextImageDecode() {
it->second.filter_quality,
SkMatrix::MakeScale(it->second.scale.width(),
it->second.scale.height()),
- it->second.frame_index, it->second.color_space);
+ it->second.frame_index);
outstanding_image_decode_.emplace(candidate);
break;
}
diff --git a/chromium/cc/tiles/checker_image_tracker.h b/chromium/cc/tiles/checker_image_tracker.h
index a8f850eb5cf..1a8229feaf5 100644
--- a/chromium/cc/tiles/checker_image_tracker.h
+++ b/chromium/cc/tiles/checker_image_tracker.h
@@ -136,7 +136,6 @@ class CC_EXPORT CheckerImageTracker {
DecodePolicy policy = DecodePolicy::SYNC;
SkFilterQuality filter_quality = kNone_SkFilterQuality;
SkSize scale = SkSize::MakeEmpty();
- gfx::ColorSpace color_space;
size_t frame_index = PaintImage::kDefaultFrameIndex;
};
diff --git a/chromium/cc/tiles/checker_image_tracker_unittest.cc b/chromium/cc/tiles/checker_image_tracker_unittest.cc
index 88c3f10cdd6..c375a591363 100644
--- a/chromium/cc/tiles/checker_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/checker_image_tracker_unittest.cc
@@ -125,7 +125,7 @@ class CheckerImageTrackerTest : public testing::Test,
.TakePaintImage(),
SkIRect::MakeWH(dimension, dimension),
kNone_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
+ PaintImage::kDefaultFrameIndex);
}
bool ShouldCheckerImage(const DrawImage& draw_image, WhichTree tree) {
@@ -433,8 +433,7 @@ TEST_F(CheckerImageTrackerTest, CheckersOnlyStaticCompletedImages) {
.set_paint_image_generator(CreatePaintImageGenerator(image_size))
.TakePaintImage(),
SkIRect::MakeWH(image_size.width(), image_size.height()),
- kNone_SkFilterQuality, SkMatrix::I(), PaintImage::kDefaultFrameIndex,
- gfx::ColorSpace());
+ kNone_SkFilterQuality, SkMatrix::I(), PaintImage::kDefaultFrameIndex);
EXPECT_FALSE(
ShouldCheckerImage(completed_paint_image, WhichTree::PENDING_TREE));
}
@@ -461,12 +460,10 @@ TEST_F(CheckerImageTrackerTest, ChoosesMaxScaleAndQuality) {
SetUpTracker(true);
DrawImage image = CreateImage(ImageType::CHECKERABLE);
- DrawImage scaled_image1(image, 0.5f, PaintImage::kDefaultFrameIndex,
- gfx::ColorSpace());
+ DrawImage scaled_image1(image, 0.5f, PaintImage::kDefaultFrameIndex);
DrawImage scaled_image2 =
DrawImage(image.paint_image(), image.src_rect(), kHigh_SkFilterQuality,
- SkMatrix::MakeScale(1.8f), PaintImage::kDefaultFrameIndex,
- gfx::ColorSpace());
+ SkMatrix::MakeScale(1.8f), PaintImage::kDefaultFrameIndex);
std::vector<DrawImage> draw_images = {scaled_image1, scaled_image2};
CheckerImageTracker::ImageDecodeQueue image_decode_queue =
@@ -541,7 +538,7 @@ TEST_F(CheckerImageTrackerTest, UseSrcRectForSize) {
DrawImage image = CreateImage(ImageType::CHECKERABLE);
image = DrawImage(image.paint_image(), SkIRect::MakeWH(200, 200),
image.filter_quality(), SkMatrix::I(),
- PaintImage::kDefaultFrameIndex, image.target_color_space());
+ PaintImage::kDefaultFrameIndex);
EXPECT_FALSE(ShouldCheckerImage(image, WhichTree::PENDING_TREE));
}
diff --git a/chromium/cc/tiles/decoded_image_tracker.cc b/chromium/cc/tiles/decoded_image_tracker.cc
index 9f717c9fc2a..ad1b297cfd7 100644
--- a/chromium/cc/tiles/decoded_image_tracker.cc
+++ b/chromium/cc/tiles/decoded_image_tracker.cc
@@ -38,7 +38,6 @@ DecodedImageTracker::~DecodedImageTracker() {
void DecodedImageTracker::QueueImageDecode(
const PaintImage& image,
- const gfx::ColorSpace& target_color_space,
const base::Callback<void(bool)>& callback) {
size_t frame_index = PaintImage::kDefaultFrameIndex;
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
@@ -49,7 +48,7 @@ void DecodedImageTracker::QueueImageDecode(
// our own.
auto image_bounds = SkIRect::MakeWH(image.width(), image.height());
DrawImage draw_image(image, image_bounds, kNone_SkFilterQuality,
- SkMatrix::I(), frame_index, target_color_space);
+ SkMatrix::I(), frame_index);
image_controller_->QueueImageDecode(
draw_image,
base::Bind(&DecodedImageTracker::ImageDecodeFinished,
diff --git a/chromium/cc/tiles/decoded_image_tracker.h b/chromium/cc/tiles/decoded_image_tracker.h
index 36f6dc35820..e16b614e48d 100644
--- a/chromium/cc/tiles/decoded_image_tracker.h
+++ b/chromium/cc/tiles/decoded_image_tracker.h
@@ -34,7 +34,6 @@ class CC_EXPORT DecodedImageTracker {
// completion. The callback takes a bool indicating whether the decode was
// successful or not.
void QueueImageDecode(const PaintImage& image,
- const gfx::ColorSpace& target_color_space,
const base::Callback<void(bool)>& callback);
// Unlock all locked images - used to respond to memory pressure or
diff --git a/chromium/cc/tiles/decoded_image_tracker_unittest.cc b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
index a31f5a2828b..4049261893f 100644
--- a/chromium/cc/tiles/decoded_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
@@ -86,44 +86,18 @@ class DecodedImageTrackerTest : public testing::Test {
TEST_F(DecodedImageTrackerTest, QueueImageLocksImages) {
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)),
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
}
-TEST_F(DecodedImageTrackerTest, Colorspace) {
- bool locked = false;
- gfx::ColorSpace decoded_color_space(
- gfx::ColorSpace::PrimaryID::XYZ_D50,
- gfx::ColorSpace::TransferID::IEC61966_2_1);
- gfx::ColorSpace srgb_color_space = gfx::ColorSpace::CreateSRGB();
- auto paint_image = CreateDiscardablePaintImage(gfx::Size(1, 1));
- decoded_image_tracker()->QueueImageDecode(
- paint_image, decoded_color_space,
- base::Bind([](bool* locked, bool success) { *locked = true; },
- base::Unretained(&locked)));
-
- // Check that the decoded color space images are locked, but if the color
- // space differs then that image is not locked. Note that we use the high
- // filter quality here, since it shouldn't matter and the checks should
- // succeed anyway.
- DrawImage locked_draw_image(
- paint_image, SkIRect::MakeWH(1, 1), kHigh_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex, decoded_color_space);
- EXPECT_TRUE(image_controller()->IsDrawImageLocked(locked_draw_image));
- DrawImage srgb_draw_image(paint_image, SkIRect::MakeWH(1, 1),
- kHigh_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex, srgb_color_space);
- EXPECT_FALSE(image_controller()->IsDrawImageLocked(srgb_draw_image));
-}
-
TEST_F(DecodedImageTrackerTest, ImagesTimeOut) {
// Add an image, this will start a 250ms timeout to release it.
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)),
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -135,7 +109,7 @@ 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)), gfx::ColorSpace(),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)),
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -156,7 +130,7 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
bool locked = false;
auto paint_image_1 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
- paint_image_1, gfx::ColorSpace(),
+ paint_image_1,
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -164,7 +138,7 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
auto paint_image_2 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
- paint_image_2, gfx::ColorSpace(),
+ paint_image_2,
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -172,11 +146,9 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
// Create dummy draw images for each:
DrawImage draw_image_1(paint_image_1, SkIRect::MakeWH(1, 1),
- kHigh_SkFilterQuality, SkMatrix::I(), 0,
- gfx::ColorSpace());
+ kHigh_SkFilterQuality, SkMatrix::I(), 0);
DrawImage draw_image_2(paint_image_2, SkIRect::MakeWH(1, 1),
- kHigh_SkFilterQuality, SkMatrix::I(), 0,
- gfx::ColorSpace());
+ kHigh_SkFilterQuality, SkMatrix::I(), 0);
// Both should be in the cache:
EXPECT_TRUE(image_controller()->IsDrawImageLocked(draw_image_1));
@@ -194,13 +166,13 @@ TEST_F(DecodedImageTrackerTest, UnlockAllImages) {
// Insert two images:
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)),
base::Bind([](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)), gfx::ColorSpace(),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)),
base::Bind([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
diff --git a/chromium/cc/tiles/frame_viewer_instrumentation.cc b/chromium/cc/tiles/frame_viewer_instrumentation.cc
index 09ac5b6857d..c941820294e 100644
--- a/chromium/cc/tiles/frame_viewer_instrumentation.cc
+++ b/chromium/cc/tiles/frame_viewer_instrumentation.cc
@@ -9,13 +9,10 @@
namespace cc {
namespace frame_viewer_instrumentation {
-const char kCategoryLayerTree[] =
- TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT(
- "viz.quads") "," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers");
-
namespace {
-const char kCategory[] = "cc," TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
+constexpr const char kCategory[] =
+ "cc," TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
const char kTileData[] = "tileData";
const char kLayerId[] = "layerId";
const char kTileId[] = "tileId";
@@ -69,7 +66,7 @@ ScopedRasterTask::~ScopedRasterTask() {
bool IsTracingLayerTreeSnapshots() {
bool category_enabled;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(kCategoryLayerTree, &category_enabled);
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(CategoryLayerTree(), &category_enabled);
return category_enabled;
}
diff --git a/chromium/cc/tiles/frame_viewer_instrumentation.h b/chromium/cc/tiles/frame_viewer_instrumentation.h
index d4cef013021..2f389bedbcb 100644
--- a/chromium/cc/tiles/frame_viewer_instrumentation.h
+++ b/chromium/cc/tiles/frame_viewer_instrumentation.h
@@ -12,7 +12,12 @@
namespace cc {
namespace frame_viewer_instrumentation {
-extern const char kCategoryLayerTree[];
+constexpr const char* CategoryLayerTree() {
+ // Declared as a constexpr function to have an external linkage and to be
+ // known at compile-time.
+ return TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT(
+ "viz.quads") "," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers");
+}
class ScopedAnalyzeTask {
public:
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 71550802821..6e3ae2ba974 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -320,24 +320,20 @@ GpuImageDecodeCache::InUseCacheKey::FromDrawImage(const DrawImage& draw_image) {
GpuImageDecodeCache::InUseCacheKey::InUseCacheKey(const DrawImage& draw_image)
: frame_key(draw_image.frame_key()),
upload_scale_mip_level(CalculateUploadScaleMipLevel(draw_image)),
- filter_quality(CalculateDesiredFilterQuality(draw_image)),
- target_color_space(draw_image.target_color_space()) {}
+ filter_quality(CalculateDesiredFilterQuality(draw_image)) {}
bool GpuImageDecodeCache::InUseCacheKey::operator==(
const InUseCacheKey& other) const {
return frame_key == other.frame_key &&
upload_scale_mip_level == other.upload_scale_mip_level &&
- filter_quality == other.filter_quality &&
- target_color_space == other.target_color_space;
+ filter_quality == other.filter_quality;
}
size_t GpuImageDecodeCache::InUseCacheKeyHash::operator()(
const InUseCacheKey& cache_key) const {
- return base::HashInts(
- cache_key.target_color_space.GetHash(),
- base::HashInts(cache_key.frame_key.hash(),
- base::HashInts(cache_key.upload_scale_mip_level,
- cache_key.filter_quality)));
+ return base::HashInts(cache_key.frame_key.hash(),
+ base::HashInts(cache_key.upload_scale_mip_level,
+ cache_key.filter_quality));
}
GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(
@@ -598,7 +594,6 @@ GpuImageDecodeCache::ImageData::ImageData(
PaintImage::Id paint_image_id,
DecodedDataMode mode,
size_t size,
- const gfx::ColorSpace& target_color_space,
SkFilterQuality quality,
int upload_scale_mip_level,
bool needs_mips,
@@ -606,7 +601,6 @@ GpuImageDecodeCache::ImageData::ImageData(
: paint_image_id(paint_image_id),
mode(mode),
size(size),
- target_color_space(target_color_space),
quality(quality),
upload_scale_mip_level(upload_scale_mip_level),
needs_mips(needs_mips),
@@ -668,7 +662,8 @@ GpuImageDecodeCache::GpuImageDecodeCache(
SkColorType color_type,
size_t max_working_set_bytes,
int max_texture_size,
- PaintImage::GeneratorClientId generator_client_id)
+ PaintImage::GeneratorClientId generator_client_id,
+ sk_sp<SkColorSpace> target_color_space)
: color_type_(color_type),
use_transfer_cache_(use_transfer_cache),
context_(context),
@@ -676,7 +671,8 @@ GpuImageDecodeCache::GpuImageDecodeCache(
generator_client_id_(generator_client_id),
persistent_cache_(PersistentCache::NO_AUTO_EVICT),
max_working_set_bytes_(max_working_set_bytes),
- max_working_set_items_(kMaxItemsInWorkingSet) {
+ max_working_set_items_(kMaxItemsInWorkingSet),
+ target_color_space_(std::move(target_color_space)) {
// In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
// Don't register a dump provider in these cases.
if (base::ThreadTaskRunnerHandle::IsSet()) {
@@ -734,6 +730,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
DecodeTaskType task_type) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::GetTaskForImageAndRef");
+
if (SkipImage(draw_image))
return TaskResult(false);
@@ -1114,10 +1111,13 @@ void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) {
gr_context_access.emplace(context_);
base::AutoLock lock(lock_);
- ImageData* image_data = GetImageDataForDrawImage(
- draw_image, InUseCacheKey::FromDrawImage(draw_image));
+ auto cache_key = InUseCacheKey::FromDrawImage(draw_image);
+ ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
DCHECK(image_data);
DCHECK(image_data->is_budgeted) << "Must budget an image for pre-decoding";
+
+ if (image_data->is_bitmap_backed)
+ DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster);
UploadImageIfNecessary(draw_image, image_data);
}
@@ -1183,7 +1183,8 @@ scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef(
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
DCHECK(image_data);
- if (image_data->decode.is_locked()) {
+ // No decode is necessary for bitmap backed images.
+ if (image_data->decode.is_locked() || image_data->is_bitmap_backed) {
// We should never be creating a decode task for a not budgeted image.
DCHECK(image_data->is_budgeted);
// We should never be creating a decode for an already-uploaded image.
@@ -1526,15 +1527,12 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
DCHECK_GT(image_data->decode.ref_count, 0u);
DCHECK_GT(image_data->upload.ref_count, 0u);
- sk_sp<SkColorSpace> target_color_space =
- SupportsColorSpaceConversion() &&
- draw_image.target_color_space().IsValid()
- ? draw_image.target_color_space().ToSkColorSpace()
- : nullptr;
- if (target_color_space &&
- SkColorSpace::Equals(target_color_space.get(),
+ sk_sp<SkColorSpace> color_space =
+ SupportsColorSpaceConversion() ? target_color_space_ : nullptr;
+ if (color_space &&
+ SkColorSpace::Equals(color_space.get(),
image_data->decode.image()->colorSpace())) {
- target_color_space = nullptr;
+ color_space = nullptr;
}
if (image_data->mode == DecodedDataMode::kTransferCache) {
@@ -1543,7 +1541,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
if (!image_data->decode.image()->peekPixels(&pixmap))
return;
- ClientImageTransferCacheEntry image_entry(&pixmap, target_color_space.get(),
+ ClientImageTransferCacheEntry image_entry(&pixmap, color_space.get(),
image_data->needs_mips);
size_t size = image_entry.SerializedSize();
void* data = context_->ContextSupport()->MapTransferCacheEntry(size);
@@ -1578,7 +1576,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
DCHECK(!use_transfer_cache_);
base::AutoUnlock unlock(lock_);
uploaded_image = MakeTextureImage(
- context_, std::move(uploaded_image), target_color_space,
+ context_, std::move(uploaded_image), color_space,
image_data->needs_mips ? GrMipMapped::kYes : GrMipMapped::kNo);
}
@@ -1657,7 +1655,6 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
!cache_color_conversion_on_cpu;
return base::WrapRefCounted(
new ImageData(draw_image.paint_image().stable_id(), mode, data_size,
- draw_image.target_color_space(),
CalculateDesiredFilterQuality(draw_image),
upload_scale_mip_level, needs_mips, is_bitmap_backed));
}
@@ -1884,10 +1881,6 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
image_data->upload_scale_mip_level;
bool quality_is_compatible =
CalculateDesiredFilterQuality(draw_image) <= image_data->quality;
- bool color_is_compatible =
- image_data->target_color_space == draw_image.target_color_space();
- if (!color_is_compatible)
- return false;
if (is_scaled && (!scale_is_compatible || !quality_is_compatible))
return false;
return true;
@@ -1970,7 +1963,7 @@ sk_sp<SkColorSpace> GpuImageDecodeCache::ColorSpaceForImageDecode(
return nullptr;
if (mode == DecodedDataMode::kCpu)
- return image.target_color_space().ToSkColorSpace();
+ return target_color_space_;
// For kGpu or kTransferCache images color conversion is handled during
// upload, so keep the original colorspace here.
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h
index dd21622a83d..a167341ecbe 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.h
+++ b/chromium/cc/tiles/gpu_image_decode_cache.h
@@ -106,7 +106,8 @@ class CC_EXPORT GpuImageDecodeCache
SkColorType color_type,
size_t max_working_set_bytes,
int max_texture_size,
- PaintImage::GeneratorClientId client_id);
+ PaintImage::GeneratorClientId client_id,
+ sk_sp<SkColorSpace> target_color_space);
~GpuImageDecodeCache() override;
// Returns the GL texture ID backing the given SkImage.
@@ -307,7 +308,6 @@ class CC_EXPORT GpuImageDecodeCache
ImageData(PaintImage::Id paint_image_id,
DecodedDataMode mode,
size_t size,
- const gfx::ColorSpace& target_color_space,
SkFilterQuality quality,
int upload_scale_mip_level,
bool needs_mips,
@@ -320,7 +320,6 @@ class CC_EXPORT GpuImageDecodeCache
const PaintImage::Id paint_image_id;
const DecodedDataMode mode;
const size_t size;
- gfx::ColorSpace target_color_space;
SkFilterQuality quality;
int upload_scale_mip_level;
bool needs_mips = false;
@@ -365,7 +364,6 @@ class CC_EXPORT GpuImageDecodeCache
PaintImage::FrameKey frame_key;
int upload_scale_mip_level;
SkFilterQuality filter_quality;
- gfx::ColorSpace target_color_space;
};
struct InUseCacheKeyHash {
size_t operator()(const InUseCacheKey&) const;
@@ -512,6 +510,7 @@ class CC_EXPORT GpuImageDecodeCache
std::vector<SkImage*> images_pending_complete_lock_;
std::vector<SkImage*> images_pending_unlock_;
std::vector<sk_sp<SkImage>> images_pending_deletion_;
+ const sk_sp<SkColorSpace> target_color_space_;
std::vector<uint32_t> ids_pending_unlock_;
std::vector<uint32_t> ids_pending_deletion_;
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
index 85a7f169741..11e0e09eeae 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -47,19 +47,20 @@ class GpuImageDecodeCachePerfTest
kTimeCheckInterval),
context_provider_(base::MakeRefCounted<TestInProcessContextProvider>(
UseTransferCache(),
- false /* support_locking */)),
- cache_(context_provider_.get(),
- UseTransferCache(),
- kRGBA_8888_SkColorType,
- kCacheSize,
- MaxTextureSize(),
- PaintImage::kDefaultGeneratorClientId) {
+ false /* support_locking */)) {
// Initializing context here is ok because image decode cache does not use
// context provider in its constructor.
gpu::ContextResult result = context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
}
+ void CreateCache(sk_sp<SkColorSpace> color_space = nullptr) {
+ cache_ = std::make_unique<GpuImageDecodeCache>(
+ context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType,
+ kCacheSize, MaxTextureSize(), PaintImage::kDefaultGeneratorClientId,
+ std::move(color_space));
+ }
+
protected:
size_t MaxTextureSize() const {
switch (GetParam()) {
@@ -88,7 +89,7 @@ class GpuImageDecodeCachePerfTest
LapTimer timer_;
scoped_refptr<TestInProcessContextProvider> context_provider_;
- GpuImageDecodeCache cache_;
+ std::unique_ptr<GpuImageDecodeCache> cache_;
};
INSTANTIATE_TEST_CASE_P(P,
@@ -98,6 +99,7 @@ INSTANTIATE_TEST_CASE_P(P,
TestMode::kSw));
TEST_P(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) {
+ CreateCache(gfx::ColorSpace::CreateXYZD50().ToSkColorSpace());
timer_.Reset();
do {
DrawImage image(
@@ -106,11 +108,10 @@ TEST_P(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) {
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u,
- gfx::ColorSpace::CreateXYZD50());
+ CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u);
- DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
- cache_.DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
+ cache_->DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -131,6 +132,7 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
context_provider_->GrContext(), SkBudgeted::kNo,
SkImageInfo::MakeN32Premul(2048, 2048));
+ CreateCache();
timer_.Reset();
do {
DrawImage image(
@@ -139,9 +141,9 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u, gfx::ColorSpace());
+ CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u);
- DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
+ DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
if (GetParam() == TestMode::kGpu) {
SkPaint paint;
@@ -152,7 +154,7 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
surface->prepareForExternalIO();
}
- cache_.DrawWithImageFinished(image, decoded_image);
+ cache_->DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -162,21 +164,21 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
TEST_P(GpuImageDecodeCachePerfTest, AcquireExistingImages) {
timer_.Reset();
+ CreateCache(gfx::ColorSpace::CreateXYZD50().ToSkColorSpace());
DrawImage image(
PaintImageBuilder::WithDefault()
.set_id(PaintImage::GetNextId())
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u,
- gfx::ColorSpace::CreateXYZD50());
+ CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u);
- DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
- cache_.DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
+ cache_->DrawWithImageFinished(image, decoded_image);
do {
- DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
- cache_.DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
+ cache_->DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index fc570ccbde2..526c1dd4aaf 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -273,10 +273,15 @@ class GpuImageDecodeCacheTest
}
std::unique_ptr<GpuImageDecodeCache> CreateCache() {
+ return CreateCache(DefaultColorSpace());
+ }
+
+ std::unique_ptr<GpuImageDecodeCache> CreateCache(
+ const gfx::ColorSpace& color_space) {
return std::make_unique<GpuImageDecodeCache>(
context_provider_.get(), use_transfer_cache_, color_type_,
kGpuMemoryLimitBytes, max_texture_size_,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace());
}
PaintImage CreatePaintImageInternal(
@@ -363,7 +368,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -372,7 +377,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -394,7 +399,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -403,7 +408,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -424,7 +429,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kHigh_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -432,8 +437,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -455,7 +459,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -466,7 +470,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
second_image,
SkIRect::MakeWH(second_image.width(), second_image.height()), quality,
CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -491,7 +495,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -505,7 +509,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -515,7 +519,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage third_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -537,7 +541,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -546,7 +550,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -556,7 +560,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage third_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -580,8 +584,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
PaintImage first_image = CreatePaintImageInternal(gfx::Size(100, 100));
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -594,8 +597,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -616,7 +618,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedAndLocked) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -658,7 +660,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedNotLocked) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -700,7 +702,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyUploaded) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -731,7 +733,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -774,7 +776,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -821,7 +823,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageUploadCanceledButDecodeRun) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -850,7 +852,7 @@ TEST_P(GpuImageDecodeCacheTest, NoTaskForImageAlreadyFailedDecoding) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -880,7 +882,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -912,7 +914,7 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -948,7 +950,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -982,7 +984,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -994,7 +996,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
DrawImage larger_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult larger_result = cache->GetTaskForImageAndRef(
larger_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(larger_result.need_unref);
@@ -1036,7 +1038,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
PaintImage image = CreatePaintImageInternal(gfx::Size(100, 100));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1047,8 +1049,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
DrawImage higher_quality_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult hq_result = cache->GetTaskForImageAndRef(
higher_quality_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(hq_result.need_unref);
@@ -1090,7 +1091,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawNegative) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(-0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1124,7 +1125,7 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeScaledDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1166,7 +1167,7 @@ TEST_P(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1207,7 +1208,7 @@ TEST_P(GpuImageDecodeCacheTest,
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1244,7 +1245,7 @@ TEST_P(GpuImageDecodeCacheTest,
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1281,7 +1282,7 @@ TEST_P(GpuImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1307,7 +1308,7 @@ TEST_P(GpuImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
DrawImage draw_image(
image, SkIRect::MakeXYWH(150, 150, image.width(), image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1333,7 +1334,7 @@ TEST_P(GpuImageDecodeCacheTest, CanceledTasksDoNotCountAgainstBudget) {
DrawImage draw_image(
image, SkIRect::MakeXYWH(0, 0, image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1359,7 +1360,7 @@ TEST_P(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
{
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
@@ -1421,7 +1422,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1436,7 +1437,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1469,7 +1470,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1488,7 +1489,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1512,10 +1513,9 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
// Create an image with kLow_FilterQuality.
- DrawImage low_draw_image(image,
- SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage low_draw_image(
+ image, SkIRect::MakeWH(image.width(), image.height()),
+ kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult low_result = cache->GetTaskForImageAndRef(
low_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(low_result.need_unref);
@@ -1525,8 +1525,7 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// should get a new task/ref.
DrawImage medium_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult medium_result = cache->GetTaskForImageAndRef(
medium_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(medium_result.need_unref);
@@ -1536,8 +1535,7 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// Get the same image at kHigh_FilterQuality. We should re-use medium.
DrawImage large_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult large_result = cache->GetTaskForImageAndRef(
large_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(large_result.need_unref);
@@ -1565,7 +1563,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1587,7 +1585,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
DrawImage draw_image_mips(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image_mips));
cache->DrawWithImageFinished(draw_image_mips, decoded_draw_image);
@@ -1601,7 +1599,7 @@ TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {
SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable);
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
@@ -1629,7 +1627,7 @@ TEST_P(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1680,13 +1678,13 @@ TEST_P(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
PaintImage image2 = CreatePaintImageInternal(gfx::Size(100, 100));
DrawImage draw_image2(
image2, SkIRect::MakeWH(image2.width(), image2.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// Add an image to the cache and un-ref it.
{
@@ -1763,7 +1761,7 @@ TEST_P(GpuImageDecodeCacheTest, ClearCache) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1793,7 +1791,7 @@ TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1818,65 +1816,17 @@ TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
EXPECT_EQ(cache->GetNumCacheEntriesForTesting(), 0u);
}
-TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentColorSpace) {
- auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
- gfx::ColorSpace color_space_a = gfx::ColorSpace::CreateSRGB();
- gfx::ColorSpace color_space_b = gfx::ColorSpace::CreateXYZD50();
-
- PaintImage first_image = CreatePaintImageInternal(gfx::Size(100, 100));
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_a);
- ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
- first_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(first_result.need_unref);
- EXPECT_TRUE(first_result.task);
-
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_b);
- ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
- second_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(second_result.need_unref);
- EXPECT_TRUE(second_result.task);
- EXPECT_TRUE(first_result.task.get() != second_result.task.get());
-
- DrawImage third_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_a);
- ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
- third_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(third_result.need_unref);
- EXPECT_TRUE(third_result.task.get() == first_result.task.get());
-
- TestTileTaskRunner::ProcessTask(first_result.task->dependencies()[0].get());
- TestTileTaskRunner::ProcessTask(first_result.task.get());
- TestTileTaskRunner::ProcessTask(second_result.task->dependencies()[0].get());
- TestTileTaskRunner::ProcessTask(second_result.task.get());
-
- cache->UnrefImage(first_draw_image);
- cache->UnrefImage(second_draw_image);
- cache->UnrefImage(third_draw_image);
-}
-
-TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {
+TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImage) {
auto cache = CreateCache();
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
// Create an image that's too large to cache.
PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1909,10 +1859,9 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- 1u, DefaultColorSpace());
+ DrawImage draw_image(
+ image, SkIRect::MakeWH(image.width(), image.height()), quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 1u);
auto decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -1922,8 +1871,7 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
cache->DrawWithImageFinished(draw_image, decoded_image);
// Scaled.
- DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
- draw_image.target_color_space());
+ DrawImage scaled_draw_image(draw_image, 0.5f, 2u);
decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(scaled_draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -1935,8 +1883,7 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
// Subset.
DrawImage subset_draw_image(
image, SkIRect::MakeWH(5, 5), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
- DefaultColorSpace());
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u);
decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(subset_draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -1956,7 +1903,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1970,7 +1917,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -2014,7 +1961,7 @@ TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2051,7 +1998,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// The image counts against our budget.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
@@ -2065,7 +2012,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
CreatePaintImageInternal(gfx::Size(100, 100)),
SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
@@ -2095,7 +2042,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// The image counts against our budget.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
@@ -2109,7 +2056,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
CreateDiscardablePaintImage(gfx::Size(100, 100)),
SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
@@ -2127,17 +2074,17 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringDecodeForLargeImageNonSRGBColorSpace) {
- auto cache = CreateCache();
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
+ auto cache = CreateCache(color_space);
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
// Create an image that's too large to upload.
PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2182,16 +2129,16 @@ TEST_P(GpuImageDecodeCacheTest,
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringUploadForSmallImageNonSRGBColorSpace) {
- auto cache = CreateCache();
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
+ auto cache = CreateCache(color_space);
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
PaintImage image = CreatePaintImageInternal(gfx::Size(11, 12));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2239,7 +2186,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2251,7 +2198,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
EXPECT_FALSE(cache->GetSWImageDecodeForTesting(draw_image));
}
-TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScaleTask) {
+TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskHasNoDeps) {
auto cache = CreateCache();
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
@@ -2260,19 +2207,41 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScaleTask) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
EXPECT_TRUE(result.task);
- TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ EXPECT_TRUE(result.task->dependencies().empty());
TestTileTaskRunner::ProcessTask(result.task.get());
cache->UnrefImage(draw_image);
}
-TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
+TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskCancelled) {
auto cache = CreateCache();
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ PaintImage image = CreateBitmapImageInternal(gfx::Size(10, 10));
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex);
+ auto result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ EXPECT_TRUE(result.task);
+ EXPECT_TRUE(result.task->dependencies().empty());
+ TestTileTaskRunner::CancelTask(result.task.get());
+ TestTileTaskRunner::CompleteTask(result.task.get());
+
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
+ auto color_space = gfx::ColorSpace::CreateDisplayP3D65();
+ auto cache = CreateCache(color_space);
const bool should_cache_sw_image =
cache->SupportsColorSpaceConversion() && !use_transfer_cache_;
@@ -2280,10 +2249,10 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(gfx::Size(10, 24000));
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, gfx::ColorSpace::CreateDisplayP3D65());
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex);
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2295,9 +2264,8 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
auto sw_image = cache->GetSWImageDecodeForTesting(draw_image);
ASSERT_EQ(!!sw_image, should_cache_sw_image);
if (should_cache_sw_image) {
- EXPECT_TRUE(SkColorSpace::Equals(
- sw_image->colorSpace(),
- gfx::ColorSpace::CreateDisplayP3D65().ToSkColorSpace().get()));
+ EXPECT_TRUE(SkColorSpace::Equals(sw_image->colorSpace(),
+ color_space.ToSkColorSpace().get()));
}
}
@@ -2310,7 +2278,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2341,7 +2309,7 @@ TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2393,7 +2361,7 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image1(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image1 =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image1));
ASSERT_TRUE(decoded_image1.image());
@@ -2430,7 +2398,7 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2446,15 +2414,16 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
TEST_P(GpuImageDecodeCacheTest, BasicMips) {
auto decode_and_check_mips = [this](SkFilterQuality filter_quality,
- SkSize scale, gfx::ColorSpace color_space,
+ SkSize scale,
+ const gfx::ColorSpace& color_space,
bool should_have_mips) {
- auto cache = CreateCache();
+ auto cache = CreateCache(color_space);
bool is_decomposable = true;
PaintImage image = CreatePaintImageInternal(gfx::Size(100, 100));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
filter_quality, CreateMatrix(scale, is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2515,7 +2484,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2552,7 +2521,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2601,7 +2570,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2632,7 +2601,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
diff --git a/chromium/cc/tiles/image_controller_unittest.cc b/chromium/cc/tiles/image_controller_unittest.cc
index dfa0bfc2750..473c7c25d5f 100644
--- a/chromium/cc/tiles/image_controller_unittest.cc
+++ b/chromium/cc/tiles/image_controller_unittest.cc
@@ -229,7 +229,7 @@ DrawImage CreateDiscardableDrawImage(gfx::Size size) {
return DrawImage(CreateDiscardablePaintImage(size),
SkIRect::MakeWH(size.width(), size.height()),
kNone_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
+ PaintImage::kDefaultFrameIndex);
}
DrawImage CreateBitmapDrawImage(gfx::Size size) {
diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc
index 13b5f9396f8..c16c0bb291b 100644
--- a/chromium/cc/tiles/picture_layer_tiling.cc
+++ b/chromium/cc/tiles/picture_layer_tiling.cc
@@ -15,7 +15,7 @@
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
#include "cc/raster/raster_source.h"
#include "cc/tiles/prioritized_tile.h"
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index d75e6e2001f..0dbd879ccf9 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -16,6 +16,7 @@
#include "cc/base/histograms.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/mipmap_util.h"
+#include "ui/gfx/color_space.h"
#include "ui/gfx/skia_util.h"
using base::trace_event::MemoryAllocatorDump;
@@ -140,8 +141,10 @@ void RecordLockExistingCachedImageHistogram(TilePriority::PriorityBin bin,
SoftwareImageDecodeCache::SoftwareImageDecodeCache(
SkColorType color_type,
size_t locked_memory_limit_bytes,
- PaintImage::GeneratorClientId generator_client_id)
+ PaintImage::GeneratorClientId generator_client_id,
+ sk_sp<SkColorSpace> target_color_space)
: decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
+ target_color_space_(std::move(target_color_space)),
locked_images_budget_(locked_memory_limit_bytes),
color_type_(color_type),
generator_client_id_(generator_client_id),
@@ -362,8 +365,9 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
// If we can use the original decode, we'll definitely need a decode.
if (key.type() == CacheKey::kOriginal) {
base::AutoUnlock release(lock_);
- local_cache_entry = Utils::DoDecodeImage(key, paint_image, color_type_,
- generator_client_id_);
+ local_cache_entry =
+ Utils::DoDecodeImage(key, paint_image, color_type_, target_color_space_,
+ generator_client_id_);
} else {
// Attempt to find a cached decode to generate a scaled/subrected decode
// from.
@@ -390,8 +394,9 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
DCHECK(!should_decode_to_scale || !key.is_nearest_neighbor());
if (should_decode_to_scale) {
base::AutoUnlock release(lock_);
- local_cache_entry = Utils::DoDecodeImage(key, paint_image, color_type_,
- generator_client_id_);
+ local_cache_entry =
+ Utils::DoDecodeImage(key, paint_image, color_type_,
+ target_color_space_, generator_client_id_);
}
// Couldn't decode to scale or find a cached candidate. Create the
@@ -416,9 +421,9 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
key.type() == CacheKey::kSubrectOriginal
? SkIRect::MakeWH(paint_image.width(), paint_image.height())
: gfx::RectToSkIRect(key.src_rect());
- DrawImage candidate_draw_image(
- paint_image, src_rect, kNone_SkFilterQuality, SkMatrix::I(),
- key.frame_key().frame_index(), key.target_color_space());
+ DrawImage candidate_draw_image(paint_image, src_rect,
+ kNone_SkFilterQuality, SkMatrix::I(),
+ key.frame_key().frame_index());
candidate_key.emplace(
CacheKey::FromDrawImage(candidate_draw_image, color_type_));
}
@@ -519,9 +524,7 @@ bool SoftwareImageDecodeCache::UseCacheForDrawImage(
// Cache images that need to be converted to a non-sRGB color space.
// TODO(ccameron): Consider caching when any color conversion is required.
// https://crbug.com/791828
- const gfx::ColorSpace& dst_color_space = draw_image.target_color_space();
- if (dst_color_space.IsValid() &&
- dst_color_space != gfx::ColorSpace::CreateSRGB()) {
+ if (target_color_space_ && !target_color_space_->isSRGB()) {
return true;
}
diff --git a/chromium/cc/tiles/software_image_decode_cache.h b/chromium/cc/tiles/software_image_decode_cache.h
index 30040d1da66..eb7cc161f1d 100644
--- a/chromium/cc/tiles/software_image_decode_cache.h
+++ b/chromium/cc/tiles/software_image_decode_cache.h
@@ -34,7 +34,8 @@ class CC_EXPORT SoftwareImageDecodeCache
SoftwareImageDecodeCache(SkColorType color_type,
size_t locked_memory_limit_bytes,
- PaintImage::GeneratorClientId generator_client_id);
+ PaintImage::GeneratorClientId generator_client_id,
+ sk_sp<SkColorSpace> target_color_space);
~SoftwareImageDecodeCache() override;
// ImageDecodeCache overrides.
@@ -150,6 +151,7 @@ class CC_EXPORT SoftwareImageDecodeCache
PaintImage::FrameKeyHash>
frame_key_to_image_keys_;
+ const sk_sp<SkColorSpace> target_color_space_;
MemoryBudget locked_images_budget_;
const SkColorType color_type_;
diff --git a/chromium/cc/tiles/software_image_decode_cache_perftest.cc b/chromium/cc/tiles/software_image_decode_cache_perftest.cc
index 64d79679c8b..5f693179b1c 100644
--- a/chromium/cc/tiles/software_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_perftest.cc
@@ -63,8 +63,7 @@ class SoftwareImageDecodeCachePerfTest : public testing::Test {
PaintImage::GetNextContentId())
.TakePaintImage(),
subrect, quality,
- CreateMatrix(SkSize::Make(scale.first, scale.second)), 0u,
- gfx::ColorSpace());
+ CreateMatrix(SkSize::Make(scale.first, scale.second)), 0u);
}
}
}
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest.cc b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
index abae6c64e6c..18f6d88444b 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
@@ -23,9 +23,13 @@ size_t kLockedMemoryLimitBytes = 128 * 1024 * 1024;
class TestSoftwareImageDecodeCache : public SoftwareImageDecodeCache {
public:
TestSoftwareImageDecodeCache()
+ : TestSoftwareImageDecodeCache(DefaultColorSpace()) {}
+
+ explicit TestSoftwareImageDecodeCache(const gfx::ColorSpace& color_space)
: SoftwareImageDecodeCache(kN32_SkColorType,
kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId) {}
+ PaintImage::kDefaultGeneratorClientId,
+ color_space.ToSkColorSpace()) {}
};
SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
@@ -54,7 +58,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyNoneQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kNone_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -76,7 +80,7 @@ TEST(SoftwareImageDecodeCacheTest,
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -94,7 +98,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropsToLowIfMipLevel0) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kMedium_SkFilterQuality,
CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -113,7 +117,7 @@ TEST(SoftwareImageDecodeCacheTest, LowUnscalableFormatStaysLow) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kARGB_4444_SkColorType);
@@ -132,7 +136,7 @@ TEST(SoftwareImageDecodeCacheTest, HighUnscalableFormatBecomesLow) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kHigh_SkFilterQuality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kARGB_4444_SkColorType);
@@ -151,7 +155,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityKeptLowIfUpscale) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -171,7 +175,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.4f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -190,7 +194,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfEnlarging) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -210,7 +214,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfIdentity) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -231,7 +235,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -252,7 +256,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -273,7 +277,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -294,7 +298,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_5Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -314,7 +318,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_0cale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -334,7 +338,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityAt0_75Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -354,7 +358,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_5Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -373,7 +377,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_49Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -392,7 +396,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_1Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -411,7 +415,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_01Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -431,7 +435,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.2f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -450,7 +454,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyUpscaleIsLowQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(2.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -473,7 +477,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToMediumIfTooLarge) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.45f, 0.45f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -493,7 +497,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -513,7 +517,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToLowIfIdentity) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -534,7 +538,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -555,7 +559,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -567,6 +571,41 @@ TEST(SoftwareImageDecodeCacheTest,
EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
}
+TEST(SoftwareImageDecodeCacheTest, ImageKeyDownscaleMipLevelWithRounding) {
+ // Tests that, when using a non-zero mip level, the final target size (which
+ // is the size of the chosen mip level) is as expected if rounding is
+ // required.
+ //
+ // The 97x61 dimensions and the (0.2f, 0.2f) scaling were chosen specifically
+ // so that:
+ //
+ // - The starting target size is 19x12 which means that 2 is the chosen mip
+ // level.
+ //
+ // - Attempting to get the final target size by simply multiplying the
+ // dimensions of the |src_rect| (97x61) times
+ // MipMapUtil::GetScaleAdjustmentForLevel() yields 24x15 if we attempt to
+ // store the result as integers. This is inconsistent with the rounding
+ // behavior introduced in https://crrev.com/c/1107049 and was the cause of
+ // https://crbug.com/891316.
+ PaintImage paint_image = CreatePaintImage(97, 61);
+ bool is_decomposable = true;
+ DrawImage draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ kMedium_SkFilterQuality,
+ CreateMatrix(SkSize::Make(0.2f, 0.2f), is_decomposable),
+ PaintImage::kDefaultFrameIndex);
+
+ auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
+ draw_image, kN32_SkColorType);
+ EXPECT_EQ(draw_image.frame_key(), key.frame_key());
+ EXPECT_FALSE(key.is_nearest_neighbor());
+ EXPECT_EQ(25, key.target_size().width());
+ EXPECT_EQ(16, key.target_size().height());
+ EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
+ EXPECT_EQ(25u * 16u * 4u, key.locked_bytes());
+}
+
TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
PaintImage paint_image = CreatePaintImage(100, 100);
bool is_decomposable = true;
@@ -575,7 +614,7 @@ TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -589,7 +628,7 @@ TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
DrawImage another_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto another_key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
another_draw_image, kN32_SkColorType);
@@ -612,7 +651,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRect) {
paint_image,
SkIRect::MakeXYWH(25, 35, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -633,7 +672,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRectWithScale) {
paint_image,
SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -654,7 +693,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -663,7 +702,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage another_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -684,7 +723,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageProcessUnrefCancel) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -714,7 +753,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kHigh_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult high_quality_result =
cache.GetTaskForImageAndRef(high_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -725,7 +764,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kNone_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult none_quality_result =
cache.GetTaskForImageAndRef(none_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -749,7 +788,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentSize) {
DrawImage half_size_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult half_size_result = cache.GetTaskForImageAndRef(
half_size_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(half_size_result.need_unref);
@@ -758,7 +797,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentSize) {
DrawImage quarter_size_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult quarter_size_result =
cache.GetTaskForImageAndRef(quarter_size_draw_image,
ImageDecodeCache::TracingInfo());
@@ -783,7 +822,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageDifferentImage) {
first_paint_image,
SkIRect::MakeWH(first_paint_image.width(), first_paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -794,75 +833,18 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageDifferentImage) {
second_paint_image,
SkIRect::MakeWH(second_paint_image.width(), second_paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
- ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
- second_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(second_result.need_unref);
- EXPECT_TRUE(second_result.task);
- EXPECT_TRUE(first_result.task.get() != second_result.task.get());
-
- TestTileTaskRunner::ProcessTask(first_result.task.get());
- TestTileTaskRunner::ProcessTask(second_result.task.get());
-
- cache.UnrefImage(first_draw_image);
- cache.UnrefImage(second_draw_image);
-}
-
-// crbug.com/709341
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_GetTaskForImageDifferentColorSpace \
- DISABLED_GetTaskForImageDifferentColorSpace
-#else
-#define MAYBE_GetTaskForImageDifferentColorSpace \
- GetTaskForImageDifferentColorSpace
-#endif
-TEST(SoftwareImageDecodeCacheTest, MAYBE_GetTaskForImageDifferentColorSpace) {
- TestSoftwareImageDecodeCache cache;
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
- gfx::ColorSpace color_space_a(gfx::ColorSpace::PrimaryID::XYZ_D50,
- gfx::ColorSpace::TransferID::IEC61966_2_1);
- gfx::ColorSpace color_space_b(gfx::ColorSpace::PrimaryID::SMPTE170M,
- gfx::ColorSpace::TransferID::IEC61966_2_1);
- gfx::ColorSpace color_space_c = gfx::ColorSpace::CreateSRGB();
-
- PaintImage paint_image = CreatePaintImage(100, 100, color_space_a);
- DrawImage first_draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_b);
- ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
- first_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(first_result.need_unref);
- EXPECT_TRUE(first_result.task);
-
- DrawImage second_draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_c);
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
EXPECT_TRUE(second_result.task);
EXPECT_TRUE(first_result.task.get() != second_result.task.get());
- DrawImage third_draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_b);
- ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
- third_draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(third_result.need_unref);
- EXPECT_TRUE(third_result.task);
- EXPECT_TRUE(first_result.task.get() == third_result.task.get());
-
TestTileTaskRunner::ProcessTask(first_result.task.get());
TestTileTaskRunner::ProcessTask(second_result.task.get());
cache.UnrefImage(first_draw_image);
cache.UnrefImage(second_draw_image);
- cache.UnrefImage(third_draw_image);
}
TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyDecoded) {
@@ -874,7 +856,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyDecoded) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -903,7 +885,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyPrerolled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -938,7 +920,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -979,7 +961,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1019,7 +1001,7 @@ TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDraw) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1052,7 +1034,7 @@ TEST(SoftwareImageDecodeCacheTest,
paint_image,
SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1083,7 +1065,7 @@ TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1108,7 +1090,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1138,7 +1120,7 @@ TEST(SoftwareImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1162,7 +1144,7 @@ TEST(SoftwareImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
paint_image,
SkIRect::MakeXYWH(150, 150, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1185,7 +1167,7 @@ TEST(SoftwareImageDecodeCacheTest, LowQualityFilterIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1213,7 +1195,7 @@ TEST(SoftwareImageDecodeCacheTest, LowQualityScaledSubrectIsHandled) {
PaintImage paint_image = CreatePaintImage(100, 100);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1246,7 +1228,7 @@ TEST(SoftwareImageDecodeCacheTest, NoneQualityScaledSubrectIsHandled) {
PaintImage paint_image = CreatePaintImage(100, 100);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1277,7 +1259,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt01_5ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1308,7 +1290,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt1_0ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1339,7 +1321,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_75ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1370,7 +1352,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_5ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1401,7 +1383,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_49ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1432,7 +1414,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_1ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1463,7 +1445,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_01ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1494,7 +1476,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_001ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.001f, 0.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1518,11 +1500,11 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image_50(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DrawImage draw_image_49(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result_50 = cache.GetTaskForImageAndRef(
draw_image_50, ImageDecodeCache::TracingInfo());
@@ -1569,7 +1551,7 @@ TEST(SoftwareImageDecodeCacheTest, ClearCache) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1604,10 +1586,9 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- 1u, DefaultColorSpace());
+ DrawImage draw_image(
+ image, SkIRect::MakeWH(image.width(), image.height()), quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 1u);
auto decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1616,8 +1597,7 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
cache.DrawWithImageFinished(draw_image, decoded_image);
// Scaled.
- DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
- draw_image.target_color_space());
+ DrawImage scaled_draw_image(draw_image, 0.5f, 2u);
decoded_image = cache.GetDecodedImageForDraw(scaled_draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1628,8 +1608,7 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
// Subset.
DrawImage subset_draw_image(
image, SkIRect::MakeWH(5, 5), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
- DefaultColorSpace());
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u);
decoded_image = cache.GetDecodedImageForDraw(subset_draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1649,7 +1628,7 @@ TEST(SoftwareImageDecodeCacheTest, SizeSubrectingIsHandled) {
DefaultColorSpace().ToSkColorSpace(), false);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(0, 0, 10, 10), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1682,7 +1661,7 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
gfx::Size(100, 100), DefaultColorSpace().ToSkColorSpace());
DrawImage draw_image(paint_image, SkIRect::MakeWH(100, 100), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
EXPECT_TRUE(decoded_draw_image.image());
@@ -1692,7 +1671,7 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
DrawImage empty_draw_image(
paint_image, SkIRect::MakeEmpty(), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage empty_decoded_draw_image =
cache.GetDecodedImageForDraw(empty_draw_image);
EXPECT_FALSE(empty_decoded_draw_image.image());
@@ -1700,16 +1679,16 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
}
TEST(SoftwareImageDecodeCacheTest, BitmapImageColorConverted) {
- TestSoftwareImageDecodeCache cache;
+ gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateDisplayP3D65();
+ TestSoftwareImageDecodeCache cache(target_color_space);
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateDisplayP3D65();
PaintImage paint_image = CreateBitmapImage(gfx::Size(100, 100));
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, target_color_space);
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1733,7 +1712,7 @@ TEST(SoftwareImageDecodeCacheTest, BitmapImageNotColorConverted) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
// The cache should not support this image.
EXPECT_FALSE(cache.UseCacheForDrawImage(draw_image));
@@ -1759,7 +1738,7 @@ TEST(SoftwareImageDecodeCacheTest, DISABLED_ContentIdCaching) {
paint_image,
SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
CreateMatrix(SkSize::Make(scale, scale), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
EXPECT_TRUE(decoded_draw_image.image());
@@ -1798,7 +1777,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image1(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image1 = cache.GetDecodedImageForDraw(draw_image1);
ASSERT_TRUE(decoded_image1.image());
EXPECT_EQ(decoded_image1.image()->width(), 50);
@@ -1815,7 +1794,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image2(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25, 0.25), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image2 = cache.GetDecodedImageForDraw(draw_image2);
ASSERT_TRUE(decoded_image2.image());
EXPECT_EQ(decoded_image2.image()->width(), 25);
@@ -1855,7 +1834,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScaleSubrect) {
// subrect vetoes decode to scale.
DrawImage draw_image(paint_image, SkIRect::MakeWH(50, 50), quality,
CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
EXPECT_EQ(decoded_image.image()->width(), 25);
@@ -1891,7 +1870,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScaleNoneQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage::kDefaultFrameIndex);
DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
EXPECT_EQ(decoded_image.image()->width(), 100);
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
index 5052a2a5d21..03d3e09e2f5 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
@@ -50,7 +50,7 @@ class BaseTest : public testing::Test {
? SkIRect::MakeWH(paint_image().width(), paint_image().height())
: src_rect,
kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(scale, scale), true),
- PaintImage::kDefaultFrameIndex, GetColorSpace());
+ PaintImage::kDefaultFrameIndex);
}
SoftwareImageDecodeCache& cache() { return *cache_; }
@@ -80,7 +80,8 @@ class N32Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kN32_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::kDefaultGeneratorClientId,
+ GetColorSpace().ToSkColorSpace());
}
};
@@ -89,7 +90,8 @@ class RGBA4444Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kARGB_4444_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::kDefaultGeneratorClientId,
+ GetColorSpace().ToSkColorSpace());
}
};
@@ -98,7 +100,8 @@ class RGBA_F16Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId);
+ PaintImage::kDefaultGeneratorClientId,
+ GetColorSpace().ToSkColorSpace());
}
};
@@ -135,9 +138,6 @@ class Predecode : public virtual BaseTest {
const DrawImage& draw_image,
const gfx::Size& expected_size) override {
auto decoded = cache().GetDecodedImageForDraw(draw_image);
- EXPECT_TRUE(SkColorSpace::Equals(
- decoded.image()->colorSpace(),
- draw_image.target_color_space().ToSkColorSpace().get()));
SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
EXPECT_EQ(decoded.image()->width(), expected_size.width());
EXPECT_EQ(decoded.image()->height(), expected_size.height());
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.cc b/chromium/cc/tiles/software_image_decode_cache_utils.cc
index 58bf110a3a6..16f5d11b30e 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.cc
@@ -59,6 +59,7 @@ SoftwareImageDecodeCacheUtils::DoDecodeImage(
const CacheKey& key,
const PaintImage& paint_image,
SkColorType color_type,
+ sk_sp<SkColorSpace> color_space,
PaintImage::GeneratorClientId client_id) {
SkISize target_size =
SkISize::Make(key.target_size().width(), key.target_size().height());
@@ -74,7 +75,7 @@ SoftwareImageDecodeCacheUtils::DoDecodeImage(
"SoftwareImageDecodeCacheUtils::DoDecodeImage - "
"decode");
bool result = paint_image.Decode(target_pixels->data(), &target_info,
- key.target_color_space().ToSkColorSpace(),
+ std::move(color_space),
key.frame_key().frame_index(), client_id);
if (!result) {
target_pixels->Unlock();
@@ -180,7 +181,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
// the filter quality doesn't matter. Early out instead.
if (target_size.IsEmpty()) {
return CacheKey(frame_key, stable_id, kSubrectAndScale, false, src_rect,
- target_size, image.target_color_space());
+ target_size);
}
ProcessingType type = kOriginal;
@@ -202,14 +203,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
} else {
type = kSubrectAndScale;
// Update the target size to be a mip level size.
- // TODO(vmpstr): MipMapUtil and JPEG decoders disagree on what to do with
- // odd sizes. If width = 2k + 1, and the mip level is 1, then this will
- // return width = k; JPEG decoder, however, will support decoding to width =
- // k + 1. We need to figure out what to do in this case.
- SkSize mip_scale_adjustment =
- MipMapUtil::GetScaleAdjustmentForLevel(src_rect.size(), mip_level);
- target_size.set_width(src_rect.width() * mip_scale_adjustment.width());
- target_size.set_height(src_rect.height() * mip_scale_adjustment.height());
+ target_size = MipMapUtil::GetSizeForLevel(src_rect.size(), mip_level);
}
// If the original image is large, we might want to do a subrect instead if
@@ -240,7 +234,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
}
return CacheKey(frame_key, stable_id, type, is_nearest_neighbor, src_rect,
- target_size, image.target_color_space());
+ target_size);
}
SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
@@ -249,15 +243,13 @@ SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
- const gfx::Size& target_size,
- const gfx::ColorSpace& target_color_space)
+ const gfx::Size& target_size)
: frame_key_(frame_key),
stable_id_(stable_id),
type_(type),
is_nearest_neighbor_(is_nearest_neighbor),
src_rect_(src_rect),
- target_size_(target_size),
- target_color_space_(target_color_space) {
+ target_size_(target_size) {
if (type == kOriginal) {
hash_ = frame_key_.hash();
} else {
@@ -274,8 +266,6 @@ SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash),
frame_key_.hash());
}
- // Include the target color space in the hash regardless of scaling.
- hash_ = base::HashInts(hash_, target_color_space.GetHash());
}
SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(const CacheKey& other) =
@@ -297,7 +287,6 @@ std::string SoftwareImageDecodeCacheUtils::CacheKey::ToString() const {
}
str << "]\nis_nearest_neightbor[" << is_nearest_neighbor_ << "]\nsrc_rect["
<< src_rect_.ToString() << "]\ntarget_size[" << target_size_.ToString()
- << "]\ntarget_color_space[" << target_color_space_.ToString()
<< "]\nhash[" << hash_ << "]";
return str.str();
}
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.h b/chromium/cc/tiles/software_image_decode_cache_utils.h
index 835d68c8492..42d7b0205ce 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.h
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.h
@@ -16,7 +16,6 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSize.h"
-#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -57,7 +56,6 @@ class SoftwareImageDecodeCacheUtils {
// image.
DCHECK(!is_nearest_neighbor_ || type_ == kOriginal);
return frame_key_ == other.frame_key_ && type_ == other.type_ &&
- target_color_space_ == other.target_color_space_ &&
(type_ == kOriginal || (src_rect_ == other.src_rect_ &&
target_size_ == other.target_size_));
}
@@ -70,9 +68,6 @@ class SoftwareImageDecodeCacheUtils {
bool is_nearest_neighbor() const { return is_nearest_neighbor_; }
gfx::Rect src_rect() const { return src_rect_; }
gfx::Size target_size() const { return target_size_; }
- const gfx::ColorSpace& target_color_space() const {
- return target_color_space_;
- }
size_t get_hash() const { return hash_; }
@@ -94,8 +89,7 @@ class SoftwareImageDecodeCacheUtils {
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
- const gfx::Size& size,
- const gfx::ColorSpace& target_color_space);
+ const gfx::Size& size);
PaintImage::FrameKey frame_key_;
// The stable id is does not factor into the cache key's value for hashing
@@ -106,7 +100,6 @@ class SoftwareImageDecodeCacheUtils {
bool is_nearest_neighbor_;
gfx::Rect src_rect_;
gfx::Size target_size_;
- gfx::ColorSpace target_color_space_;
size_t hash_;
};
@@ -186,6 +179,7 @@ class SoftwareImageDecodeCacheUtils {
const CacheKey& key,
const PaintImage& image,
SkColorType color_type,
+ sk_sp<SkColorSpace> color_space,
PaintImage::GeneratorClientId client_id);
static std::unique_ptr<CacheEntry> GenerateCacheEntryFromCandidate(
const CacheKey& key,
diff --git a/chromium/cc/tiles/tile.cc b/chromium/cc/tiles/tile.cc
index db0ba9f0177..96962c83b25 100644
--- a/chromium/cc/tiles/tile.cc
+++ b/chromium/cc/tiles/tile.cc
@@ -10,7 +10,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
#include "cc/tiles/tile_manager.h"
#include "components/viz/common/resources/resource_sizes.h"
diff --git a/chromium/cc/tiles/tile_draw_info.h b/chromium/cc/tiles/tile_draw_info.h
index aab93183734..993fcdc1c30 100644
--- a/chromium/cc/tiles/tile_draw_info.h
+++ b/chromium/cc/tiles/tile_draw_info.h
@@ -7,7 +7,7 @@
#include <memory>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/resources/resource_pool.h"
#include "components/viz/common/resources/platform_color.h"
#include "components/viz/common/resources/resource_format_utils.h"
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index 8f076724eb5..48e78c00e11 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -18,9 +18,9 @@
#include "base/metrics/histogram.h"
#include "base/numerics/safe_conversions.h"
#include "base/optional.h"
-#include "base/sys_info.h"
+#include "base/system/sys_info.h"
#include "base/threading/thread_checker.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/layers/picture_layer_impl.h"
@@ -682,8 +682,6 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(),
resource_pool_->resource_count());
- RasterColorSpace raster_color_space = client_->GetRasterColorSpace();
-
std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue(
client_->BuildRasterQueue(global_state_.tree_priority,
RasterTilePriorityQueue::Type::ALL));
@@ -736,8 +734,7 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
DCHECK(prioritized_tile.should_decode_checkered_images_for_tile());
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, raster_color_space.color_space,
- CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
continue;
}
@@ -793,15 +790,13 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
if (tile->raster_task_scheduled_with_checker_images() &&
prioritized_tile.should_decode_checkered_images_for_tile()) {
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, raster_color_space.color_space,
- CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
}
} else {
// Creating the raster task here will acquire resources, but
// this resource usage has already been accounted for above.
- auto raster_task = CreateRasterTask(
- prioritized_tile, client_->GetRasterColorSpace(), &work_to_schedule);
+ auto raster_task = CreateRasterTask(prioritized_tile, &work_to_schedule);
if (!raster_task) {
continue;
}
@@ -841,8 +836,7 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
if (tile->draw_info().is_checker_imaged() ||
tile->raster_task_scheduled_with_checker_images()) {
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, raster_color_space.color_space,
- CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
}
}
@@ -899,7 +893,6 @@ void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
void TileManager::PartitionImagesForCheckering(
const PrioritizedTile& prioritized_tile,
- const gfx::ColorSpace& raster_color_space,
std::vector<DrawImage>* sync_decoded_images,
std::vector<PaintImage>* checkered_images,
const gfx::Rect* invalidated_rect,
@@ -922,7 +915,7 @@ void TileManager::PartitionImagesForCheckering(
(*image_to_frame_index)[image.stable_id()] = frame_index;
DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
- frame_index, raster_color_space);
+ frame_index);
if (checker_image_tracker_.ShouldCheckerImage(draw_image, tree))
checkered_images->push_back(draw_image.paint_image());
else
@@ -932,7 +925,6 @@ void TileManager::PartitionImagesForCheckering(
void TileManager::AddCheckeredImagesToDecodeQueue(
const PrioritizedTile& prioritized_tile,
- const gfx::ColorSpace& raster_color_space,
CheckerImageTracker::DecodeType decode_type,
CheckerImageTracker::ImageDecodeQueue* image_decode_queue) {
Tile* tile = prioritized_tile.tile();
@@ -945,7 +937,7 @@ void TileManager::AddCheckeredImagesToDecodeQueue(
size_t frame_index = client_->GetFrameIndexForImage(
original_draw_image->paint_image(), tree);
DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
- frame_index, raster_color_space);
+ frame_index);
if (checker_image_tracker_.ShouldCheckerImage(draw_image, tree)) {
image_decode_queue->emplace_back(draw_image.paint_image(), decode_type);
}
@@ -981,9 +973,6 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
graph_.Reset();
- gfx::ColorSpace raster_color_space =
- client_->GetRasterColorSpace().color_space;
-
scoped_refptr<TileTask> required_for_activation_done_task =
CreateTaskSetFinishedTask(
&TileManager::DidFinishRunningTileTasksRequiredForActivation);
@@ -1038,9 +1027,8 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) {
std::vector<DrawImage> sync_decoded_images;
std::vector<PaintImage> checkered_images;
- PartitionImagesForCheckering(prioritized_tile, raster_color_space,
- &sync_decoded_images, &checkered_images,
- nullptr);
+ PartitionImagesForCheckering(prioritized_tile, &sync_decoded_images,
+ &checkered_images, nullptr);
// Add the sync decoded images to |new_locked_images| so they can be added
// to the task graph.
@@ -1132,7 +1120,6 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
scoped_refptr<TileTask> TileManager::CreateRasterTask(
const PrioritizedTile& prioritized_tile,
- const RasterColorSpace& raster_color_space,
PrioritizedWorkToSchedule* work_to_schedule) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"TileManager::CreateRasterTask");
@@ -1149,7 +1136,7 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
tile->id(), tile->invalidated_content_rect(), tile->invalidated_id(),
&invalidated_rect);
}
-
+ const RasterColorSpace& raster_color_space = client_->GetRasterColorSpace();
bool partial_tile_decode = false;
if (resource) {
resource_content_id = tile->invalidated_id();
@@ -1180,8 +1167,8 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
base::flat_map<PaintImage::Id, size_t> image_id_to_current_frame_index;
if (!skip_images) {
PartitionImagesForCheckering(
- prioritized_tile, raster_color_space.color_space, &sync_decoded_images,
- &checkered_images, partial_tile_decode ? &invalidated_rect : nullptr,
+ prioritized_tile, &sync_decoded_images, &checkered_images,
+ partial_tile_decode ? &invalidated_rect : nullptr,
&image_id_to_current_frame_index);
}
@@ -1243,7 +1230,6 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
}
PlaybackImageProvider image_provider(image_controller_.cache(),
- raster_color_space.color_space,
std::move(settings));
playback_settings.raster_color_space = raster_color_space;
@@ -1301,7 +1287,7 @@ void TileManager::OnRasterTaskCompleted(
// Once raster is done, allow the resource to be exported to the display
// compositor, by giving it a ResourceId.
- resource_pool_->PrepareForExport(resource);
+ bool exported = resource_pool_->PrepareForExport(resource);
// In SMOOTHNESS_TAKES_PRIORITY mode, we wait for GPU work to complete for a
// tile before setting it as ready to draw.
@@ -1312,11 +1298,16 @@ void TileManager::OnRasterTaskCompleted(
}
TileDrawInfo& draw_info = tile->draw_info();
- bool needs_swizzle = raster_buffer_provider_->IsResourceSwizzleRequired();
- bool is_premultiplied = raster_buffer_provider_->IsResourcePremultiplied();
- draw_info.SetResource(std::move(resource),
- raster_task_was_scheduled_with_checker_images,
- needs_swizzle, is_premultiplied);
+ if (exported) {
+ bool needs_swizzle = raster_buffer_provider_->IsResourceSwizzleRequired();
+ bool is_premultiplied = raster_buffer_provider_->IsResourcePremultiplied();
+ draw_info.SetResource(std::move(resource),
+ raster_task_was_scheduled_with_checker_images,
+ needs_swizzle, is_premultiplied);
+ } else {
+ resource_pool_->ReleaseResource(std::move(resource));
+ draw_info.set_oom();
+ }
if (raster_task_was_scheduled_with_checker_images)
num_of_tiles_with_checker_images_++;
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index e475cdf52b0..ac58ccfdc99 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -139,6 +139,9 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
~TileManager() override;
// Assigns tile memory and schedules work to prepare tiles for drawing.
+ // This step occurs after Commit and at most once per BeginFrame. It can be
+ // called on its own, that is, outside of Commit.
+ //
// - Runs client_->NotifyReadyToActivate() when all tiles required for
// activation are prepared, or failed to prepare due to OOM.
// - Runs client_->NotifyReadyToDraw() when all tiles required draw are
@@ -201,10 +204,12 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
// The raster here never really happened, cuz tests. So just add an
// arbitrary sync token.
if (resource.gpu_backing()) {
+ resource.gpu_backing()->mailbox = gpu::Mailbox::Generate();
resource.gpu_backing()->mailbox_sync_token.Set(
gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(1), 1);
}
- resource_pool_->PrepareForExport(resource);
+ bool exported = resource_pool_->PrepareForExport(resource);
+ DCHECK(exported);
draw_info.SetResource(std::move(resource), false, false, false);
draw_info.set_resource_ready_for_draw();
}
@@ -345,7 +350,6 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
scoped_refptr<TileTask> CreateRasterTask(
const PrioritizedTile& prioritized_tile,
- const RasterColorSpace& raster_color_space,
PrioritizedWorkToSchedule* work_to_schedule);
std::unique_ptr<EvictionTilePriorityQueue>
@@ -378,14 +382,12 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void PartitionImagesForCheckering(
const PrioritizedTile& prioritized_tile,
- const gfx::ColorSpace& raster_color_space,
std::vector<DrawImage>* sync_decoded_images,
std::vector<PaintImage>* checkered_images,
const gfx::Rect* invalidated_rect,
base::flat_map<PaintImage::Id, size_t>* image_to_frame_index = nullptr);
void AddCheckeredImagesToDecodeQueue(
const PrioritizedTile& prioritized_tile,
- const gfx::ColorSpace& raster_color_space,
CheckerImageTracker::DecodeType decode_type,
CheckerImageTracker::ImageDecodeQueue* image_decode_queue);
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 6c7fe87703b..7fbe4f370dd 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -2169,6 +2169,91 @@ TEST_F(TileManagerTest, PartialRasterSuccessfullyDisabled) {
RunPartialRasterCheck(TakeHostImpl(), false /* partial_raster_enabled */);
}
+class InvalidResourceRasterBufferProvider
+ : public FakeRasterBufferProviderImpl {
+ public:
+ std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+ const ResourcePool::InUsePoolResource& resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override {
+ if (!resource.gpu_backing()) {
+ auto backing = std::make_unique<StubGpuBacking>();
+ // Don't set a mailbox to signal invalid resource.
+ backing->texture_target = 5;
+ resource.set_gpu_backing(std::move(backing));
+ }
+ return std::make_unique<FakeRasterBuffer>();
+ }
+
+ private:
+ class StubGpuBacking : public ResourcePool::GpuBacking {
+ public:
+ void OnMemoryDump(
+ base::trace_event::ProcessMemoryDump* pmd,
+ const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
+ uint64_t tracing_process_id,
+ int importance) const override {}
+ };
+
+ class FakeRasterBuffer : public RasterBuffer {
+ public:
+ void Playback(const RasterSource* raster_source,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
+ const gfx::AxisTransform2d& transform,
+ const RasterSource::PlaybackSettings& playback_settings,
+ const GURL& url) override {}
+ };
+};
+
+class InvalidResourceTileManagerTest : public TileManagerTest {
+ protected:
+ std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override {
+ return FakeLayerTreeFrameSink::Create3d();
+ }
+};
+
+TEST_F(InvalidResourceTileManagerTest, InvalidResource) {
+ auto* tile_manager = host_impl()->tile_manager();
+ InvalidResourceRasterBufferProvider raster_buffer_provider;
+ tile_manager->SetRasterBufferProviderForTesting(&raster_buffer_provider);
+
+ gfx::Size size(10, 12);
+ FakePictureLayerTilingClient tiling_client;
+ tiling_client.SetTileSize(size);
+
+ std::unique_ptr<PictureLayerImpl> layer = PictureLayerImpl::Create(
+ host_impl()->active_tree(), 1, Layer::LayerMaskType::NOT_MASK);
+ layer->set_contributes_to_drawn_render_surface(true);
+
+ auto* tiling = layer->picture_layer_tiling_set()->AddTiling(
+ gfx::AxisTransform2d(), FakeRasterSource::CreateFilled(size));
+ tiling->set_resolution(HIGH_RESOLUTION);
+ tiling->CreateAllTilesForTesting();
+ tiling->SetTilePriorityRectsForTesting(gfx::Rect(size), // Visible rect.
+ gfx::Rect(size), // Skewport rect.
+ gfx::Rect(size), // Soon rect.
+ gfx::Rect(size)); // Eventually rect.
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+ tile_manager->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ tile_manager->CheckForCompletedTasks();
+
+ Tile* tile = tiling->TileAt(0, 0);
+ ASSERT_TRUE(tile);
+ // The tile in the tiling was rastered, but didn't get a resource.
+ EXPECT_TRUE(tile->draw_info().IsReadyToDraw());
+ EXPECT_EQ(TileDrawInfo::OOM_MODE, tile->draw_info().mode());
+
+ // Ensure that the host impl doesn't outlive |raster_buffer_provider|.
+ layer = nullptr;
+ TakeHostImpl();
+}
+
// FakeRasterBufferProviderImpl that allows us to mock ready to draw
// functionality.
class MockReadyToDrawRasterBufferProviderImpl
@@ -3280,9 +3365,9 @@ TEST_F(DecodedImageTrackerTileManagerTest, DecodedImageTrackerDropsLocksOnUse) {
// Add the images to our decoded_image_tracker.
host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
- image1, gfx::ColorSpace(), base::DoNothing());
+ image1, base::DoNothing());
host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
- image2, gfx::ColorSpace(), base::DoNothing());
+ image2, base::DoNothing());
EXPECT_EQ(0u, host_impl()
->tile_manager()
->decoded_image_tracker()
diff --git a/chromium/cc/tiles/tile_priority.cc b/chromium/cc/tiles/tile_priority.cc
index 0efe51e5972..7898163053e 100644
--- a/chromium/cc/tiles/tile_priority.cc
+++ b/chromium/cc/tiles/tile_priority.cc
@@ -5,7 +5,7 @@
#include "cc/tiles/tile_priority.h"
#include "base/numerics/safe_conversions.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
#include "cc/base/math_util.h"
diff --git a/chromium/cc/tiles/tile_priority.h b/chromium/cc/tiles/tile_priority.h
index 15746de6506..015b0c422ea 100644
--- a/chromium/cc/tiles/tile_priority.h
+++ b/chromium/cc/tiles/tile_priority.h
@@ -12,7 +12,7 @@
#include <memory>
#include <string>
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/cc_export.h"
namespace base {
diff --git a/chromium/cc/trees/clip_node.cc b/chromium/cc/trees/clip_node.cc
index c1a73a952c5..edeba2af9d0 100644
--- a/chromium/cc/trees/clip_node.cc
+++ b/chromium/cc/trees/clip_node.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/trace_event/trace_event_argument.h"
+#include "cc/trees/clip_node.h"
+
#include "cc/base/math_util.h"
#include "cc/layers/layer.h"
-#include "cc/trees/clip_node.h"
#include "cc/trees/property_tree.h"
+#include "base/trace_event/traced_value.h"
+
namespace cc {
ClipNode::ClipNode()
diff --git a/chromium/cc/trees/clip_node.h b/chromium/cc/trees/clip_node.h
index 5620f9d020c..54e554719e4 100644
--- a/chromium/cc/trees/clip_node.h
+++ b/chromium/cc/trees/clip_node.h
@@ -9,6 +9,7 @@
#include "base/optional.h"
#include "cc/cc_export.h"
#include "cc/trees/clip_expander.h"
+#include "cc/trees/property_tree.h"
#include "ui/gfx/geometry/rect_f.h"
namespace base {
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc
index 925069e0643..dded3612e22 100644
--- a/chromium/cc/trees/damage_tracker.cc
+++ b/chromium/cc/trees/damage_tracker.cc
@@ -64,7 +64,7 @@ void DamageTracker::UpdateDamageTracking(
//
// - This algorithm requires that descendant surfaces compute their damage
// before ancestor surfaces. Further, since contributing surfaces with
- // background filters can expand the damage caused by contributors
+ // backdrop filters can expand the damage caused by contributors
// underneath them (that is, before them in draw order), the exact damage
// caused by these contributors must be computed before computing the damage
// caused by the contributing surface. This is implemented by visiting
@@ -338,11 +338,11 @@ void DamageTracker::ExpandDamageInsideRectWithFilters(
if (!is_valid_rect || damage_rect.IsEmpty())
return;
- // Compute the pixels in the background of the surface that could be affected
+ // Compute the pixels in the backdrop of the surface that could be affected
// by the damage in the content below.
gfx::Rect expanded_damage_rect = filters.MapRect(damage_rect, SkMatrix::I());
- // Restrict it to the rectangle in which the background filter is shown.
+ // Restrict it to the rectangle in which the backdrop filter is shown.
expanded_damage_rect.Intersect(pre_filter_rect);
damage_for_this_update_.Union(expanded_damage_rect);
@@ -452,17 +452,16 @@ void DamageTracker::AccumulateDamageFromRenderSurface(
}
}
- // If the layer has a background filter, this may cause pixels in our surface
+ // If the layer has a backdrop filter, this may cause pixels in our surface
// to be expanded, so we will need to expand any damage at or below this
// layer. We expand the damage from this layer too, as we need to readback
// those pixels from the surface with only the contents of layers below this
// one in them. This means we need to redraw any pixels in the surface being
// used for the blur in this layer this frame.
- const FilterOperations& background_filters =
- render_surface->BackgroundFilters();
- if (background_filters.HasFilterThatMovesPixels()) {
+ const FilterOperations& backdrop_filters = render_surface->BackdropFilters();
+ if (backdrop_filters.HasFilterThatMovesPixels()) {
ExpandDamageInsideRectWithFilters(surface_rect_in_target_space,
- background_filters);
+ backdrop_filters);
}
// True if any changes from contributing render surface.
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index d4c755877c1..03d1e971600 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -924,7 +924,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) {
EXPECT_EQ(expected_child_damage_rect, child_damage_rect);
}
-TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
+TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces();
LayerImpl* child1 = root->test_properties()->children[0];
LayerImpl* child2 = root->test_properties()->children[1];
@@ -937,13 +937,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
// Setting the filter will damage the whole surface.
ClearDamageForAllSurfaces(root);
- child1->test_properties()->background_filters = filters;
+ child1->test_properties()->backdrop_filters = filters;
child1->NoteLayerPropertyChanged();
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
// CASE 1: Setting the update rect should cause the corresponding damage to
- // the surface, blurred based on the size of the child's background
+ // the surface, blurred based on the size of the child's backdrop
// blur filter. Note that child1's render surface has a size of
// 206x208 due to contributions from grand_child1 and grand_child2.
ClearDamageForAllSurfaces(root);
@@ -964,7 +964,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
// CASE 2: Setting the update rect should cause the corresponding damage to
- // the surface, blurred based on the size of the child's background
+ // the surface, blurred based on the size of the child's backdrop
// blur filter. Since the damage extends to the right/bottom outside
// of the blurred layer, only the left/top should end up expanded.
ClearDamageForAllSurfaces(root);
@@ -1053,7 +1053,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
// CASE 7: No changes, so should not damage the surface.
ClearDamageForAllSurfaces(root);
- // We want to make sure that the background filter doesn't cause empty damage
+ // We want to make sure that the backdrop filter doesn't cause empty damage
// to get expanded. We position child1 so that an expansion of the empty rect
// would have non-empty intersection with child1 in its target space (root
// space).
@@ -1791,7 +1791,7 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(5.f));
root->SetDrawsContent(true);
- root->test_properties()->background_filters = filters;
+ root->test_properties()->backdrop_filters = filters;
// Really far left.
child1->SetPosition(gfx::PointF(std::numeric_limits<int>::min() + 100, 0));
@@ -1917,7 +1917,7 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(5.f));
child1->SetDrawsContent(true);
- child1->test_properties()->background_filters = filters;
+ child1->test_properties()->backdrop_filters = filters;
// Really far left.
grandchild1->SetPosition(
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index 7c9b86cb096..ef8086d01d5 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -457,9 +457,14 @@ static inline bool LayerShouldBeSkippedInternal(
LayerType* layer,
const TransformTree& transform_tree,
const EffectTree& effect_tree) {
+ // TODO(enne): remove temporary CHECKs once http://crbug.com/898668 is fixed.
+ CHECK_NE(layer->transform_tree_index(), TransformTree::kInvalidNodeId);
const TransformNode* transform_node =
transform_tree.Node(layer->transform_tree_index());
+ CHECK(transform_node);
+ CHECK_NE(layer->effect_tree_index(), EffectTree::kInvalidNodeId);
const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
+ CHECK(effect_node);
if (effect_node->has_render_surface && effect_node->subtree_has_copy_request)
return false;
@@ -725,6 +730,9 @@ bool LayerShouldBeSkippedForDrawPropertiesComputation(
LayerImpl* layer,
const TransformTree& transform_tree,
const EffectTree& effect_tree) {
+ // TODO(enne): remove temporary CHECKs once http://crbug.com/898668 is fixed.
+ CHECK(layer);
+ CHECK(layer->layer_tree_impl());
return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree);
}
@@ -732,6 +740,11 @@ bool LayerShouldBeSkippedForDrawPropertiesComputation(
Layer* layer,
const TransformTree& transform_tree,
const EffectTree& effect_tree) {
+ // TODO(enne): remove temporary CHECKs once http://crbug.com/898668 is fixed.
+ CHECK(layer);
+ CHECK(layer->layer_tree_host());
+ CHECK_EQ(layer->layer_tree_host()->property_trees()->sequence_number,
+ layer->property_tree_sequence_number());
return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree);
}
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index 4bc3274497e..b0138a10a4a 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/layers/layer.h"
#include "cc/trees/effect_node.h"
+#include "base/trace_event/traced_value.h"
+#include "cc/layers/layer.h"
#include "cc/trees/property_tree.h"
namespace cc {
@@ -50,7 +50,7 @@ bool EffectNode::operator==(const EffectNode& other) const {
cache_render_surface == other.cache_render_surface &&
has_copy_request == other.has_copy_request &&
filters == other.filters &&
- background_filters == other.background_filters &&
+ backdrop_filters == other.backdrop_filters &&
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 72d0c062e17..0f8bf3399a6 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -39,7 +39,7 @@ struct CC_EXPORT EffectNode {
float screen_space_opacity;
FilterOperations filters;
- FilterOperations background_filters;
+ FilterOperations backdrop_filters;
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 0603ba726c7..95c79a7b19c 100644
--- a/chromium/cc/trees/element_id.cc
+++ b/chromium/cc/trees/element_id.cc
@@ -9,7 +9,7 @@
#include <ostream>
#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "base/values.h"
namespace cc {
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index edbdd247f15..15b3568a8cf 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -105,8 +105,11 @@ 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.
- virtual void SubmitCompositorFrame(viz::CompositorFrame frame) = 0;
+ // 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.
+ virtual void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool show_hit_test_borders) = 0;
// Signals that a BeginFrame issued by the viz::BeginFrameSource provided to
// the client did not lead to a CompositorFrame submission.
@@ -117,6 +120,10 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
const viz::SharedBitmapId& id) override = 0;
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0;
+ // Ensure next CompositorFrame is submitted to a new surface. Only used when
+ // surface synchronization is off.
+ virtual void ForceAllocateNewId() {}
+
protected:
class ContextLostForwarder;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index 87fc6b8b11e..b89a6e738c4 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -68,6 +68,9 @@ class CC_EXPORT LayerTreeFrameSinkClient {
// viz::ContextProviders) must be recreated.
virtual void DidLoseLayerTreeFrameSink() = 0;
+ // Notification that the client does not need a new BeginFrame.
+ virtual void DidNotNeedBeginFrame() = 0;
+
// For SynchronousCompositor (WebView) to ask the layer compositor to submit
// a new CompositorFrame synchronously.
virtual void OnDraw(const gfx::Transform& transform,
diff --git a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
index 355b818c48b..cd40a54d467 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
@@ -28,7 +28,8 @@ class StubLayerTreeFrameSink : public LayerTreeFrameSink {
std::move(compositor_task_runner),
nullptr) {}
- void SubmitCompositorFrame(viz::CompositorFrame frame) override {
+ void SubmitCompositorFrame(viz::CompositorFrame frame,
+ bool show_hit_test_borders) override {
client_->DidReceiveCompositorFrameAck();
}
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override {}
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index ecee592a25f..01ec4196d06 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -28,7 +28,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
@@ -120,7 +120,7 @@ LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode)
content_source_id_(0),
event_listener_properties_(),
mutator_host_(params.mutator_host),
- defer_commits_weak_ptr_factory_(this) {
+ defer_main_frame_update_weak_ptr_factory_(this) {
DCHECK(task_graph_runner_);
DCHECK(!settings_.enable_checker_imaging || image_worker_task_runner_);
@@ -173,15 +173,15 @@ void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) {
proxy_ = std::move(proxy);
proxy_->Start();
- UpdateDeferCommitsInternal();
+ UpdateDeferMainFrameUpdateInternal();
mutator_host_->SetSupportsScrollAnimations(proxy_->SupportsImplScrolling());
}
LayerTreeHost::~LayerTreeHost() {
// Track when we're inside a main frame to see if compositor is being
- // destroyed midway which causes a crash. crbug.com/654672
- DCHECK(!inside_main_frame_);
+ // destroyed midway which causes a crash. crbug.com/895883
+ CHECK(!inside_main_frame_);
TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
// Clear any references into the LayerTreeHost.
@@ -277,8 +277,8 @@ const LayerTreeDebugState& LayerTreeHost::GetDebugState() const {
return debug_state_;
}
-void LayerTreeHost::RequestMainFrameUpdate() {
- client_->UpdateLayerTreeHost();
+void LayerTreeHost::RequestMainFrameUpdate(bool record_main_frame_metrics) {
+ client_->UpdateLayerTreeHost(record_main_frame_metrics);
}
// This function commits the LayerTreeHost to an impl tree. When modifying
@@ -312,6 +312,7 @@ void LayerTreeHost::FinishCommitOnImplThread(
pending_presentation_time_callbacks_.push_back(base::DoNothing());
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);
@@ -376,22 +377,14 @@ void LayerTreeHost::FinishCommitOnImplThread(
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host=3
if (VLOG_IS_ON(3)) {
- VLOG(3) << "After finishing commit on impl, the sync tree:";
- // Because the property tree and layer list output can be verbose, the VLOG
- // output is split by line to avoid line buffer limits on android.
- VLOG(3) << "property trees:";
std::string property_trees;
base::JSONWriter::WriteWithOptions(
*sync_tree->property_trees()->AsTracedValue()->ToBaseValue(),
base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
- std::stringstream property_trees_stream(property_trees);
- for (std::string line; std::getline(property_trees_stream, line);)
- VLOG(3) << line;
-
- VLOG(3) << "layers:";
- std::stringstream layers_stream(host_impl->LayerListAsJson());
- for (std::string line; std::getline(layers_stream, line);)
- VLOG(3) << line;
+ VLOG(3) << "After finishing commit on impl, the sync tree:"
+ << "\nproperty_trees:\n"
+ << property_trees << "\nlayers:\n"
+ << host_impl->LayerListAsJson();
}
}
@@ -444,11 +437,11 @@ void LayerTreeHost::WillCommit() {
}
}
-
-void LayerTreeHost::UpdateDeferCommitsInternal() {
- proxy_->SetDeferCommits(defer_commits_count_ > 0 ||
- (settings_.enable_surface_synchronization &&
- !local_surface_id_from_parent_.is_valid()));
+void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() {
+ proxy_->SetDeferMainFrameUpdate(
+ defer_main_frame_update_count_ > 0 ||
+ (settings_.enable_surface_synchronization &&
+ !local_surface_id_allocation_from_parent_.IsValid()));
}
bool LayerTreeHost::IsUsingLayerLists() const {
@@ -534,23 +527,24 @@ void LayerTreeHost::DidLoseLayerTreeFrameSink() {
SetNeedsCommit();
}
-ScopedDeferCommits::ScopedDeferCommits(LayerTreeHost* host)
- : host_(host->defer_commits_weak_ptr_factory_.GetWeakPtr()) {
- host->defer_commits_count_++;
- host->UpdateDeferCommitsInternal();
+ScopedDeferMainFrameUpdate::ScopedDeferMainFrameUpdate(LayerTreeHost* host)
+ : host_(host->defer_main_frame_update_weak_ptr_factory_.GetWeakPtr()) {
+ host->defer_main_frame_update_count_++;
+ host->UpdateDeferMainFrameUpdateInternal();
}
-ScopedDeferCommits::~ScopedDeferCommits() {
+ScopedDeferMainFrameUpdate::~ScopedDeferMainFrameUpdate() {
LayerTreeHost* host = host_.get();
if (host) {
- DCHECK_GT(host->defer_commits_count_, 0u);
- if (--host->defer_commits_count_ == 0)
- host->UpdateDeferCommitsInternal();
+ DCHECK_GT(host->defer_main_frame_update_count_, 0u);
+ if (--host->defer_main_frame_update_count_ == 0)
+ host->UpdateDeferMainFrameUpdateInternal();
}
}
-std::unique_ptr<ScopedDeferCommits> LayerTreeHost::DeferCommits() {
- return std::make_unique<ScopedDeferCommits>(this);
+std::unique_ptr<ScopedDeferMainFrameUpdate>
+LayerTreeHost::DeferMainFrameUpdate() {
+ return std::make_unique<ScopedDeferMainFrameUpdate>(this);
}
DISABLE_CFI_PERF
@@ -656,7 +650,7 @@ void LayerTreeHost::LayoutAndUpdateLayers() {
DCHECK(IsSingleThreaded());
// This function is only valid when not using the scheduler.
DCHECK(!settings_.single_thread_proxy_scheduler);
- RequestMainFrameUpdate();
+ RequestMainFrameUpdate(false /* record_main_frame_metrics */);
UpdateLayers();
}
@@ -756,8 +750,6 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
// and SlimmingPaintV2.
if (!IsUsingLayerLists()) {
TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
Layer* root_scroll =
PropertyTreeBuilder::FindFirstScrollableLayer(root_layer);
Layer* page_scale_layer = viewport_layers_.page_scale.get();
@@ -813,33 +805,27 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
// --vmodule=layer_tree_host=3
// This only prints output for the renderer.
if (VLOG_IS_ON(3) && GetClientNameForMetrics() == std::string("Renderer")) {
- VLOG(3) << "After updating layers on the main thread:";
- // Because the property tree and layer list output can be verbose, the VLOG
- // output is split by line to avoid line buffer limits on android.
- VLOG(3) << "property trees:";
std::string property_trees;
base::JSONWriter::WriteWithOptions(
*property_trees_.AsTracedValue()->ToBaseValue(),
base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
- std::stringstream property_trees_stream(property_trees);
- for (std::string line; std::getline(property_trees_stream, line);)
- VLOG(3) << line;
-
- VLOG(3) << "layers:";
+ std::ostringstream layers;
for (auto* layer : *this) {
- VLOG(3) << " layer id " << layer->id();
- VLOG(3) << " element_id: " << layer->element_id();
- VLOG(3) << " bounds: " << layer->bounds().ToString();
- VLOG(3) << " opacity: " << layer->opacity();
- VLOG(3) << " position: " << layer->position().ToString();
- VLOG(3) << " draws_content: " << layer->DrawsContent();
- VLOG(3) << " scrollable: " << layer->scrollable();
- VLOG(3) << " contents_opaque: " << layer->contents_opaque();
- VLOG(3) << " transform_tree_index: " << layer->transform_tree_index();
- VLOG(3) << " clip_tree_index: " << layer->clip_tree_index();
- VLOG(3) << " effect_tree_index: " << layer->effect_tree_index();
- VLOG(3) << " scroll_tree_index: " << layer->scroll_tree_index();
+ 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();
}
bool painted_content_has_slow_paths = false;
@@ -869,23 +855,25 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
return did_paint_content;
}
-void LayerTreeHost::ApplyViewportDeltas(const ScrollAndScaleSet& info) {
- gfx::Vector2dF inner_viewport_scroll_delta;
+void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) {
+ gfx::ScrollOffset inner_viewport_scroll_delta;
if (info.inner_viewport_scroll.element_id)
inner_viewport_scroll_delta = info.inner_viewport_scroll.scroll_delta;
if (inner_viewport_scroll_delta.IsZero() && info.page_scale_delta == 1.f &&
- info.elastic_overscroll_delta.IsZero() && !info.top_controls_delta)
+ info.elastic_overscroll_delta.IsZero() && !info.top_controls_delta &&
+ !info.browser_controls_constraint_changed &&
+ !info.scroll_gesture_did_end) {
return;
+ }
// Preemptively apply the scroll offset and scale delta here before sending
// it to the client. If the client comes back and sets it to the same
// value, then the layer can early out without needing a full commit.
if (viewport_layers_.inner_viewport_scroll) {
viewport_layers_.inner_viewport_scroll->SetScrollOffsetFromImplSide(
- gfx::ScrollOffsetWithDelta(
- viewport_layers_.inner_viewport_scroll->CurrentScrollOffset(),
- inner_viewport_scroll_delta));
+ viewport_layers_.inner_viewport_scroll->CurrentScrollOffset() +
+ inner_viewport_scroll_delta);
}
ApplyPageScaleDeltaFromImplSide(info.page_scale_delta);
@@ -895,7 +883,8 @@ void LayerTreeHost::ApplyViewportDeltas(const ScrollAndScaleSet& info) {
// may be translated appropriately.
client_->ApplyViewportChanges(
{inner_viewport_scroll_delta, info.elastic_overscroll_delta,
- info.page_scale_delta, info.top_controls_delta});
+ info.page_scale_delta, info.top_controls_delta,
+ info.browser_controls_constraint, info.scroll_gesture_did_end});
SetNeedsUpdateLayers();
}
@@ -925,8 +914,8 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
Layer* layer = LayerByElementId(info->scrolls[i].element_id);
if (!layer)
continue;
- layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta(
- layer->CurrentScrollOffset(), info->scrolls[i].scroll_delta));
+ layer->SetScrollOffsetFromImplSide(layer->CurrentScrollOffset() +
+ info->scrolls[i].scroll_delta);
SetNeedsUpdateLayers();
}
for (size_t i = 0; i < info->scrollbars.size(); ++i) {
@@ -940,7 +929,7 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* 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.
- ApplyViewportDeltas(*info);
+ ApplyViewportChanges(*info);
RecordWheelAndTouchScrollingCount(*info);
}
@@ -1078,6 +1067,13 @@ void LayerTreeHost::RegisterViewportLayers(const ViewportLayers& layers) {
viewport_layers_.outer_viewport_scroll = layers.outer_viewport_scroll;
}
+void LayerTreeHost::RegisterViewportPropertyIds(
+ const ViewportPropertyIds& ids) {
+ DCHECK(!viewport_layers_.inner_viewport_scroll);
+ DCHECK(IsUsingLayerLists());
+ viewport_property_ids_ = ids;
+}
+
void LayerTreeHost::RegisterSelection(const LayerSelection& selection) {
if (selection_ == selection)
return;
@@ -1140,8 +1136,10 @@ void LayerTreeHost::SetEventListenerProperties(
void LayerTreeHost::SetViewportSizeAndScale(
const gfx::Size& device_viewport_size,
float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id_from_parent) {
- SetLocalSurfaceIdFromParent(local_surface_id_from_parent);
+ const viz::LocalSurfaceIdAllocation&
+ local_surface_id_allocation_from_parent) {
+ SetLocalSurfaceIdAllocationFromParent(
+ local_surface_id_allocation_from_parent);
bool changed = false;
if (device_viewport_size_ != device_viewport_size) {
@@ -1170,7 +1168,7 @@ void LayerTreeHost::SetViewportSizeAndScale(
// be.
CHECK(!has_pushed_local_surface_id_from_parent_ ||
new_local_surface_id_request_ ||
- !local_surface_id_from_parent_.is_valid());
+ !local_surface_id_allocation_from_parent_.IsValid());
#endif
}
}
@@ -1267,29 +1265,48 @@ void LayerTreeHost::SetRasterColorSpace(
this, [](Layer* layer) { layer->SetNeedsDisplay(); });
}
+void LayerTreeHost::SetExternalPageScaleFactor(float page_scale_factor) {
+ if (external_page_scale_factor_ == page_scale_factor)
+ return;
+
+ external_page_scale_factor_ = page_scale_factor;
+ SetNeedsCommit();
+}
+
void LayerTreeHost::SetContentSourceId(uint32_t id) {
content_source_id_ = id;
}
-void LayerTreeHost::SetLocalSurfaceIdFromParent(
- const viz::LocalSurfaceId& local_surface_id_from_parent) {
- if (local_surface_id_from_parent_.parent_sequence_number() ==
+void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent(
+ const viz::LocalSurfaceIdAllocation&
+ 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 =
+ 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() &&
- local_surface_id_from_parent_.embed_token() ==
+ 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.
+ DCHECK_EQ(local_surface_id_from_parent.is_valid(),
+ local_surface_id_allocation_from_parent.IsValid());
+
TRACE_EVENT_WITH_FLOW2(
TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
"LocalSurfaceId.Submission.Flow",
TRACE_ID_GLOBAL(local_surface_id_from_parent.submission_trace_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "SetLocalSurfaceIdFromParent", "local_surface_id",
- local_surface_id_from_parent.ToString());
- local_surface_id_from_parent_ = local_surface_id_from_parent;
+ "SetLocalSurfaceAllocationIdFromParent", "local_surface_id_allocation",
+ local_surface_id_allocation_from_parent.ToString());
+ local_surface_id_allocation_from_parent_ =
+ local_surface_id_allocation_from_parent;
has_pushed_local_surface_id_from_parent_ = false;
- UpdateDeferCommitsInternal();
+ UpdateDeferMainFrameUpdateInternal();
SetNeedsCommit();
}
@@ -1302,7 +1319,7 @@ void LayerTreeHost::RequestNewLocalSurfaceId() {
// viz::LocalSurfaceId but that request will be deferred until we have a valid
// viz::LocalSurfaceId from the parent.
DCHECK(settings_.enable_surface_synchronization ||
- local_surface_id_from_parent_.is_valid());
+ local_surface_id_allocation_from_parent_.IsValid());
if (new_local_surface_id_request_)
return;
new_local_surface_id_request_ = true;
@@ -1412,14 +1429,10 @@ void LayerTreeHost::UpdateHudLayer(bool show_hud_info) {
if (show_hud_info) {
if (!hud_layer_.get())
hud_layer_ = HeadsUpDisplayLayer::Create();
-
- gfx::Size device_viewport_in_layout_pixels =
- gfx::Size(device_viewport_size_.width() / device_scale_factor_,
- device_viewport_size_.height() / device_scale_factor_);
- hud_layer_->SetBounds(device_viewport_in_layout_pixels);
-
if (root_layer_.get() && !hud_layer_->parent())
root_layer_->AddChild(hud_layer_);
+ hud_layer_->UpdateLocationAndSize(device_viewport_size_,
+ device_scale_factor_);
} else if (hud_layer_.get()) {
hud_layer_->RemoveFromParent();
hud_layer_ = nullptr;
@@ -1483,6 +1496,8 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->ClearViewportLayers();
}
+ tree_impl->set_viewport_property_ids(viewport_property_ids_);
+
tree_impl->RegisterSelection(selection_);
tree_impl->PushPageScaleFromMainThread(
@@ -1499,6 +1514,7 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->elastic_overscroll()->PushPendingToActive();
tree_impl->SetRasterColorSpace(raster_color_space_id_, raster_color_space_);
+ tree_impl->SetExternalPageScaleFactor(external_page_scale_factor_);
tree_impl->set_content_source_id(content_source_id_);
@@ -1510,7 +1526,8 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
if (TakeNewLocalSurfaceIdRequest())
tree_impl->RequestNewLocalSurfaceId();
- tree_impl->SetLocalSurfaceIdFromParent(local_surface_id_from_parent_);
+ tree_impl->SetLocalSurfaceIdAllocationFromParent(
+ local_surface_id_allocation_from_parent_);
has_pushed_local_surface_id_from_parent_ = true;
if (pending_page_scale_animation_) {
@@ -1518,6 +1535,9 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
std::move(pending_page_scale_animation_));
}
+ if (TakeForceSendMetadataRequest())
+ tree_impl->RequestForceSendMetadata();
+
tree_impl->set_has_ever_been_drawn(false);
}
@@ -1549,6 +1569,7 @@ void LayerTreeHost::RegisterElement(ElementId element_id,
ElementListType list_type,
Layer* layer) {
element_layers_map_[element_id] = layer;
+ elements_in_property_trees_.insert(element_id);
mutator_host_->RegisterElement(element_id, list_type);
}
@@ -1556,6 +1577,27 @@ void LayerTreeHost::UnregisterElement(ElementId element_id,
ElementListType list_type) {
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) {
+ DCHECK(IsUsingLayerLists());
+
+ // Unregister ids that should no longer be registered.
+ 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);
+ }
+
+ // Register new ids that were not already registered.
+ for (const auto& id : ids) {
+ if (!elements_in_property_trees_.count(id)) {
+ elements_in_property_trees_.insert(id);
+ mutator_host_->RegisterElement(id, ElementListType::ACTIVE);
+ }
+ }
}
static void SetElementIdForTesting(Layer* layer) {
@@ -1577,6 +1619,10 @@ void LayerTreeHost::BuildPropertyTreesForTesting() {
bool LayerTreeHost::IsElementInList(ElementId element_id,
ElementListType list_type) const {
+ if (IsUsingLayerLists()) {
+ return list_type == ElementListType::ACTIVE &&
+ elements_in_property_trees_.count(element_id);
+ }
return list_type == ElementListType::ACTIVE && LayerByElementId(element_id);
}
@@ -1728,4 +1774,10 @@ void LayerTreeHost::SetRenderFrameObserver(
proxy_->SetRenderFrameObserver(std::move(observer));
}
+bool LayerTreeHost::TakeForceSendMetadataRequest() {
+ bool force_send_metadata_request = force_send_metadata_request_;
+ force_send_metadata_request_ = false;
+ return force_send_metadata_request;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index d2cd6ed1f5b..d35269410a8 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -44,6 +44,7 @@
#include "cc/trees/swap_promise_manager.h"
#include "cc/trees/target_property.h"
#include "components/viz/common/resources/resource_format.h"
+#include "components/viz/common/surfaces/local_surface_id_allocation.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/rect.h"
@@ -72,12 +73,12 @@ class UkmRecorderFactory;
struct RenderingStats;
struct ScrollAndScaleSet;
-// Returned from LayerTreeHost::DeferCommits. Automatically un-defers on
+// Returned from LayerTreeHost::DeferMainFrameUpdate. Automatically un-defers on
// destruction.
-class CC_EXPORT ScopedDeferCommits {
+class CC_EXPORT ScopedDeferMainFrameUpdate {
public:
- explicit ScopedDeferCommits(LayerTreeHost* host);
- ~ScopedDeferCommits();
+ explicit ScopedDeferMainFrameUpdate(LayerTreeHost* host);
+ ~ScopedDeferMainFrameUpdate();
private:
base::WeakPtr<LayerTreeHost> host_;
@@ -220,14 +221,16 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
bool CommitRequested() const;
// Prevents the compositor from requesting main frame updates from the client
- // until the ScopedDeferCommits object is destroyed, or StopDeferringCommits
- // is called.
- std::unique_ptr<ScopedDeferCommits> DeferCommits();
-
- // Returns whether there are any outstanding ScopedDeferCommits, though
- // commits may be deferred also when the local_surface_id_from_parent() is not
- // valid.
- bool defer_commits() const { return defer_commits_count_; }
+ // until the ScopedDeferMainFrameUpdate object is destroyed, or
+ // StopDeferringCommits is called.
+ std::unique_ptr<ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
+
+ // Returns whether there are any outstanding ScopedDeferMainFrameUpdate,
+ // though commits may be deferred also when the local_surface_id_from_parent()
+ // is not valid.
+ bool defer_main_frame_update() const {
+ return defer_main_frame_update_count_;
+ }
// Synchronously performs a main frame update and layer updates. Used only in
// single threaded mode when the compositor's internal scheduling is disabled.
@@ -330,6 +333,16 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return viewport_layers_.outer_viewport_scroll.get();
}
+ // Counterpart of ViewportLayers for CompositeAfterPaint which doesn't create
+ // viewport layers.
+ struct ViewportPropertyIds {
+ int page_scale_transform = TransformTree::kInvalidNodeId;
+ // TODO(crbug.com/909750): Switch other usages of viewport layers to
+ // property ids for CompositeAfterPaint.
+ };
+
+ void RegisterViewportPropertyIds(const ViewportPropertyIds&);
+
// Sets or gets the position of touch handles for a text selection. These are
// submitted to the display compositor along with the Layer tree's contents
// allowing it to present the selection handles. This is done because the
@@ -359,10 +372,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return event_listener_properties_[static_cast<size_t>(event_class)];
}
- void SetViewportSizeAndScale(
- const gfx::Size& device_viewport_size,
- float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id_from_parent);
+ void SetViewportSizeAndScale(const gfx::Size& device_viewport_size,
+ float device_scale_factor,
+ const viz::LocalSurfaceIdAllocation&
+ local_surface_id_allocation_from_parent);
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
@@ -409,10 +422,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// If this LayerTreeHost needs a valid viz::LocalSurfaceId then commits will
// be deferred until a valid viz::LocalSurfaceId is provided.
- void SetLocalSurfaceIdFromParent(
- const viz::LocalSurfaceId& local_surface_id_from_parent);
- const viz::LocalSurfaceId& local_surface_id_from_parent() const {
- return local_surface_id_from_parent_;
+ void SetLocalSurfaceIdAllocationFromParent(
+ const viz::LocalSurfaceIdAllocation&
+ local_surface_id_allocation_from_parent);
+
+ const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent()
+ const {
+ return local_surface_id_allocation_from_parent_;
}
// Requests the allocation of a new LocalSurfaceId on the compositor thread.
@@ -430,6 +446,20 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return raster_color_space_;
}
+ // This layer tree may be embedded in a hierarchy that has page scale
+ // factor controlled at the top level. We represent that scale here as
+ // 'external_page_scale_factor', a value that affects raster scale in the
+ // same way that page_scale_factor does, but doesn't affect any geometry
+ // calculations.
+ void SetExternalPageScaleFactor(float page_scale_factor);
+
+ // Requests that we force send RenderFrameMetadata with the next frame.
+ void RequestForceSendMetadata() { force_send_metadata_request_ = true; }
+
+ // Returns the state of |force_send_metadata_request_| and resets the
+ // variable to false.
+ bool TakeForceSendMetadataRequest();
+
// Used externally by blink for setting the PropertyTrees when
// UseLayerLists() is true, which also implies that Slimming Paint
// v2 is enabled.
@@ -470,8 +500,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void SetElasticOverscrollFromImplSide(gfx::Vector2dF elastic_overscroll);
gfx::Vector2dF elastic_overscroll() const { return elastic_overscroll_; }
- // Ensures a HUD layer exists if it is needed, and updates the layer bounds.
- // If a HUD layer exists but is no longer needed, it is destroyed.
+ // Ensures a HUD layer exists if it is needed, and updates the HUD bounds and
+ // position. If a HUD layer exists but is no longer needed, it is destroyed.
void UpdateHudLayer(bool show_hud_info);
HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); }
@@ -487,6 +517,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void PushPropertyTreesTo(LayerTreeImpl* tree_impl);
void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl);
+ // TODO(flackr): This list should be on the property trees and pushed
+ // as part of PushPropertyTreesTo.
+ void PushRegisteredElementIdsTo(LayerTreeImpl* tree_impl);
void PushSurfaceRangesTo(LayerTreeImpl* tree_impl);
void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl);
@@ -497,6 +530,17 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
ElementListType list_type,
Layer* layer);
void UnregisterElement(ElementId element_id, ElementListType list_type);
+
+ // Registers the new active element ids, updating |registered_element_ids_|,
+ // and unregisters any element ids that were previously registered. This is
+ // similar to |RegisterElement| and |UnregisterElement| but for layer lists
+ // where we do not have a unique element id to layer mapping.
+ using ElementIdSet = std::unordered_set<ElementId, ElementIdHash>;
+ void SetActiveRegisteredElementIds(const ElementIdSet&);
+ const ElementIdSet& elements_in_property_trees() {
+ return elements_in_property_trees_;
+ }
+
void SetElementIdsForTesting();
void BuildPropertyTreesForTesting();
@@ -514,7 +558,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void BeginMainFrameNotExpectedSoon();
void BeginMainFrameNotExpectedUntil(base::TimeTicks time);
void AnimateLayers(base::TimeTicks monotonic_frame_begin_time);
- void RequestMainFrameUpdate();
+ void RequestMainFrameUpdate(bool record_main_frame_metrics);
void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl);
void WillCommit();
void CommitComplete();
@@ -641,20 +685,20 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
private:
friend class LayerTreeHostSerializationTest;
- friend class ScopedDeferCommits;
+ friend class ScopedDeferMainFrameUpdate;
// This is the number of consecutive frames in which we want the content to be
// free of slow-paths before toggling the flag.
enum { kNumFramesToConsiderBeforeRemovingSlowPathFlag = 60 };
- void ApplyViewportDeltas(const ScrollAndScaleSet& info);
+ void ApplyViewportChanges(const ScrollAndScaleSet& info);
void RecordWheelAndTouchScrollingCount(const ScrollAndScaleSet& info);
void ApplyPageScaleDeltaFromImplSide(float page_scale_delta);
void InitializeProxy(std::unique_ptr<Proxy> proxy);
bool DoUpdateLayers(Layer* root_layer);
- void UpdateDeferCommitsInternal();
+ void UpdateDeferMainFrameUpdateInternal();
const CompositorMode compositor_mode_;
@@ -706,6 +750,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
scoped_refptr<Layer> root_layer_;
ViewportLayers viewport_layers_;
+ // For CompositeAfterPaint.
+ ViewportPropertyIds viewport_property_ids_;
float top_controls_height_ = 0.f;
float top_controls_shown_ratio_ = 0.f;
@@ -720,17 +766,18 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
float page_scale_factor_ = 1.f;
float min_page_scale_factor_ = 1.f;
float max_page_scale_factor_ = 1.f;
+ float external_page_scale_factor_ = 1.f;
int raster_color_space_id_ = -1;
gfx::ColorSpace raster_color_space_;
bool clear_caches_on_next_commit_ = false;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_from_parent_;
+ viz::LocalSurfaceIdAllocation local_surface_id_allocation_from_parent_;
// Used to detect surface invariant violations.
bool has_pushed_local_surface_id_from_parent_ = false;
bool new_local_surface_id_request_ = false;
- uint32_t defer_commits_count_ = 0;
+ uint32_t defer_main_frame_update_count_ = 0;
SkColor background_color_ = SK_ColorWHITE;
@@ -746,6 +793,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
+ // Whether we have a pending request to force send RenderFrameMetadata with
+ // the next frame.
+ bool force_send_metadata_request_ = false;
+
PropertyTrees property_trees_;
bool needs_full_tree_sync_ = true;
@@ -768,6 +819,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
std::unordered_map<ElementId, Layer*, ElementIdHash> element_layers_map_;
+ // The set of registered element ids when using layer list mode. In non-layer-
+ // list mode, |element_layers_map_| is used.
+ ElementIdSet elements_in_property_trees_;
+
bool in_paint_layer_contents_ = false;
// This is true if atleast one layer in the layer tree has a copy request. We
@@ -786,8 +841,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// added here.
std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_;
- // Used to vend weak pointers to LayerTreeHost to ScopedDeferCommits objects.
- base::WeakPtrFactory<LayerTreeHost> defer_commits_weak_ptr_factory_;
+ // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate
+ // objects.
+ base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
};
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 97150433e01..2973940a711 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -9,11 +9,12 @@
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
+#include "cc/input/browser_controls_state.h"
+#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace gfx {
struct PresentationFeedback;
-class Vector2dF;
}
namespace viz {
@@ -24,7 +25,7 @@ namespace cc {
struct ApplyViewportChangesArgs {
// Scroll offset delta of the inner (visual) viewport.
- gfx::Vector2dF inner_delta;
+ gfx::ScrollOffset inner_delta;
// Elastic overscroll effect offset delta. This is used only on Mac. a.k.a
// "rubber-banding" overscroll.
@@ -37,6 +38,14 @@ struct ApplyViewportChangesArgs {
// How much the browser controls have been shown or hidden. The ratio runs
// between 0 (hidden) and 1 (full-shown). This is additive.
float browser_controls_delta;
+
+ // Whether the browser controls have been locked to fully hidden or shown or
+ // whether they can be freely moved.
+ BrowserControlsState browser_controls_constraint;
+
+ // Set to true when a scroll gesture being handled on the compositor has
+ // ended.
+ bool scroll_gesture_did_end;
};
// A LayerTreeHost is bound to a LayerTreeHostClient. The main rendering
@@ -80,8 +89,11 @@ class LayerTreeHostClient {
// (Blink's notions of) style, layout, paint invalidation and compositing
// state. (The "compositing state" will result in a mutated layer tree on the
// LayerTreeHost via additional interface indirections which lead back to
- // mutations on the LayerTreeHost.)
- virtual void UpdateLayerTreeHost() = 0;
+ // mutations on the LayerTreeHost.) The |record_main_frame_metrics| flag
+ // determines whether Blink will compute metrics related to main frame update
+ // time. If true, the caller must ensure that RecordEndOfFrameMetrics is
+ // called when this method returns and the total main frame time is known.
+ virtual void UpdateLayerTreeHost(bool record_main_frame_metrics) = 0;
// Notifies the client of viewport-related changes that occured in the
// LayerTreeHost since the last commit. This typically includes things
diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc
index f3631c4cb05..16bee1698d4 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -178,8 +178,11 @@ bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==(
ScrollAndScaleSet::ScrollAndScaleSet()
: page_scale_delta(1.f),
top_controls_delta(0.f),
+ browser_controls_constraint(BrowserControlsState::kBoth),
+ browser_controls_constraint_changed(false),
has_scrolled_by_wheel(false),
- has_scrolled_by_touch(false) {}
+ has_scrolled_by_touch(false),
+ scroll_gesture_did_end(false) {}
ScrollAndScaleSet::~ScrollAndScaleSet() = default;
@@ -200,12 +203,6 @@ static inline void ClearMaskLayersContributeToDrawnRenderSurface(
mask_layer->set_contributes_to_drawn_render_surface(false);
}
-static bool CdpPerfTracingEnabled() {
- bool tracing_enabled;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED("cdp.perf", &tracing_enabled);
- return tracing_enabled;
-}
-
static float TranslationFromActiveTreeLayerScreenSpaceTransform(
LayerImpl* pending_tree_layer) {
LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl();
@@ -496,21 +493,12 @@ void CalculateDrawPropertiesInternal(
PropertyTreeOption property_tree_option) {
inputs->render_surface_list->clear();
- const bool should_measure_property_tree_performance =
- property_tree_option == BUILD_PROPERTY_TREES;
-
LayerImplList visible_layer_list;
switch (property_tree_option) {
case BUILD_PROPERTY_TREES: {
// The translation from layer to property trees is an intermediate
// state. We will eventually get these data passed directly to the
// compositor.
- if (should_measure_property_tree_performance) {
- TRACE_EVENT_BEGIN0(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
- }
-
PropertyTreeBuilder::BuildPropertyTrees(
inputs->root_layer, inputs->page_scale_layer,
inputs->inner_viewport_scroll_layer,
@@ -530,18 +518,9 @@ void CalculateDrawPropertiesInternal(
// updates when they are built on compositor thread.
inputs->property_trees->transform_tree
.set_source_to_parent_updates_allowed(false);
- if (should_measure_property_tree_performance) {
- TRACE_EVENT_END0(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
- }
-
break;
}
case DONT_BUILD_PROPERTY_TREES: {
- TRACE_EVENT0(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::ComputeJustVisibleRectsWithPropertyTrees");
// Since page scale and elastic overscroll are SyncedProperties, changes
// on the active tree immediately affect the pending tree, so instead of
// trying to update property trees whenever these values change, we
@@ -603,11 +582,6 @@ void CalculateDrawPropertiesInternal(
}
}
- if (should_measure_property_tree_performance) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::CalculateDrawProperties");
- }
-
{
TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates");
draw_property_utils::FindLayersThatNeedUpdates(
@@ -630,11 +604,6 @@ void CalculateDrawPropertiesInternal(
inputs->render_surface_list, inputs->max_texture_size);
}
- if (should_measure_property_tree_performance) {
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::CalculateDrawProperties");
- }
-
// A root layer render_surface should always exist after
// CalculateDrawProperties.
DCHECK(inputs->property_trees->effect_tree.GetRenderSurface(
@@ -663,48 +632,6 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
void LayerTreeHostCommon::CalculateDrawProperties(
CalcDrawPropsImplInputs* inputs) {
CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES);
-
- if (CdpPerfTracingEnabled()) {
- LayerTreeImpl* layer_tree_impl = inputs->root_layer->layer_tree_impl();
- if (layer_tree_impl->IsPendingTree() &&
- layer_tree_impl->is_first_frame_after_commit()) {
- LayerImpl* active_tree_root =
- layer_tree_impl->FindActiveTreeLayerById(inputs->root_layer->id());
- float jitter = 0.f;
- if (active_tree_root) {
- int last_scrolled_node_index =
- active_tree_root->layer_tree_impl()->LastScrolledScrollNodeIndex();
- if (last_scrolled_node_index != ScrollTree::kInvalidNodeId) {
- std::unordered_set<int> jitter_nodes;
- for (auto* layer : *layer_tree_impl) {
- // Layers that have the same scroll tree index jitter together. So,
- // it is enough to calculate jitter on one of these layers. So,
- // after we find a jittering layer, we need not consider other
- // layers with the same scroll tree index.
- int scroll_tree_index = layer->scroll_tree_index();
- if (last_scrolled_node_index <= scroll_tree_index &&
- jitter_nodes.find(scroll_tree_index) == jitter_nodes.end()) {
- float layer_jitter = CalculateLayerJitter(layer);
- if (layer_jitter > 0.f) {
- jitter_nodes.insert(layer->scroll_tree_index());
- jitter += layer_jitter;
- }
- }
- }
- }
- }
- TRACE_EVENT_ASYNC_BEGIN1(
- "cdp.perf", "jitter",
- inputs->root_layer->layer_tree_impl()->source_frame_number(), "value",
- jitter);
- inputs->root_layer->layer_tree_impl()->set_is_first_frame_after_commit(
- false);
- TRACE_EVENT_ASYNC_END1(
- "cdp.perf", "jitter",
- inputs->root_layer->layer_tree_impl()->source_frame_number(), "value",
- jitter);
- }
- }
}
void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h
index 6116eaf5300..42de6d2ab68 100644
--- a/chromium/cc/trees/layer_tree_host_common.h
+++ b/chromium/cc/trees/layer_tree_host_common.h
@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "cc/cc_export.h"
+#include "cc/input/browser_controls_state.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_impl.h"
@@ -134,9 +135,7 @@ class CC_EXPORT LayerTreeHostCommon {
struct CC_EXPORT ScrollUpdateInfo {
ElementId element_id;
- // TODO(miletus): Use ScrollOffset once LayerTreeHost/Blink fully supports
- // fractional scroll offset.
- gfx::Vector2d scroll_delta;
+ gfx::ScrollOffset scroll_delta;
bool operator==(const ScrollUpdateInfo& other) const;
};
@@ -173,9 +172,15 @@ struct CC_EXPORT ScrollAndScaleSet {
float top_controls_delta;
std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars;
std::vector<std::unique_ptr<SwapPromise>> swap_promises;
+ BrowserControlsState browser_controls_constraint;
+ bool browser_controls_constraint_changed;
bool has_scrolled_by_wheel;
bool has_scrolled_by_touch;
+ // Set to true when a scroll gesture being handled on the compositor has
+ // ended.
+ bool scroll_gesture_did_end;
+
private:
DISALLOW_COPY_AND_ASSIGN(ScrollAndScaleSet);
};
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index 991303a6456..561cdd1ade5 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -50,7 +50,7 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest {
void SetupTree() override {
gfx::Size viewport = gfx::Size(720, 1038);
layer_tree_host()->SetViewportSizeAndScale(viewport, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
scoped_refptr<Layer> root =
ParseTreeFromJson(json_, &content_layer_client_);
ASSERT_TRUE(root.get());
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 57bed051c21..17a78468e72 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -1409,7 +1409,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
}
TEST_F(LayerTreeHostCommonTest,
- RenderSurfaceListForTransparentChildWithBackgroundFilter) {
+ RenderSurfaceListForTransparentChildWithBackdropFilter) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* render_surface1 = AddChild<LayerImpl>(root);
LayerImpl* child = AddChild<LayerImpl>(render_surface1);
@@ -1421,7 +1421,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->SetDrawsContent(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(1.5f));
- render_surface1->test_properties()->background_filters = filters;
+ render_surface1->test_properties()->backdrop_filters = filters;
child->SetBounds(gfx::Size(10, 10));
child->SetDrawsContent(true);
root->layer_tree_impl()->SetElementIdsForTesting();
@@ -1434,7 +1434,7 @@ TEST_F(LayerTreeHostCommonTest,
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
EXPECT_EQ(2U, render_surface_list.size());
}
- // The layer is fully transparent, but has a background filter, so it
+ // The layer is fully transparent, but has a backdrop filter, so it
// shouldn't be skipped and should be drawn.
ASSERT_TRUE(GetRenderSurface(root));
EXPECT_EQ(1, GetRenderSurface(root)->num_contributors());
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 9b1e5d7484e..dcfc217ced6 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -25,8 +25,8 @@
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/system/sys_info.h"
+#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
@@ -40,6 +40,7 @@
#include "cc/input/scroll_state.h"
#include "cc/input/scrollbar_animation_controller.h"
#include "cc/input/scroller_size_metrics.h"
+#include "cc/input/snap_selection_strategy.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/heads_up_display_layer_impl.h"
@@ -330,7 +331,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
frame_metrics_(LTHI_FrameMetricsSettings(settings_)),
skipped_frame_tracker_(&frame_metrics_),
is_animating_for_snap_(false),
- paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()) {
+ paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()),
+ scroll_gesture_did_end_(false) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
@@ -455,7 +457,7 @@ void LayerTreeHostImpl::CommitComplete() {
void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
// LayerTreeHost may have changed the GPU rasterization flags state, which
// may require an update of the tree resources.
- UpdateTreeResourcesForGpuRasterizationIfNeeded();
+ UpdateTreeResourcesIfNeeded();
sync_tree()->set_needs_update_draw_properties();
// We need an update immediately post-commit to have the opportunity to create
@@ -478,16 +480,15 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
// Defer invalidating images until UpdateDrawProperties is performed since
// that updates whether an image should be animated based on its visibility
// and the updated data for the image from the main frame.
- PaintImageIdFlatSet images_to_invalidate =
- tile_manager_.TakeImagesToInvalidateOnSyncTree();
- if (ukm_manager_)
- ukm_manager_->AddCheckerboardedImages(images_to_invalidate.size());
+ PaintImageIdFlatSet images_to_invalidate =
+ tile_manager_.TakeImagesToInvalidateOnSyncTree();
+ if (ukm_manager_)
+ ukm_manager_->AddCheckerboardedImages(images_to_invalidate.size());
- const auto& animated_images =
- image_animation_controller_.AnimateForSyncTree(
- CurrentBeginFrameArgs().frame_time);
- images_to_invalidate.insert(animated_images.begin(), animated_images.end());
- sync_tree()->InvalidateRegionForImages(images_to_invalidate);
+ const auto& animated_images = image_animation_controller_.AnimateForSyncTree(
+ CurrentBeginFrameArgs().frame_time);
+ images_to_invalidate.insert(animated_images.begin(), animated_images.end());
+ sync_tree()->InvalidateRegionForImages(images_to_invalidate);
// Note that it is important to push the state for checkerboarded and animated
// images prior to PrepareTiles here when committing to the active tree. This
@@ -950,8 +951,8 @@ bool LayerTreeHostImpl::HasDamage() const {
// If we have a new LocalSurfaceId, we must always submit a CompositorFrame
// because the parent is blocking on us.
- if (last_draw_local_surface_id_ !=
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceId()) {
+ if (last_draw_local_surface_id_allocation_ !=
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()) {
return true;
}
@@ -1249,12 +1250,13 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
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);
}
- 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",
@@ -1386,11 +1388,6 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
}
DrawResult draw_result = CalculateRenderPasses(frame);
- if (client_name) {
- UMA_HISTOGRAM_ENUMERATION(
- base::StringPrintf("Compositing.%s.DrawResult", client_name),
- draw_result);
- }
if (draw_result != DRAW_SUCCESS) {
DCHECK(!resourceless_software_draw_);
return draw_result;
@@ -1441,7 +1438,7 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
}
if (pass->quad_list.empty() && pass->copy_requests.empty() &&
- pass->filters.IsEmpty() && pass->background_filters.IsEmpty()) {
+ pass->filters.IsEmpty() && pass->backdrop_filters.IsEmpty()) {
// Remove the pass and decrement |i| to counter the for loop's increment,
// so we don't skip the next pass in the loop.
frame->render_passes.erase(frame->render_passes.begin() + i);
@@ -1811,8 +1808,6 @@ LayerTreeHostImpl::FrameTokenInfo::~FrameTokenInfo() = default;
void LayerTreeHostImpl::DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) {
- TRACE_EVENT_MARK_WITH_TIMESTAMP0("cc,benchmark", "FramePresented",
- feedback.timestamp);
std::vector<LayerTreeHost::PresentationTimeCallback> all_callbacks;
while (!frame_token_infos_.empty()) {
auto info = frame_token_infos_.begin();
@@ -1833,6 +1828,10 @@ void LayerTreeHostImpl::DidPresentCompositorFrame(
frame_token, std::move(all_callbacks), feedback);
}
+void LayerTreeHostImpl::DidNotNeedBeginFrame() {
+ skipped_frame_tracker_.WillNotProduceFrame();
+}
+
void LayerTreeHostImpl::ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) {
resource_provider_.ReceiveReturnsFromParent(resources);
@@ -1959,6 +1958,10 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
metadata.top_controls_shown_ratio =
browser_controls_offset_manager_->TopControlsShownRatio();
+ metadata.local_surface_id_allocation_time =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
+ .allocation_time();
+
#if defined(OS_ANDROID)
metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
metadata.root_layer_size = active_tree_->ScrollableSize();
@@ -2007,6 +2010,8 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
metadata.viewport_size_in_pixels = active_tree_->GetDeviceViewport().size();
metadata.page_scale_factor = active_tree_->current_page_scale_factor();
+ metadata.external_page_scale_factor =
+ active_tree_->external_page_scale_factor();
metadata.top_controls_height =
browser_controls_offset_manager_->TopControlsHeight();
@@ -2056,12 +2061,12 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
metadata.has_transparent_background);
#endif
- viz::LocalSurfaceId local_surface_id =
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
- if (local_surface_id.is_valid()) {
+ if (child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
+ .IsValid()) {
if (allocate_new_local_surface_id)
- local_surface_id = child_local_surface_id_allocator_.GenerateId();
- metadata.local_surface_id = local_surface_id;
+ child_local_surface_id_allocator_.GenerateId();
+ metadata.local_surface_id_allocation =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
}
return metadata;
@@ -2082,7 +2087,8 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
}
auto compositor_frame = GenerateCompositorFrame(frame);
- layer_tree_frame_sink_->SubmitCompositorFrame(std::move(compositor_frame));
+ layer_tree_frame_sink_->SubmitCompositorFrame(
+ std::move(compositor_frame), 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.
@@ -2139,7 +2145,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
{
TRACE_EVENT0("cc", "DrawLayers.FrameViewerTracing");
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
- frame_viewer_instrumentation::kCategoryLayerTree,
+ frame_viewer_instrumentation::CategoryLayerTree(),
"cc::LayerTreeHostImpl", id_, AsValueWithFrame(frame));
}
@@ -2173,7 +2179,8 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
if (render_frame_metadata_observer_) {
last_draw_render_frame_metadata_ = MakeRenderFrameMetadata(frame);
render_frame_metadata_observer_->OnRenderFrameSubmission(
- *last_draw_render_frame_metadata_, &metadata);
+ *last_draw_render_frame_metadata_, &metadata,
+ active_tree()->TakeForceSendMetadataRequest());
}
metadata.latency_info.emplace_back(ui::SourceEventType::FRAME);
@@ -2222,12 +2229,13 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
// LocalSurfaceId might slip through, but single-thread-without-scheduler
// mode is only used in tests so it doesn't matter.
CHECK(!settings_.single_thread_proxy_scheduler ||
- active_tree()->local_surface_id_from_parent().is_valid());
+ active_tree()->local_surface_id_allocation_from_parent().IsValid());
layer_tree_frame_sink_->SetLocalSurfaceId(
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id());
}
- last_draw_local_surface_id_ =
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
+ last_draw_local_surface_id_allocation_ =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
if (const char* client_name = GetClientNameForMetrics()) {
size_t total_quad_count = 0;
for (const auto& pass : compositor_frame.render_pass_list)
@@ -2409,8 +2417,15 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() {
return true;
}
-void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() {
- if (!UpdateGpuRasterizationStatus())
+void LayerTreeHostImpl::UpdateTreeResourcesIfNeeded() {
+ // For simplicity, clobber all resources when the color space changes.
+ // This is mostly to clear the image decode caches, which don't handle
+ // multiple color space at once.
+ int color_space_id = GetRasterColorSpace().color_space_id;
+ bool color_space_changed = last_color_space_id_ != color_space_id;
+ last_color_space_id_ = color_space_id;
+
+ if (!UpdateGpuRasterizationStatus() && !color_space_changed)
return;
// Clean up and replace existing tile manager with another one that uses
@@ -2597,11 +2612,15 @@ static uint32_t GetFlagsForSurfaceLayer(const SurfaceLayerImpl* layer) {
static void PopulateHitTestRegion(viz::HitTestRegion* hit_test_region,
const LayerImpl* layer,
uint32_t flags,
+ uint32_t async_hit_test_reasons,
const gfx::Rect& rect,
const viz::SurfaceId& surface_id,
float device_scale_factor) {
hit_test_region->frame_sink_id = surface_id.frame_sink_id();
hit_test_region->flags = flags;
+ hit_test_region->async_hit_test_reasons = async_hit_test_reasons;
+ DCHECK_EQ(!!async_hit_test_reasons,
+ !!(flags & viz::HitTestRegionFlags::kHitTestAsk));
hit_test_region->rect = rect;
// The transform of hit test region maps a point from parent hit test region
@@ -2662,12 +2681,13 @@ base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
gfx::Rect layer_screen_space_rect = MathUtil::MapEnclosingClippedRect(
surface_layer->ScreenSpaceTransform(),
gfx::Rect(surface_layer->bounds()));
- if (overlapping_region.Contains(layer_screen_space_rect))
- continue;
-
auto flag = GetFlagsForSurfaceLayer(surface_layer);
- if (overlapping_region.Intersects(layer_screen_space_rect))
+ uint32_t async_hit_test_reasons =
+ viz::AsyncHitTestReasons::kNotAsyncHitTest;
+ if (overlapping_region.Intersects(layer_screen_space_rect)) {
flag |= viz::HitTestRegionFlags::kHitTestAsk;
+ async_hit_test_reasons |= viz::AsyncHitTestReasons::kOverlappedRegion;
+ }
if (surface_layer->is_clipped()) {
bool layer_hit_test_region_is_rectangle =
active_tree()
@@ -2678,13 +2698,16 @@ base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
content_rect =
gfx::ScaleToEnclosingRect(surface_layer->visible_layer_rect(),
device_scale_factor, device_scale_factor);
- if (!layer_hit_test_region_is_rectangle)
+ if (!layer_hit_test_region_is_rectangle) {
flag |= viz::HitTestRegionFlags::kHitTestAsk;
+ async_hit_test_reasons |= viz::AsyncHitTestReasons::kIrregularClip;
+ }
}
const auto& surface_id = surface_layer->range().end();
hit_test_region_list->regions.emplace_back();
PopulateHitTestRegion(&hit_test_region_list->regions.back(), layer, flag,
- content_rect, surface_id, device_scale_factor);
+ async_hit_test_reasons, content_rect, surface_id,
+ device_scale_factor);
continue;
}
// TODO(sunxd): Submit all overlapping layer bounds as hit test regions.
@@ -2711,6 +2734,10 @@ bool LayerTreeHostImpl::HaveRootScrollNode() const {
return InnerViewportScrollNode();
}
+void LayerTreeHostImpl::SetNeedsCommit() {
+ client_->SetNeedsCommitOnImplThread();
+}
+
LayerImpl* LayerTreeHostImpl::InnerViewportContainerLayer() const {
return active_tree_->InnerViewportContainerLayer();
}
@@ -2904,9 +2931,9 @@ void LayerTreeHostImpl::ActivateSyncTree() {
UpdateRootLayerStateForSynchronousInputHandler();
// Update the child's LocalSurfaceId.
- if (active_tree()->local_surface_id_from_parent().is_valid()) {
+ if (active_tree()->local_surface_id_allocation_from_parent().IsValid()) {
child_local_surface_id_allocator_.UpdateFromParent(
- active_tree()->local_surface_id_from_parent());
+ active_tree()->local_surface_id_allocation_from_parent());
if (active_tree()->TakeNewLocalSurfaceIdRequest())
child_local_surface_id_allocator_.GenerateId();
}
@@ -2914,22 +2941,14 @@ void LayerTreeHostImpl::ActivateSyncTree() {
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host_impl=3
if (VLOG_IS_ON(3)) {
- VLOG(3) << "After activating sync tree, the active tree:";
- // Because the property tree and layer list output can be verbose, the VLOG
- // output is split by line to avoid line buffer limits on android.
- VLOG(3) << "property trees:";
std::string property_trees;
base::JSONWriter::WriteWithOptions(
*active_tree_->property_trees()->AsTracedValue()->ToBaseValue(),
base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees);
- std::stringstream property_trees_stream(property_trees);
- for (std::string line; std::getline(property_trees_stream, line);)
- VLOG(3) << line;
-
- VLOG(3) << "layers:";
- std::stringstream layers_stream(LayerListAsJson());
- for (std::string line; std::getline(layers_stream, line);)
- VLOG(3) << line;
+ VLOG(3) << "After activating sync tree, the active tree:"
+ << "\nproperty_trees:\n"
+ << property_trees << "\nlayers:\n"
+ << LayerListAsJson();
}
}
@@ -2989,6 +3008,12 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
SetFullViewportDamage();
SetNeedsRedraw();
}
+ // If surface synchronization is off, force allocating a new LocalSurfaceId
+ // because the previous LocalSurfaceId might have been evicted while we were
+ // invisible. When surface synchronization is on, the embedder will pass us
+ // a new LocalSurfaceID.
+ if (layer_tree_frame_sink_ && !settings_.enable_surface_synchronization)
+ layer_tree_frame_sink_->ForceAllocateNewId();
} else {
EvictAllUIResources();
// Call PrepareTiles to evict tiles when we become invisible.
@@ -3008,7 +3033,8 @@ void LayerTreeHostImpl::SetNeedsOneBeginImplFrame() {
void LayerTreeHostImpl::SetNeedsRedraw() {
NotifySwapPromiseMonitorsOfSetNeedsRedraw();
client_->SetNeedsRedrawOnImplThread();
- skipped_frame_tracker_.WillProduceFrame();
+ if (CurrentlyScrollingNode())
+ skipped_frame_tracker_.WillProduceFrame();
}
ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const {
@@ -3067,13 +3093,15 @@ void LayerTreeHostImpl::CreateTileManagerResources() {
viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
tile_format),
settings_.decoded_image_working_set_budget_bytes, max_texture_size_,
- paint_image_generator_client_id_);
+ paint_image_generator_client_id_,
+ GetRasterColorSpace().color_space.ToSkColorSpace());
} else {
bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
viz::ResourceFormatToClosestSkColorType(gpu_compositing, tile_format),
settings_.decoded_image_working_set_budget_bytes,
- paint_image_generator_client_id_);
+ paint_image_generator_client_id_,
+ GetRasterColorSpace().color_space.ToSkColorSpace());
}
// Pass the single-threaded synchronous task graph runner to the worker pool
@@ -3173,9 +3201,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, GetRasterColorSpace().color_space,
- base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
- base::Unretained(this), request_id));
+ image, base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
+ base::Unretained(this), request_id));
tile_manager_.checker_image_tracker().DisallowCheckeringForImage(image);
}
@@ -3357,6 +3384,18 @@ bool LayerTreeHostImpl::InitializeFrameSink(
// TODO(crbug.com/469175): Replace with RequiresHighResToDraw.
SetRequiresHighResToDraw();
+ // Always allocate a new viz::LocalSurfaceId when we get a new
+ // LayerTreeFrameSink to ensure that we do not reuse the same surface after
+ // it might have been garbage collected.
+ if (settings_.enable_surface_synchronization) {
+ 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();
+ } else {
+ layer_tree_frame_sink_->ForceAllocateNewId();
+ }
+
return true;
}
@@ -4493,12 +4532,13 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
const SnapContainerData& data = scroll_node->snap_container_data.value();
gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndPosition(
+ current_position, did_scroll_x_for_scroll_gesture_,
+ did_scroll_y_for_scroll_gesture_);
gfx::ScrollOffset snap_position;
- if (!data.FindSnapPosition(current_position, did_scroll_x_for_scroll_gesture_,
- did_scroll_y_for_scroll_gesture_,
- &snap_position)) {
+ if (!data.FindSnapPosition(*strategy, &snap_position))
return false;
- }
gfx::Vector2dF delta =
ScrollOffsetToVector2dF(snap_position - current_position);
@@ -4541,8 +4581,8 @@ gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset(
bool LayerTreeHostImpl::GetSnapFlingInfo(
const gfx::Vector2dF& natural_displacement_in_viewport,
- gfx::Vector2dF* out_initial_offset,
- gfx::Vector2dF* out_target_offset) const {
+ gfx::Vector2dF* out_initial_position,
+ gfx::Vector2dF* out_target_position) const {
const ScrollNode* scroll_node = CurrentlyScrollingNode();
if (!scroll_node || !scroll_node->snap_container_data.has_value())
return false;
@@ -4552,24 +4592,19 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
gfx::Vector2dF natural_displacement_in_content =
gfx::ScaleVector2d(natural_displacement_in_viewport, 1.f / scale_factor);
- *out_initial_offset =
- ScrollOffsetToVector2dF(GetVisualScrollOffset(*scroll_node));
-
- bool did_scroll_x = did_scroll_x_for_scroll_gesture_ ||
- natural_displacement_in_content.x() != 0;
- bool did_scroll_y = did_scroll_y_for_scroll_gesture_ ||
- natural_displacement_in_content.y() != 0;
+ gfx::ScrollOffset current_offset = GetVisualScrollOffset(*scroll_node);
+ *out_initial_position = ScrollOffsetToVector2dF(current_offset);
gfx::ScrollOffset snap_offset;
- if (!data.FindSnapPosition(gfx::ScrollOffset(*out_initial_offset +
- natural_displacement_in_content),
- did_scroll_x, did_scroll_y, &snap_offset)) {
+ std::unique_ptr<SnapSelectionStrategy> strategy =
+ SnapSelectionStrategy::CreateForEndAndDirection(
+ current_offset, gfx::ScrollOffset(natural_displacement_in_content));
+ if (!data.FindSnapPosition(*strategy, &snap_offset))
return false;
- }
- *out_target_offset = ScrollOffsetToVector2dF(snap_offset);
- out_target_offset->Scale(scale_factor);
- out_initial_offset->Scale(scale_factor);
+ *out_target_position = ScrollOffsetToVector2dF(snap_offset);
+ out_target_position->Scale(scale_factor);
+ out_initial_position->Scale(scale_factor);
return true;
}
@@ -4594,6 +4629,8 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
}
void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) {
+ scroll_gesture_did_end_ = true;
+
if (should_snap && SnapAtScrollEnd())
return;
@@ -4739,7 +4776,8 @@ void LayerTreeHostImpl::CollectScrollDeltas(
: ElementId();
active_tree_->property_trees()->scroll_tree.CollectScrollDeltas(
- scroll_info, inner_viewport_scroll_element_id);
+ scroll_info, inner_viewport_scroll_element_id,
+ active_tree_->settings().commit_fractional_scroll_deltas);
}
void LayerTreeHostImpl::CollectScrollbarUpdates(
@@ -4772,8 +4810,16 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
// Record and reset scroll source flags.
scroll_info->has_scrolled_by_wheel = has_scrolled_by_wheel_;
scroll_info->has_scrolled_by_touch = has_scrolled_by_touch_;
+ scroll_info->scroll_gesture_did_end = scroll_gesture_did_end_;
has_scrolled_by_wheel_ = has_scrolled_by_touch_ = false;
+ if (browser_controls_manager()) {
+ scroll_info->browser_controls_constraint =
+ browser_controls_manager()->PullConstraintForMainThread(
+ &scroll_info->browser_controls_constraint_changed);
+ }
+
+ scroll_gesture_did_end_ = false;
return scroll_info;
}
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index a215f1cb908..b932defe22e 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -67,12 +67,12 @@ class CompositorFrameMetadata;
namespace cc {
class BrowserControlsOffsetManager;
-class LayerTreeFrameSink;
class DebugRectHistory;
class EvictionTilePriorityQueue;
class FrameRateCounter;
class ImageAnimationController;
class LayerImpl;
+class LayerTreeFrameSink;
class LayerTreeImpl;
class MemoryHistory;
class MutatorEvents;
@@ -91,7 +91,6 @@ class SwapPromiseMonitor;
class SynchronousTaskGraphRunner;
class TaskGraphRunner;
class UIResourceBitmap;
-struct ScrollAndScaleSet;
class Viewport;
using BeginFrameCallbackList = std::vector<base::Closure>;
@@ -295,6 +294,7 @@ class CC_EXPORT LayerTreeHostImpl
float CurrentBrowserControlsShownRatio() const override;
void DidChangeBrowserControlsPosition() override;
bool HaveRootScrollNode() const override;
+ void SetNeedsCommit() override;
void UpdateViewportContainerSizes();
@@ -306,6 +306,7 @@ class CC_EXPORT LayerTreeHostImpl
return viewport_damage_rect_;
}
+ virtual void WillSendBeginMainFrame() {}
virtual void DidSendBeginMainFrame() {}
virtual void BeginMainFrameAborted(
CommitEarlyOutReason reason,
@@ -442,6 +443,7 @@ class CC_EXPORT LayerTreeHostImpl
void DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) override;
+ void DidNotNeedBeginFrame() override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override;
@@ -542,7 +544,6 @@ class CC_EXPORT LayerTreeHostImpl
return is_animating_for_snap_;
}
- void SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); }
void SetNeedsOneBeginImplFrame();
void SetNeedsRedraw();
@@ -615,8 +616,8 @@ class CC_EXPORT LayerTreeHostImpl
gfx::ScrollOffset GetVisualScrollOffset(const ScrollNode& scroll_node) const;
bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement_in_viewport,
- gfx::Vector2dF* out_initial_offset,
- gfx::Vector2dF* out_target_offset) const override;
+ gfx::Vector2dF* out_initial_position,
+ gfx::Vector2dF* out_target_position) const override;
// Returns the amount of delta that can be applied to scroll_node, taking
// page scale into account.
@@ -778,7 +779,7 @@ class CC_EXPORT LayerTreeHostImpl
// Returns true if status changed.
bool UpdateGpuRasterizationStatus();
- void UpdateTreeResourcesForGpuRasterizationIfNeeded();
+ void UpdateTreeResourcesIfNeeded();
Viewport* viewport() const { return viewport_.get(); }
@@ -1075,7 +1076,7 @@ class CC_EXPORT LayerTreeHostImpl
uint32_t next_frame_token_ = 1u;
- viz::LocalSurfaceId last_draw_local_surface_id_;
+ viz::LocalSurfaceIdAllocation last_draw_local_surface_id_allocation_;
base::flat_set<viz::SurfaceRange> last_draw_referenced_surfaces_;
base::Optional<RenderFrameMetadata> last_draw_render_frame_metadata_;
viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
@@ -1106,10 +1107,15 @@ class CC_EXPORT LayerTreeHostImpl
base::circular_deque<FrameTokenInfo> frame_token_infos_;
ui::FrameMetrics frame_metrics_;
ui::SkippedFrameTracker skipped_frame_tracker_;
+ int last_color_space_id_ = -1;
bool is_animating_for_snap_;
const PaintImage::GeneratorClientId paint_image_generator_client_id_;
+ // Set to true when a scroll gesture being handled on the compositor has
+ // ended.
+ bool scroll_gesture_did_end_;
+
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 47732887d78..a31b2fe9444 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -20,6 +20,7 @@
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
@@ -54,6 +55,7 @@
#include "cc/test/layer_tree_test.h"
#include "cc/test/skia_common.h"
#include "cc/test/test_task_graph_runner.h"
+#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/latency_info_swap_promise.h"
@@ -192,8 +194,10 @@ class LayerTreeHostImplTest : public testing::Test,
}
void DidActivateSyncTree() override {
// Make sure the active tree always has a valid LocalSurfaceId.
- host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
- viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
+ host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
+ viz::LocalSurfaceIdAllocation(
+ viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
+ base::TimeTicks::Now()));
}
void WillPrepareTiles() override {}
void DidPrepareTiles() override {}
@@ -254,8 +258,10 @@ class LayerTreeHostImplTest : public testing::Test,
bool init = host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get());
host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 10));
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
- host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
- viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
+ host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
+ viz::LocalSurfaceIdAllocation(
+ viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
+ base::TimeTicks::Now()));
// Set the viz::BeginFrameArgs so that methods which use it are able to.
host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
BEGINFRAME_FROM_HERE, 0, 1,
@@ -294,7 +300,7 @@ class LayerTreeHostImplTest : public testing::Test,
static ::testing::AssertionResult ScrollInfoContains(
const ScrollAndScaleSet& scroll_info,
ElementId id,
- const gfx::Vector2d& scroll_delta) {
+ const gfx::ScrollOffset& scroll_delta) {
int times_encountered = 0;
for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
@@ -960,7 +966,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
gfx::ScrollOffset scroll_offset(20, 30);
- gfx::Vector2d scroll_delta(11, -15);
+ gfx::ScrollOffset scroll_delta(11, -15);
auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1);
auto* root = root_owned.get();
@@ -977,14 +983,14 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
std::unique_ptr<ScrollAndScaleSet> scroll_info;
- root->ScrollBy(scroll_delta);
+ root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta));
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(scroll_info->scrolls.size(), 1u);
EXPECT_TRUE(
ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta));
- gfx::Vector2d scroll_delta2(-5, 27);
- root->ScrollBy(scroll_delta2);
+ gfx::ScrollOffset scroll_delta2(-5, 27);
+ root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta2));
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(scroll_info->scrolls.size(), 1u);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(),
@@ -1128,8 +1134,10 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
// We should still be scrolling, because the scrolled layer also exists in the
// new tree.
- gfx::Vector2d scroll_delta(0, 10);
- host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
+ gfx::ScrollOffset scroll_delta(0, 10);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta))
+ .get());
host_impl_->ScrollEnd(EndState().get());
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -1664,7 +1672,7 @@ TEST_F(LayerTreeHostImplTest, SnapAnimationCancelledByScroll) {
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
BeginImplFrameAndAnimate(begin_frame_args,
start_time + base::TimeDelta::FromMilliseconds(150));
- EXPECT_VECTOR_EQ(ScrollOffsetToVector2dF(current_offset),
+ EXPECT_VECTOR_EQ(gfx::ScrollOffsetToVector2dF(current_offset),
overflow->CurrentScrollOffset());
}
@@ -2256,7 +2264,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
host_impl_->ProcessScrollDeltas();
EXPECT_TRUE(ScrollInfoContains(
*scroll_info.get(), scroll_layer->element_id(),
- gfx::Vector2d(0, scroll_delta.y() / page_scale_delta)));
+ gfx::ScrollOffset(0, scroll_delta.y() / page_scale_delta)));
}
}
@@ -2876,7 +2884,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(-10, -10)));
+ gfx::ScrollOffset(-10, -10)));
}
// Two-finger panning should work when starting fully zoomed out.
@@ -2910,7 +2918,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(10, 10)));
+ gfx::ScrollOffset(10, 10)));
}
}
@@ -2951,7 +2959,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(0, -1)));
+ gfx::ScrollOffset(0, -1)));
// Verify this scroll delta is consistent with the snapped position of the
// scroll layer.
@@ -3193,7 +3201,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, 2);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(-50, -50)));
+ gfx::ScrollOffset(-50, -50)));
}
start_time += base::TimeDelta::FromSeconds(10);
@@ -3246,7 +3254,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
// Pushed to (0,0) via clamping against contents layer size.
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(-50, -50)));
+ gfx::ScrollOffset(-50, -50)));
}
}
@@ -3432,7 +3440,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
- gfx::Vector2d(-50, -50)));
+ gfx::ScrollOffset(-50, -50)));
}
TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
@@ -3577,8 +3585,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->DidBecomeActive();
host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain();
- host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
- viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
+ host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
+ viz::LocalSurfaceIdAllocation(
+ viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
+ base::TimeTicks::Now()));
DrawFrame();
// SetScrollElementId will initialize the scrollbar which will cause it to
@@ -5369,61 +5379,9 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
const gfx::Size& inner_viewport_size,
const gfx::Size& outer_viewport_size,
const gfx::Size& scroll_layer_size) {
- tree_impl->set_browser_controls_shrink_blink_size(true);
- tree_impl->SetTopControlsHeight(top_controls_height_);
- tree_impl->SetCurrentBrowserControlsShownRatio(1.f);
- tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
- host_impl_->DidChangeBrowserControlsPosition();
-
- std::unique_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1);
- std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2);
- std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(tree_impl, 3);
-
- std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(tree_impl, 4);
- std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5);
-
- root_clip->SetBounds(inner_viewport_size);
- root->SetScrollable(inner_viewport_size);
- root->SetElementId(LayerIdToElementIdForTesting(root->id()));
- root->SetBounds(outer_viewport_size);
- root->SetPosition(gfx::PointF());
- root->SetDrawsContent(false);
- root_clip->test_properties()->force_render_surface = true;
- root->test_properties()->is_container_for_fixed_position_layers = true;
- outer_clip->SetBounds(outer_viewport_size);
- outer_scroll->SetScrollable(outer_viewport_size);
- outer_scroll->SetElementId(
- LayerIdToElementIdForTesting(outer_scroll->id()));
- outer_scroll->SetBounds(scroll_layer_size);
- outer_scroll->SetPosition(gfx::PointF());
- outer_scroll->SetDrawsContent(false);
- outer_scroll->test_properties()->is_container_for_fixed_position_layers =
- true;
-
- int inner_viewport_container_layer_id = root_clip->id();
- int outer_viewport_container_layer_id = outer_clip->id();
- int inner_viewport_scroll_layer_id = root->id();
- int outer_viewport_scroll_layer_id = outer_scroll->id();
- int page_scale_layer_id = page_scale->id();
-
- outer_clip->test_properties()->AddChild(std::move(outer_scroll));
- root->test_properties()->AddChild(std::move(outer_clip));
- page_scale->test_properties()->AddChild(std::move(root));
- root_clip->test_properties()->AddChild(std::move(page_scale));
-
- tree_impl->SetRootLayerForTesting(std::move(root_clip));
- LayerTreeImpl::ViewportLayerIds viewport_ids;
- viewport_ids.page_scale = page_scale_layer_id;
- viewport_ids.inner_viewport_container = inner_viewport_container_layer_id;
- viewport_ids.outer_viewport_container = outer_viewport_container_layer_id;
- viewport_ids.inner_viewport_scroll = inner_viewport_scroll_layer_id;
- viewport_ids.outer_viewport_scroll = outer_viewport_scroll_layer_id;
- tree_impl->SetViewportLayersFromIds(viewport_ids);
- tree_impl->BuildPropertyTreesForTesting();
-
- host_impl_->active_tree()->SetDeviceViewportSize(inner_viewport_size);
- LayerImpl* root_clip_ptr = tree_impl->root_layer_for_testing();
- EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
+ LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport(
+ host_impl_.get(), tree_impl, top_controls_height_, inner_viewport_size,
+ outer_viewport_size, scroll_layer_size);
}
protected:
@@ -5508,6 +5466,65 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
host_impl_->ScrollEnd(EndState().get());
}
+TEST_F(LayerTreeHostImplBrowserControlsTest,
+ MovingBrowserControlsChangesViewportClip) {
+ // TODO(bokan): This test is checking pre-blink-gen-property-tree behavior
+ // and can be removed once that flag ships. See crbug.com/901083.
+ if (DefaultSettings().use_layer_lists)
+ return;
+
+ SetupBrowserControlsAndScrollLayerWithVirtualViewport(
+ gfx::Size(50, 50), gfx::Size(25, 25), gfx::Size(100, 100));
+
+ LayerTreeImpl* active_tree = host_impl_->active_tree();
+
+ // Create a content layer beneath the outer viewport scroll layer.
+ int id = host_impl_->OuterViewportScrollLayer()->id();
+ host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild(
+ LayerImpl::Create(host_impl_->active_tree(), id + 2));
+ LayerImpl* content =
+ active_tree->OuterViewportScrollLayer()->test_properties()->children[0];
+ content->SetBounds(gfx::Size(100, 100));
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 4.f);
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ DrawFrame();
+
+ LayerImpl* inner_container = active_tree->InnerViewportContainerLayer();
+ LayerImpl* outer_container = active_tree->OuterViewportContainerLayer();
+ LayerImpl* outer_scroll = active_tree->OuterViewportScrollLayer();
+ auto* property_trees = host_impl_->active_tree()->property_trees();
+ ClipNode* outer_clip_node =
+ property_trees->clip_tree.Node(outer_scroll->clip_tree_index());
+
+ // The browser controls should start off showing so the viewport should be
+ // shrunk.
+ EXPECT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset());
+ ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds());
+ ASSERT_EQ(gfx::Size(25, 25), outer_container->bounds());
+ EXPECT_EQ(gfx::SizeF(100, 100), active_tree->ScrollableSize());
+ EXPECT_EQ(gfx::SizeF(50, 50), outer_clip_node->clip.size());
+
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point()).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
+
+ // Hide the browser controls by 10px. The outer clip should expand by 10px as
+ // well because the clip node doesn't account for the "resize to
+ // minimum-scale" that occurs for the outer viewport layer (hence, why the
+ // outer viewport layer is half the size of the inner in this test).
+ {
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 10.f)).get());
+ ASSERT_EQ(40, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(gfx::SizeF(50, 60), outer_clip_node->clip.size());
+ }
+
+ host_impl_->ScrollEnd(EndState().get());
+}
+
// Tests that browser controls affect the position of horizontal scrollbars.
TEST_F(LayerTreeHostImplBrowserControlsTest,
HidingBrowserControlsAdjustsScrollbarPosition) {
@@ -5874,8 +5891,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// bounds.
TEST_F(LayerTreeHostImplBrowserControlsTest,
PositionBrowserControlsExplicitly) {
- settings_ = DefaultSettings();
- CreateHostImpl(settings_, CreateLayerTreeFrameSink());
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
layer_size_, layer_size_, layer_size_);
DrawFrame();
@@ -5909,8 +5924,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// applied on sync tree activation. The total browser controls offset shouldn't
// change after the activation.
TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) {
- settings_ = DefaultSettings();
- CreateHostImpl(settings_, CreateLayerTreeFrameSink());
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
layer_size_, layer_size_, layer_size_);
DrawFrame();
@@ -5959,8 +5972,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) {
// the compositor to accommodate the browser controls.
TEST_F(LayerTreeHostImplBrowserControlsTest,
BrowserControlsLayoutHeightChanged) {
- settings_ = DefaultSettings();
- CreateHostImpl(settings_, CreateLayerTreeFrameSink());
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
layer_size_, layer_size_, layer_size_);
DrawFrame();
@@ -6197,8 +6208,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
TEST_F(LayerTreeHostImplBrowserControlsTest,
ScrollNonScrollableRootWithBrowserControls) {
- settings_ = DefaultSettings();
- CreateHostImpl(settings_, CreateLayerTreeFrameSink());
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
layer_size_, layer_size_, layer_size_);
DrawFrame();
@@ -6311,6 +6320,20 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
+ // The first animation frame will not produce any delta, it will establish
+ // the animation.
+ {
+ begin_frame_args.frame_time = start_time;
+ begin_frame_args.sequence_number++;
+ host_impl_->WillBeginImplFrame(begin_frame_args);
+ host_impl_->Animate();
+ host_impl_->UpdateAnimationState(true);
+ host_impl_->DidFinishImplFrame();
+ float delta =
+ host_impl_->active_tree()->top_controls_shown_ratio()->Delta();
+ ASSERT_EQ(delta, 0);
+ }
+
// Pump an animation frame to put some delta in the browser controls.
{
begin_frame_args.frame_time =
@@ -6535,7 +6558,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
EXPECT_EQ(viewport_size, root_container->bounds());
gfx::Vector2d scroll_delta(0, 10);
- gfx::Vector2d expected_scroll_delta = scroll_delta;
+ gfx::ScrollOffset expected_scroll_delta(scroll_delta);
LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer();
gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
EXPECT_EQ(
@@ -6582,7 +6605,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
EXPECT_EQ(viewport_size, root_container->bounds());
gfx::Vector2d scroll_delta(0, 10);
- gfx::Vector2d expected_scroll_delta = scroll_delta;
+ gfx::ScrollOffset expected_scroll_delta(scroll_delta);
LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer();
gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
EXPECT_EQ(
@@ -6687,7 +6710,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
DrawFrame();
gfx::Vector2d scroll_delta(0, 10);
- gfx::Vector2d expected_scroll_delta(scroll_delta);
+ gfx::ScrollOffset expected_scroll_delta(scroll_delta);
gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset());
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
@@ -6770,7 +6793,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
->children[0];
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
grand_child_layer->element_id(),
- gfx::Vector2d(0, -5)));
+ gfx::ScrollOffset(0, -5)));
// The child should not have scrolled.
ExpectNone(*scroll_info.get(), child->element_id());
@@ -6947,8 +6970,9 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
->test_properties()
->children[0];
LayerImpl* grand_child = child->test_properties()->children[0];
- EXPECT_TRUE(ScrollInfoContains(
- *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2)));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
+ grand_child->element_id(),
+ gfx::ScrollOffset(0, -2)));
// The child should not have scrolled.
ExpectNone(*scroll_info.get(), child->element_id());
@@ -6971,11 +6995,12 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
// The child should have scrolled up to its limit.
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(),
- gfx::Vector2d(0, -3)));
+ gfx::ScrollOffset(0, -3)));
// The grand child should not have scrolled.
- EXPECT_TRUE(ScrollInfoContains(
- *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2)));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
+ grand_child->element_id(),
+ gfx::ScrollOffset(0, -2)));
// After scrolling the parent, another scroll on the opposite direction
// should still scroll the child.
@@ -6995,12 +7020,13 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
scroll_info = host_impl_->ProcessScrollDeltas();
// The grand child should have scrolled.
- EXPECT_TRUE(ScrollInfoContains(
- *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 5)));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
+ grand_child->element_id(),
+ gfx::ScrollOffset(0, 5)));
// The child should not have scrolled.
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(),
- gfx::Vector2d(0, -3)));
+ gfx::ScrollOffset(0, -3)));
// Scrolling should be adjusted from viewport space.
host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
@@ -7020,8 +7046,9 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
scroll_info = host_impl_->ProcessScrollDeltas();
// Should have scrolled by half the amount in layer space (5 - 2/2)
- EXPECT_TRUE(ScrollInfoContains(
- *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 4)));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
+ grand_child->element_id(),
+ gfx::ScrollOffset(0, 4)));
}
}
TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
@@ -7064,13 +7091,15 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
host_impl_->active_tree()->SetDeviceViewportSize(surface_size);
DrawFrame();
{
- gfx::Vector2d scroll_delta(0, 4);
+ gfx::ScrollOffset scroll_delta(0, 4);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
InputHandler::WHEEL)
.thread);
- host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta))
+ .get());
host_impl_->ScrollEnd(EndState().get());
std::unique_ptr<ScrollAndScaleSet> scroll_info =
@@ -7200,18 +7229,21 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
// The layer should have scrolled down in its local coordinates.
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
- gfx::Vector2d(0, gesture_scroll_delta.x())));
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
+ gfx::ScrollOffset(0, gesture_scroll_delta.x())));
// Reset and scroll down with the wheel.
SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
- gfx::Vector2d wheel_scroll_delta(0, 10);
+ gfx::ScrollOffset wheel_scroll_delta(0, 10);
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
.thread);
- host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(
+ wheel_scroll_delta))
+ .get());
host_impl_->ScrollEnd(EndState().get());
// The layer should have scrolled down in its local coordinates.
@@ -7271,9 +7303,9 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
// The child layer should have scrolled down in its local coordinates an
// amount proportional to the angle between it and the input scroll delta.
- gfx::Vector2d expected_scroll_delta(
- 0,
- gesture_scroll_delta.y() * std::cos(gfx::DegToRad(child_layer_angle)));
+ gfx::ScrollOffset expected_scroll_delta(
+ 0, std::floor(gesture_scroll_delta.y() *
+ std::cos(gfx::DegToRad(child_layer_angle))));
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id,
@@ -7297,9 +7329,9 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
// The child layer should have scrolled down in its local coordinates an
// amount proportional to the angle between it and the input scroll delta.
- gfx::Vector2d expected_scroll_delta(
- 0,
- -gesture_scroll_delta.x() * std::sin(gfx::DegToRad(child_layer_angle)));
+ gfx::ScrollOffset expected_scroll_delta(
+ 0, std::floor(-gesture_scroll_delta.x() *
+ std::sin(gfx::DegToRad(child_layer_angle))));
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id,
@@ -7346,21 +7378,21 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
std::unique_ptr<ScrollAndScaleSet> scroll_info;
- gfx::Vector2d gesture_scroll_deltas[4];
- gesture_scroll_deltas[0] = gfx::Vector2d(4, 10);
- gesture_scroll_deltas[1] = gfx::Vector2d(4, 10);
- gesture_scroll_deltas[2] = gfx::Vector2d(10, 0);
- gesture_scroll_deltas[3] = gfx::Vector2d(10, 0);
+ gfx::ScrollOffset gesture_scroll_deltas[4];
+ gesture_scroll_deltas[0] = gfx::ScrollOffset(4, 10);
+ gesture_scroll_deltas[1] = gfx::ScrollOffset(4, 10);
+ gesture_scroll_deltas[2] = gfx::ScrollOffset(10, 0);
+ gesture_scroll_deltas[3] = gfx::ScrollOffset(10, 0);
- gfx::Vector2d expected_scroll_deltas[4];
+ gfx::ScrollOffset expected_scroll_deltas[4];
// Perspective affects the vertical delta by a different
// amount depending on the vertical position of the |viewport_point|.
- expected_scroll_deltas[0] = gfx::Vector2d(2, 9);
- expected_scroll_deltas[1] = gfx::Vector2d(1, 4);
+ expected_scroll_deltas[0] = gfx::ScrollOffset(2, 9);
+ expected_scroll_deltas[1] = gfx::ScrollOffset(1, 4);
// Deltas which start with the same vertical position of the
// |viewport_point| are subject to identical perspective effects.
- expected_scroll_deltas[2] = gfx::Vector2d(5, 0);
- expected_scroll_deltas[3] = gfx::Vector2d(5, 0);
+ expected_scroll_deltas[2] = gfx::ScrollOffset(5, 0);
+ expected_scroll_deltas[3] = gfx::ScrollOffset(5, 0);
gfx::Point viewport_point(1, 1);
@@ -7376,8 +7408,11 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(
- UpdateState(viewport_point, gesture_scroll_deltas[i]).get());
- viewport_point += gesture_scroll_deltas[i];
+ UpdateState(viewport_point,
+ gfx::ScrollOffsetToVector2dF(gesture_scroll_deltas[i]))
+ .get());
+ viewport_point +=
+ gfx::ScrollOffsetToFlooredVector2d(gesture_scroll_deltas[i]);
host_impl_->ScrollEnd(EndState().get());
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -7420,18 +7455,21 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
// amount.
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
- gfx::Vector2d(0, scroll_delta.y() / scale)));
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
+ gfx::ScrollOffset(0, scroll_delta.y() / scale)));
// Reset and scroll down with the wheel.
SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
- gfx::Vector2d wheel_scroll_delta(0, 10);
+ gfx::ScrollOffset wheel_scroll_delta(0, 10);
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
.thread);
- host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(
+ wheel_scroll_delta))
+ .get());
host_impl_->ScrollEnd(EndState().get());
// It should apply the scale factor to the scroll delta for the wheel event.
@@ -7600,7 +7638,8 @@ TEST_F(LayerTreeHostImplTest,
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
EXPECT_FALSE(frame.has_no_damage);
- CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset));
+ CheckLayerScrollDelta(scroll_layer,
+ gfx::ScrollOffsetToVector2dF(scroll_offset));
}
TEST_F(LayerTreeHostImplTest,
@@ -7638,7 +7677,7 @@ TEST_F(LayerTreeHostImplTest,
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(frame.has_no_damage);
CheckLayerScrollDelta(scroll_layer,
- ScrollOffsetToVector2dF(gfx::ScrollOffset()));
+ gfx::ScrollOffsetToVector2dF(gfx::ScrollOffset()));
}
TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
@@ -9284,8 +9323,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
root->test_properties()->AddChild(std::move(child));
layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
- layer_tree_host_impl->active_tree()->SetLocalSurfaceIdFromParent(
- viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
+ layer_tree_host_impl->active_tree()->SetLocalSurfaceIdAllocationFromParent(
+ viz::LocalSurfaceIdAllocation(
+ viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
+ base::TimeTicks::Now()));
TestFrameData frame;
@@ -9854,6 +9895,11 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
// RequiresHighResToDraw is set when new output surface is used.
EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
+ // The first commit will also set RequiresHighResToDraw due to the
+ // raster color space changing.
+ host_impl_->ResetRequiresHighResToDraw();
+ host_impl_->CommitComplete();
+ EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
host_impl_->ResetRequiresHighResToDraw();
host_impl_->SetContentHasSlowPaths(false);
@@ -10026,9 +10072,8 @@ class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
const viz::LocalSurfaceId& local_surface_id) override {}
void DisplayReceivedCompositorFrame(
const viz::CompositorFrame& frame) override {}
- void DisplayWillDrawAndSwap(
- bool will_draw_and_swap,
- const viz::RenderPassList& render_passes) override {}
+ void DisplayWillDrawAndSwap(bool will_draw_and_swap,
+ viz::RenderPassList* render_passes) override {}
void DisplayDidDrawAndSwap() override {}
private:
@@ -13737,7 +13782,8 @@ class TestRenderFrameMetadataObserver : public RenderFrameMetadataObserver {
void BindToCurrentThread() override {}
void OnRenderFrameSubmission(
const RenderFrameMetadata& render_frame_metadata,
- viz::CompositorFrameMetadata* compositor_frame_metadata) override {
+ viz::CompositorFrameMetadata* compositor_frame_metadata,
+ bool force_send) override {
if (increment_counter_)
compositor_frame_metadata->send_frame_token_to_embedder = true;
last_metadata_ = render_frame_metadata;
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 1c95b6fcf4e..9c800d93374 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -148,7 +148,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
void BuildTree() override {
gfx::Size viewport = gfx::Size(720, 1038);
layer_tree_host()->SetViewportSizeAndScale(viewport, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
scoped_refptr<Layer> root = ParseTreeFromJson(json_,
&fake_content_layer_client_);
ASSERT_TRUE(root.get());
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index 93dee1acd3d..39499795006 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -294,7 +294,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
RunPixelResourceTest(background, expected);
}
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
+TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
const int kRootWidth = 2;
const int kRootHeight = 2;
InitializeFromTestCase(resource_type());
@@ -302,7 +302,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
- // Orange child layers have a background filter set and they will blend with
+ // Orange child layers have a backdrop filter set and they will blend with
// the green background
gfx::Rect child_rect(0, 0, kRootWidth, kRootHeight);
scoped_refptr<SolidColorLayer> green_lane =
@@ -310,7 +310,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
background->AddChild(green_lane);
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
- green_lane->SetBackgroundFilters(filters);
+ green_lane->SetBackdropFilters(filters);
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 378d4338879..67e3b25aefc 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -19,11 +19,11 @@ namespace {
class LayerTreeHostFiltersPixelTest : public LayerTreePixelTest {};
-TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
+TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlur) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
- // The green box is entirely behind a layer with background blur, so it
+ // The green box is entirely behind a layer with backdrop blur, so it
// should appear blurred on its edges.
scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
gfx::Rect(50, 50, 100, 100), kCSSGreen);
@@ -35,7 +35,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(
2.f, SkBlurImageFilter::kClamp_TileMode));
- blur->SetBackgroundFilters(filters);
+ blur->SetBackdropFilters(filters);
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
// Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
@@ -53,17 +53,16 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
small_error_allowed));
#endif
- RunPixelTest(PIXEL_TEST_GL,
- background,
- base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png")));
+ RunPixelTest(PIXEL_TEST_GL, background,
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png")));
}
-TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
+TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
- // The green border is outside the layer with background blur, but the
- // background blur should use pixels from outside its layer borders, up to the
+ // The green border is outside the layer with backdrop blur, but the
+ // backdrop blur should use pixels from outside its layer borders, up to the
// radius of the blur effect. So the border should be blurred underneath the
// top layer causing the green to bleed under the transparent layer, but not
// in the 1px region between the transparent layer and the green border.
@@ -77,7 +76,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(
5.f, SkBlurImageFilter::kClamp_TileMode));
- blur->SetBackgroundFilters(filters);
+ blur->SetBackdropFilters(filters);
#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
@@ -101,12 +100,11 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
#endif
RunPixelTest(
- PIXEL_TEST_GL,
- background,
- base::FilePath(FILE_PATH_LITERAL("background_filter_blur_outsets.png")));
+ PIXEL_TEST_GL, background,
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_outsets.png")));
}
-TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
+TEST_F(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOffAxis) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT);
@@ -144,7 +142,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(
2.f, SkBlurImageFilter::kClamp_TileMode));
- blur->SetBackgroundFilters(filters);
+ blur->SetBackdropFilters(filters);
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -168,9 +166,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
#endif
RunPixelTest(
- PIXEL_TEST_GL,
- background,
- base::FilePath(FILE_PATH_LITERAL("background_filter_blur_off_axis.png")));
+ PIXEL_TEST_GL, background,
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis.png")));
}
class LayerTreeHostFiltersScaledPixelTest
@@ -384,7 +381,7 @@ TEST_F(ImageFilterNonZeroOriginPixelTest, ImageFilterNonZeroOrigin_Software) {
RunPixelTestType(PIXEL_TEST_SOFTWARE);
}
-class ImageScaledBackgroundFilter : public LayerTreeHostFiltersPixelTest {
+class ImageScaledBackdropFilter : public LayerTreeHostFiltersPixelTest {
protected:
void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) {
scoped_refptr<SolidColorLayer> background =
@@ -422,7 +419,7 @@ class ImageScaledBackgroundFilter : public LayerTreeHostFiltersPixelTest {
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
- filter->SetBackgroundFilters(filters);
+ filter->SetBackdropFilters(filters);
#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -451,19 +448,19 @@ class ImageScaledBackgroundFilter : public LayerTreeHostFiltersPixelTest {
}
};
-TEST_F(ImageScaledBackgroundFilter, ImageFilterScaled_GL) {
+TEST_F(ImageScaledBackdropFilter, ImageFilterScaled_GL) {
RunPixelTestType(PIXEL_TEST_GL,
base::FilePath(FILE_PATH_LITERAL(
- "background_filter_on_scaled_layer_gl.png")));
+ "backdrop_filter_on_scaled_layer_gl.png")));
}
-TEST_F(ImageScaledBackgroundFilter, ImageFilterScaled_Software) {
+TEST_F(ImageScaledBackdropFilter, ImageFilterScaled_Software) {
RunPixelTestType(PIXEL_TEST_SOFTWARE,
base::FilePath(FILE_PATH_LITERAL(
- "background_filter_on_scaled_layer_sw.png")));
+ "backdrop_filter_on_scaled_layer_sw.png")));
}
-class ImageBackgroundFilter : public LayerTreeHostFiltersPixelTest {
+class ImageBackdropFilter : public LayerTreeHostFiltersPixelTest {
protected:
void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) {
// Add a white background with a rotated red rect in the center.
@@ -499,7 +496,7 @@ class ImageBackgroundFilter : public LayerTreeHostFiltersPixelTest {
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(
5.0f, SkBlurImageFilter::kClamp_TileMode));
- filter->SetBackgroundFilters(filters);
+ filter->SetBackdropFilters(filters);
// Allow some fuzziness so that this doesn't fail when Skia makes minor
// changes to blur or rectangle rendering.
@@ -518,16 +515,16 @@ class ImageBackgroundFilter : public LayerTreeHostFiltersPixelTest {
}
};
-TEST_F(ImageBackgroundFilter, BackgroundFilterRotated_GL) {
+TEST_F(ImageBackdropFilter, BackdropFilterRotated_GL) {
RunPixelTestType(
PIXEL_TEST_GL,
- base::FilePath(FILE_PATH_LITERAL("background_filter_rotated_gl.png")));
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_rotated_gl.png")));
}
-TEST_F(ImageBackgroundFilter, BackgroundFilterRotated_Software) {
+TEST_F(ImageBackdropFilter, BackdropFilterRotated_Software) {
RunPixelTestType(
PIXEL_TEST_SOFTWARE,
- base::FilePath(FILE_PATH_LITERAL("background_filter_rotated_sw.png")));
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_rotated_sw.png")));
}
class ImageScaledRenderSurface : public LayerTreeHostFiltersPixelTest {
@@ -615,7 +612,7 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
FilterOperations border_filters;
border_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
- border_edge_zoom->SetBackgroundFilters(border_filters);
+ border_edge_zoom->SetBackdropFilters(border_filters);
root->AddChild(border_edge_zoom);
// Test a zoom that extends past the edge of the screen.
@@ -624,7 +621,7 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
FilterOperations top_filters;
top_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
- top_edge_zoom->SetBackgroundFilters(top_filters);
+ top_edge_zoom->SetBackdropFilters(top_filters);
root->AddChild(top_edge_zoom);
// Test a zoom that is fully within the screen.
@@ -633,7 +630,7 @@ class ZoomFilterTest : public LayerTreeHostFiltersPixelTest {
FilterOperations mid_filters;
mid_filters.Append(
FilterOperation::CreateZoomFilter(2.f /* zoom */, 0 /* inset */));
- contained_zoom->SetBackgroundFilters(mid_filters);
+ contained_zoom->SetBackdropFilters(mid_filters);
root->AddChild(contained_zoom);
#if defined(OS_WIN)
@@ -1056,7 +1053,7 @@ TEST_F(FilterWithGiantCropRectNoClip, GL) {
base::FilePath(FILE_PATH_LITERAL("filter_with_giant_crop_rect.png")));
}
-class BackgroundFilterWithDeviceScaleFactorTest
+class BackdropFilterWithDeviceScaleFactorTest
: public LayerTreeHostFiltersPixelTest {
protected:
void RunPixelTestType(float device_scale_factor,
@@ -1076,7 +1073,7 @@ class BackgroundFilterWithDeviceScaleFactorTest
FilterOperations filters;
filters.Append(FilterOperation::CreateReferenceFilter(
sk_make_sp<OffsetPaintFilter>(0, 80, nullptr)));
- filtered->SetBackgroundFilters(filters);
+ filtered->SetBackdropFilters(filters);
root->AddChild(filtered);
// This should appear as a grid of 4 100x100 squares which are:
@@ -1102,28 +1099,28 @@ class BackgroundFilterWithDeviceScaleFactorTest
float device_scale_factor_ = 1;
};
-TEST_F(BackgroundFilterWithDeviceScaleFactorTest, StandardDpi_GL) {
+TEST_F(BackdropFilterWithDeviceScaleFactorTest, StandardDpi_GL) {
RunPixelTestType(
1.f, PIXEL_TEST_GL,
- base::FilePath(FILE_PATH_LITERAL("offset_background_filter_1x.png")));
+ base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_1x.png")));
}
-TEST_F(BackgroundFilterWithDeviceScaleFactorTest, StandardDpi_Software) {
+TEST_F(BackdropFilterWithDeviceScaleFactorTest, StandardDpi_Software) {
RunPixelTestType(
1.f, PIXEL_TEST_SOFTWARE,
- base::FilePath(FILE_PATH_LITERAL("offset_background_filter_1x.png")));
+ base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_1x.png")));
}
-TEST_F(BackgroundFilterWithDeviceScaleFactorTest, HiDpi_GL) {
+TEST_F(BackdropFilterWithDeviceScaleFactorTest, HiDpi_GL) {
RunPixelTestType(
2.f, PIXEL_TEST_GL,
- base::FilePath(FILE_PATH_LITERAL("offset_background_filter_2x.png")));
+ base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_2x.png")));
}
-TEST_F(BackgroundFilterWithDeviceScaleFactorTest, HiDpi_Software) {
+TEST_F(BackdropFilterWithDeviceScaleFactorTest, HiDpi_Software) {
RunPixelTestType(
2.f, PIXEL_TEST_SOFTWARE,
- base::FilePath(FILE_PATH_LITERAL("offset_background_filter_2x.png")));
+ base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_2x.png")));
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 6732d5e21a6..4639cb3cd2e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -267,19 +267,19 @@ class CircleContentLayerClient : public ContentLayerClient {
gfx::Size bounds_;
};
-using LayerTreeHostMasksForBackgroundFiltersPixelTest =
+using LayerTreeHostMasksForBackdropFiltersPixelTest =
ParameterizedPixelResourceTest;
INSTANTIATE_TEST_CASE_P(
PixelResourceTest,
- LayerTreeHostMasksForBackgroundFiltersPixelTest,
+ LayerTreeHostMasksForBackdropFiltersPixelTest,
::testing::Combine(
::testing::Values(SOFTWARE, GPU, ONE_COPY, ZERO_COPY),
::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK,
Layer::LayerMaskType::MULTI_TEXTURE_MASK)));
-TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
- MaskOfLayerWithBackgroundFilter) {
+TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
+ MaskOfLayerWithBackdropFilter) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(100, 100), SK_ColorWHITE);
@@ -296,7 +296,7 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
- blur->SetBackgroundFilters(filters);
+ blur->SetBackdropFilters(filters);
gfx::Size mask_bounds(100, 100);
CircleContentLayerClient mask_client(mask_bounds);
@@ -322,14 +322,12 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
base::FilePath image_name =
(test_case_ == GPU)
- ? base::FilePath(
- FILE_PATH_LITERAL("mask_of_background_filter_gpu.png"))
- : base::FilePath(FILE_PATH_LITERAL("mask_of_background_filter.png"));
+ ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png"))
+ : base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter.png"));
RunPixelResourceTest(background, image_name);
}
-TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
- MaskOfLayerWithBlend) {
+TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(128, 128), SK_ColorWHITE);
@@ -733,8 +731,8 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
RunPixelResourceTest(root, image_name);
}
-TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
- MaskOfLayerWithBackgroundFilterAndBlend) {
+TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
+ MaskOfLayerWithBackdropFilterAndBlend) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE);
@@ -757,7 +755,7 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
- picture_horizontal->SetBackgroundFilters(filters);
+ picture_horizontal->SetBackdropFilters(filters);
background->AddChild(picture_vertical);
background->AddChild(picture_horizontal);
@@ -783,7 +781,7 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
RunPixelResourceTest(background,
base::FilePath(FILE_PATH_LITERAL(
- "mask_of_background_filter_and_blend.png")));
+ "mask_of_backdrop_filter_and_blend.png")));
}
} // namespace
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 416b5de8bd6..a648ed5a45e 100644
--- a/chromium/cc/trees/layer_tree_host_single_thread_client.h
+++ b/chromium/cc/trees/layer_tree_host_single_thread_client.h
@@ -5,6 +5,8 @@
#ifndef CC_TREES_LAYER_TREE_HOST_SINGLE_THREAD_CLIENT_H_
#define CC_TREES_LAYER_TREE_HOST_SINGLE_THREAD_CLIENT_H_
+#include "base/time/time.h"
+
namespace cc {
class LayerTreeHostSingleThreadClient {
@@ -15,6 +17,10 @@ class LayerTreeHostSingleThreadClient {
// delay for potential future frame.
virtual void RequestScheduleAnimation() {}
+ // Called whenever the begin frame interval changes. This interval can be used
+ // for animations.
+ virtual void FrameIntervalUpdated(base::TimeDelta interval) {}
+
// Called whenever the compositor submits a CompositorFrame. Afterward,
// LayerTreeHostClient::DidReceiveCompositorFrameAck() will be called once the
// display compositor/ finishes processing the frame. So these functions can
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index d71fdf95d32..97e682c6c82 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -16,6 +16,7 @@
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/animation/timing_function.h"
#include "cc/input/scroll_elasticity_helper.h"
@@ -1316,7 +1317,7 @@ class LayerTreeHostTestNoDamageCausesNoInvalidate : public LayerTreeHostTest {
root_ = Layer::Create();
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->SetRootLayer(root_);
@@ -1413,7 +1414,7 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
root_->AddChild(child_);
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(100, 100), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->SetRootLayer(root_);
root_->SetBounds(gfx::Size(50, 50));
@@ -1501,7 +1502,7 @@ class LayerTreeHostTestPrepareTilesWithoutDraw : public LayerTreeHostTest {
layer_tree_host()->root_layer()->AddChild(child_layer_);
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->root_layer()->SetBounds(gfx::Size(50, 50));
child_layer_->SetBounds(gfx::Size(50, 50));
@@ -2333,7 +2334,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
root_layer_->SetBounds(bounds_);
layer_tree_host()->SetRootLayer(root_layer_);
layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
client_.set_bounds(root_layer_->bounds());
}
@@ -2398,7 +2399,7 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
root_layer_->SetBounds(bounds_);
layer_tree_host()->SetRootLayer(root_layer_);
layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
client_.set_bounds(root_layer_->bounds());
@@ -2433,8 +2434,8 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
void DidCommitAndDrawFrame() override {
// On the second commit, resize the viewport.
if (num_draws_ == 1) {
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(400, 64), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(400, 64), 1.f, viz::LocalSurfaceIdAllocation());
}
if (num_draws_ < 2) {
layer_tree_host()->SetNeedsRedrawRect(invalid_rect_);
@@ -2549,7 +2550,7 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
// a second commit as a result.
layer_tree_host()->SetViewportSizeAndScale(
layer_tree_host()->device_viewport_size(), 4.f,
- layer_tree_host()->local_surface_id_from_parent());
+ layer_tree_host()->local_surface_id_allocation_from_parent());
break;
default:
// No extra commits.
@@ -2594,7 +2595,7 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest {
if (layer_tree_host()->SourceFrameNumber() == 1) {
layer_tree_host()->SetViewportSizeAndScale(
layer_tree_host()->device_viewport_size(), 4.f,
- layer_tree_host()->local_surface_id_from_parent());
+ layer_tree_host()->local_surface_id_allocation_from_parent());
}
}
@@ -2773,7 +2774,7 @@ class LayerTreeHostTestSetNeedsCommitWithForcedRedraw
root_layer_->SetBounds(bounds_);
layer_tree_host()->SetRootLayer(root_layer_);
layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
client_.set_bounds(root_layer_->bounds());
}
@@ -3062,7 +3063,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest {
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->set_background_color(SK_ColorGRAY);
layer_tree_host()->SetEventListenerProperties(
EventListenerClass::kMouseWheel, EventListenerProperties::kPassive);
@@ -3110,7 +3111,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->set_background_color(SK_ColorGRAY);
PostSetNeedsCommitToMainThread();
@@ -3164,7 +3165,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->set_background_color(SK_ColorGRAY);
PostSetNeedsCommitToMainThread();
@@ -3236,8 +3237,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
gfx::ScrollOffset offset = scroll_layer_->CurrentScrollOffset();
- scroll_layer_->SetScrollOffset(
- ScrollOffsetWithDelta(offset, args.inner_delta));
+ scroll_layer_->SetScrollOffset(offset + args.inner_delta);
layer_tree_host()->SetPageScaleFactorAndLimits(args.page_scale_delta, 0.5f,
2.f);
}
@@ -3323,7 +3323,7 @@ class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest {
void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
EXPECT_TRUE(sent_gesture_);
- EXPECT_EQ(gfx::Vector2dF(50, 50), args.inner_delta);
+ EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta);
EXPECT_EQ(2, args.page_scale_delta);
auto* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer();
@@ -3379,7 +3379,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
child_layer_ = FakePictureLayer::Create(&client_);
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(60, 60), 1.5f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
root_layer_->AddChild(child_layer_);
@@ -3476,7 +3476,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
layer_ = FakePictureLayer::Create(&client_);
@@ -3520,13 +3520,13 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
-class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
+class LayerTreeHostTestDeferMainFrameUpdate : public LayerTreeHostTest {
public:
- LayerTreeHostTestDeferCommits() = default;
+ LayerTreeHostTestDeferMainFrameUpdate() = default;
void BeginTest() override {
// Start with commits deferred.
- PostGetDeferCommitsToMainThread(&scoped_defer_commits_);
+ PostGetDeferMainFrameUpdateToMainThread(&scoped_defer_main_frame_update_);
PostSetNeedsCommitToMainThread();
}
@@ -3549,7 +3549,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
FROM_HERE,
// Unretained because the test should not end before allowing
// commits via this running.
- base::BindOnce(&LayerTreeHostTestDeferCommits::AllowCommits,
+ base::BindOnce(&LayerTreeHostTestDeferMainFrameUpdate::AllowCommits,
base::Unretained(this)));
break;
default:
@@ -3560,7 +3560,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
}
void WillBeginMainFrame() override {
- EXPECT_FALSE(scoped_defer_commits_);
+ EXPECT_FALSE(scoped_defer_main_frame_update_);
EXPECT_TRUE(IsCommitAllowed());
num_send_begin_main_frame_++;
EndTest();
@@ -3573,24 +3573,24 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
virtual void AllowCommits() {
allow_commits_ = true;
- scoped_defer_commits_.reset();
+ scoped_defer_main_frame_update_.reset();
}
virtual bool IsCommitAllowed() const { return allow_commits_; }
private:
- std::unique_ptr<ScopedDeferCommits> scoped_defer_commits_;
+ std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
bool allow_commits_ = false;
int num_will_begin_impl_frame_ = 0;
int num_send_begin_main_frame_ = 0;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferMainFrameUpdate);
// This verifies that changing the size of a LayerTreeHost without providing a
// LocalSurfaceId defers commits.
class LayerTreeHostInvalidLocalSurfaceIdDefersCommit
- : public LayerTreeHostTestDeferCommits {
+ : public LayerTreeHostTestDeferMainFrameUpdate {
public:
LayerTreeHostInvalidLocalSurfaceIdDefersCommit() = default;
void InitializeSettings(LayerTreeSettings* settings) override {
@@ -3605,15 +3605,17 @@ class LayerTreeHostInvalidLocalSurfaceIdDefersCommit
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void AllowCommits() override {
- local_surface_id_ = allocator_.GenerateId();
- PostSetLocalSurfaceIdToMainThread(local_surface_id_);
+ allocator_.GenerateId();
+ PostSetLocalSurfaceIdAllocationToMainThread(
+ allocator_.GetCurrentLocalSurfaceIdAllocation());
}
- bool IsCommitAllowed() const override { return local_surface_id_.is_valid(); }
+ bool IsCommitAllowed() const override {
+ return allocator_.GetCurrentLocalSurfaceIdAllocation().IsValid();
+ }
private:
viz::ParentLocalSurfaceIdAllocator allocator_;
- viz::LocalSurfaceId local_surface_id_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostInvalidLocalSurfaceIdDefersCommit);
@@ -3621,10 +3623,13 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostInvalidLocalSurfaceIdDefersCommit);
// This verifies that we can abort a commit inside the main frame, and
// we don't leave any weird states around if we never allow the commit
// to happen.
-class LayerTreeHostTestDeferCommitsInsideBeginMainFrame
+// TODO(schenney): This should be renamed back to
+// LayerTreeHostTestDeferCommitInsideBeginMainFrame when we re-create
+// the concept of defer commit when not defering main frame updates.
+class LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame
: public LayerTreeHostTest {
public:
- LayerTreeHostTestDeferCommitsInsideBeginMainFrame() = default;
+ LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame() = default;
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -3632,7 +3637,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrame
++begin_main_frame_count_;
// This should prevent the commit from happening.
- scoped_defer_commits_ = layer_tree_host()->DeferCommits();
+ scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
// Wait to see if the commit happens. It's possible the deferred
// commit happens when it shouldn't but takes long enough that
// this passes. But it won't fail when it shouldn't.
@@ -3651,20 +3656,24 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrame
}
private:
- std::unique_ptr<ScopedDeferCommits> scoped_defer_commits_;
+ std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
int commit_count_ = 0;
int begin_main_frame_count_ = 0;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostTestDeferCommitsInsideBeginMainFrame);
+ LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame);
// This verifies that we can abort a commit inside the main frame, and
// we will finish the commit once it is allowed.
-class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
+// TODO(schenney): This should be renamed back to
+// LayerTreeHostTestDeferCommitInsideBeginMainFrameWithCommitAfter when
+// we re-create the concept of defer commit when not defering main frame
+// updates.
+class LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter
: public LayerTreeHostTest {
public:
- LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter() = default;
+ LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter() = default;
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -3674,7 +3683,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
return;
// This should prevent the commit from happening.
- scoped_defer_commits_ = layer_tree_host()->DeferCommits();
+ scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
// Wait to see if the commit happens. It's possible the deferred
// commit happens when it shouldn't but takes long enough that
// this passes. But it won't fail when it shouldn't.
@@ -3682,7 +3691,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
FROM_HERE,
// Unretained because the test doesn't end before this runs.
base::BindOnce(
- &LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter::
+ &LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter::
AllowCommits,
base::Unretained(this)),
base::TimeDelta::FromMilliseconds(100));
@@ -3692,7 +3701,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
// Once we've waited and seen that commit did not happen, we
// allow commits and should see this one go through.
allow_commits_ = true;
- scoped_defer_commits_.reset();
+ scoped_defer_main_frame_update_.reset();
}
void DidCommit() override {
@@ -3713,7 +3722,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
}
private:
- std::unique_ptr<ScopedDeferCommits> scoped_defer_commits_;
+ std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
bool allow_commits_ = false;
int commit_count_ = 0;
int begin_main_frame_count_ = 0;
@@ -3721,7 +3730,7 @@ class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
};
SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter);
+ LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter);
// This verifies that animate_only BeginFrames only run animation/layout
// updates, i.e. abort commits after the paint stage and only request layer
@@ -4480,8 +4489,8 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
++expected_push_properties_grandchild_;
break;
case 10:
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(20, 20), 1.f, viz::LocalSurfaceIdAllocation());
// No layers need commit.
break;
case 11:
@@ -5503,7 +5512,7 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
// The viewport is empty, but we still need to update layers on the main
// thread.
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(0, 0), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
}
@@ -5835,7 +5844,7 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest {
layer_tree_host()->SetRootLayer(layer_);
gfx::Size bounds(100, 100);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
}
@@ -5932,7 +5941,7 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest {
layer_tree_host()->SetRootLayer(layer_);
gfx::Size bounds(100, 100);
layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
}
@@ -6873,13 +6882,13 @@ class LayerTreeHostTestRenderSurfaceEffectTreeIndex : public LayerTreeHostTest {
case 2:
// Setting an empty viewport causes draws to get skipped, so the active
// tree won't update draw properties.
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation());
child_->SetForceRenderSurfaceForTesting(false);
break;
case 3:
- layer_tree_host()->SetViewportSizeAndScale(root_->bounds(), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ root_->bounds(), 1.f, viz::LocalSurfaceIdAllocation());
}
}
@@ -7019,6 +7028,8 @@ class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
EXPECT_EQ(info_.page_scale_delta, args.page_scale_delta);
EXPECT_EQ(info_.top_controls_delta, args.browser_controls_delta);
+ EXPECT_EQ(info_.browser_controls_constraint,
+ args.browser_controls_constraint);
deltas_sent_to_client_ = true;
}
@@ -7316,7 +7327,7 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
layer_tree_host()->SetRootLayer(root);
LayerTreeHostTest::SetupTree();
layer_tree_host()->SetViewportSizeAndScale(viewport_size_, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
client_.set_bounds(root->bounds());
}
@@ -7542,7 +7553,7 @@ class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(16, 16), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
PostSetNeedsCommitToMainThread();
}
@@ -7914,28 +7925,33 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
}
void BeginTest() override {
- expected_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
- PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_);
+ allocator_.GenerateId();
+ expected_local_surface_id_allocation_ =
+ allocator_.GetCurrentLocalSurfaceIdAllocation();
+ PostSetLocalSurfaceIdAllocationToMainThread(
+ expected_local_surface_id_allocation_);
}
DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
LayerTreeHostImpl::FrameData* frame_data,
DrawResult draw_result) override {
EXPECT_EQ(DRAW_SUCCESS, draw_result);
- EXPECT_EQ(expected_local_surface_id_,
- host_impl->active_tree()->local_surface_id_from_parent());
+ EXPECT_EQ(
+ expected_local_surface_id_allocation_,
+ host_impl->active_tree()->local_surface_id_allocation_from_parent());
return draw_result;
}
void DisplayReceivedLocalSurfaceIdOnThread(
const viz::LocalSurfaceId& local_surface_id) override {
- EXPECT_EQ(expected_local_surface_id_, local_surface_id);
+ EXPECT_EQ(expected_local_surface_id_allocation_.local_surface_id(),
+ local_surface_id);
EndTest();
}
void AfterTest() override {}
- viz::LocalSurfaceId expected_local_surface_id_;
+ viz::LocalSurfaceIdAllocation expected_local_surface_id_allocation_;
viz::ParentLocalSurfaceIdAllocator allocator_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
@@ -7949,12 +7965,20 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest {
}
void BeginTest() override {
- expected_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
- EXPECT_TRUE(child_allocator_.UpdateFromParent(expected_local_surface_id_));
- child_local_surface_id_ = child_allocator_.GenerateId();
- EXPECT_NE(expected_local_surface_id_, child_local_surface_id_);
- PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_);
- PostSetLocalSurfaceIdToMainThread(child_local_surface_id_);
+ allocator_.GenerateId();
+ expected_local_surface_id_allocation_ =
+ 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,
@@ -7962,21 +7986,23 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest {
DrawResult draw_result) override {
EXPECT_EQ(DRAW_SUCCESS, draw_result);
// We should not be picking up the newer |child_local_surface_id_|.
- EXPECT_EQ(expected_local_surface_id_,
- host_impl->active_tree()->local_surface_id_from_parent());
+ EXPECT_EQ(
+ expected_local_surface_id_allocation_,
+ host_impl->active_tree()->local_surface_id_allocation_from_parent());
return draw_result;
}
void DisplayReceivedLocalSurfaceIdOnThread(
const viz::LocalSurfaceId& local_surface_id) override {
- EXPECT_EQ(expected_local_surface_id_, local_surface_id);
+ EXPECT_EQ(expected_local_surface_id_allocation_.local_surface_id(),
+ local_surface_id);
EndTest();
}
void AfterTest() override {}
- viz::LocalSurfaceId expected_local_surface_id_;
- viz::LocalSurfaceId child_local_surface_id_;
+ viz::LocalSurfaceIdAllocation expected_local_surface_id_allocation_;
+ viz::LocalSurfaceIdAllocation child_local_surface_id_allocation_;
viz::ParentLocalSurfaceIdAllocator allocator_;
viz::ChildLocalSurfaceIdAllocator child_allocator_;
};
@@ -7991,8 +8017,11 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
}
void BeginTest() override {
- expected_parent_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
- PostSetLocalSurfaceIdToMainThread(expected_parent_local_surface_id_);
+ allocator_.GenerateId();
+ expected_parent_local_surface_id_allocation_ =
+ allocator_.GetCurrentLocalSurfaceIdAllocation();
+ PostSetLocalSurfaceIdAllocationToMainThread(
+ expected_parent_local_surface_id_allocation_);
PostRequestNewLocalSurfaceIdToMainThread();
}
@@ -8000,18 +8029,21 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
LayerTreeHostImpl::FrameData* frame_data,
DrawResult draw_result) override {
EXPECT_EQ(DRAW_SUCCESS, draw_result);
- EXPECT_EQ(expected_parent_local_surface_id_,
- host_impl->active_tree()->local_surface_id_from_parent());
+ EXPECT_EQ(
+ expected_parent_local_surface_id_allocation_,
+ host_impl->active_tree()->local_surface_id_allocation_from_parent());
return draw_result;
}
void DisplayReceivedLocalSurfaceIdOnThread(
const viz::LocalSurfaceId& local_surface_id) override {
+ const viz::LocalSurfaceId& expected_parent_local_surface_id =
+ expected_parent_local_surface_id_allocation_.local_surface_id();
viz::LocalSurfaceId child_local_surface_id(
- expected_parent_local_surface_id_.parent_sequence_number(),
- expected_parent_local_surface_id_.child_sequence_number() + 1,
- expected_parent_local_surface_id_.embed_token());
- EXPECT_NE(expected_parent_local_surface_id_, local_surface_id);
+ expected_parent_local_surface_id.parent_sequence_number(),
+ expected_parent_local_surface_id.child_sequence_number() + 1,
+ expected_parent_local_surface_id.embed_token());
+ EXPECT_NE(expected_parent_local_surface_id, local_surface_id);
EXPECT_EQ(child_local_surface_id, local_surface_id);
}
@@ -8025,7 +8057,7 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
void AfterTest() override {}
- viz::LocalSurfaceId expected_parent_local_surface_id_;
+ viz::LocalSurfaceIdAllocation expected_parent_local_surface_id_allocation_;
viz::ParentLocalSurfaceIdAllocator allocator_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestNewLocalSurfaceId);
@@ -8071,7 +8103,7 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest {
layer_tree_host()->SetRootLayer(root);
LayerTreeHostTest::SetupTree();
layer_tree_host()->SetViewportSizeAndScale(viewport_size_, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
client_.set_bounds(root->bounds());
}
@@ -8311,8 +8343,7 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)),
SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
- SkMatrix::I(), PaintImage::kDefaultFrameIndex,
- gfx::ColorSpace());
+ SkMatrix::I(), PaintImage::kDefaultFrameIndex);
auto callback =
base::Bind(&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
base::Unretained(this));
@@ -8880,17 +8911,22 @@ class LayerTreeHostTestNewLocalSurfaceIdForcesDraw : public LayerTreeHostTest {
void BeginTest() override {
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
- local_surface_id_ = allocator_.GenerateId();
- PostSetLocalSurfaceIdToMainThread(local_surface_id_);
+ allocator_.GenerateId();
+ local_surface_id_allocation_ =
+ allocator_.GetCurrentLocalSurfaceIdAllocation();
+ PostSetLocalSurfaceIdAllocationToMainThread(local_surface_id_allocation_);
}
void DidReceiveCompositorFrameAck() override {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
- local_surface_id_ = allocator_.GenerateId();
- PostSetLocalSurfaceIdToMainThread(local_surface_id_);
+ allocator_.GenerateId();
+ local_surface_id_allocation_ =
+ allocator_.GetCurrentLocalSurfaceIdAllocation();
+ PostSetLocalSurfaceIdAllocationToMainThread(
+ local_surface_id_allocation_);
break;
case 2:
EndTest();
@@ -8901,7 +8937,7 @@ class LayerTreeHostTestNewLocalSurfaceIdForcesDraw : public LayerTreeHostTest {
}
void AfterTest() override {}
- viz::LocalSurfaceId local_surface_id_;
+ viz::LocalSurfaceIdAllocation local_surface_id_allocation_;
viz::ParentLocalSurfaceIdAllocator allocator_;
};
@@ -8942,5 +8978,92 @@ class DidReceiveCompositorFrameAckNotSentWhenNotNeeded
SINGLE_AND_MULTI_THREAD_TEST_F(
DidReceiveCompositorFrameAckNotSentWhenNotNeeded);
+// Confirms that requests to force send RFM are forwarded once (and exactly
+// once) to the RFM observer. Does this by drawing 3 frames and requesting
+// force send from only the second then validating the request.
+class LayerTreeHostTestRequestForceSendMetadata
+ : public LayerTreeHostTest,
+ public RenderFrameMetadataObserver {
+ public:
+ // Provides a wrapper which can be passed to LayerTreeHost, but just forwards
+ // to the test class.
+ class ForwardingRenderFrameMetadataObserver
+ : public RenderFrameMetadataObserver {
+ public:
+ explicit ForwardingRenderFrameMetadataObserver(
+ RenderFrameMetadataObserver* target)
+ : target_(target) {}
+
+ // RenderFrameMetadataObserver implementation.
+ void BindToCurrentThread() override { target_->BindToCurrentThread(); }
+ void OnRenderFrameSubmission(
+ const RenderFrameMetadata& render_frame_metadata,
+ viz::CompositorFrameMetadata* compositor_frame_metadata,
+ bool force_send) override {
+ target_->OnRenderFrameSubmission(render_frame_metadata,
+ compositor_frame_metadata, force_send);
+ }
+
+ private:
+ RenderFrameMetadataObserver* target_ = nullptr;
+ };
+
+ LayerTreeHostTestRequestForceSendMetadata() = default;
+
+ void BeginTest() override {
+ // Just set up a basic frame which can be repeatedly re-drawn.
+ layer_tree_host()->SetRenderFrameObserver(
+ std::make_unique<ForwardingRenderFrameMetadataObserver>(this));
+ layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f,
+ viz::LocalSurfaceIdAllocation());
+ layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
+
+ layer_ = FakePictureLayer::Create(&client_);
+ layer_->SetBounds(gfx::Size(10, 10));
+ layer_->SetPosition(gfx::PointF(0.f, 0.f));
+ layer_->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(layer_);
+
+ PostSetNeedsCommitToMainThread();
+ client_.set_bounds(layer_->bounds());
+ }
+
+ void DidCommitAndDrawFrame() override {
+ // Draw three frames, sending a request to force send metadata on the
+ // middle (second) frame.
+ if (num_draw_layers_ == 3)
+ return;
+ if (num_draw_layers_ == 2)
+ layer_tree_host()->RequestForceSendMetadata();
+ layer_->SetNeedsDisplay();
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ num_draw_layers_++;
+ if (num_draw_layers_ == 3)
+ EndTest();
+ }
+
+ void AfterTest() override { EXPECT_EQ(1, num_force_sends_); }
+
+ // RenderFrameMetadataObserver implementation. Called on thread.
+ void BindToCurrentThread() override {}
+ void OnRenderFrameSubmission(
+ const RenderFrameMetadata& render_frame_metadata,
+ viz::CompositorFrameMetadata* compositor_frame_metadata,
+ bool force_send) override {
+ if (force_send)
+ num_force_sends_++;
+ }
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<Layer> layer_;
+ int num_draw_layers_ = 0;
+ int num_force_sends_ = 0;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestForceSendMetadata);
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 4f0c551c681..a871ac9d1a9 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -818,30 +818,46 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
root_->AddChild(child_);
child_->AddChild(grandchild_);
- layer_tree_host()->SetRootLayer(root_);
LayerTreeHostContextTest::SetupTree();
client_.set_bounds(root_->bounds());
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+ void AttachTree() { layer_tree_host()->SetRootLayer(root_); }
+
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl);
+ ++num_commits_;
+
FakePictureLayerImpl* root_picture = nullptr;
FakePictureLayerImpl* child_picture = nullptr;
FakePictureLayerImpl* grandchild_picture = nullptr;
-
- root_picture = static_cast<FakePictureLayerImpl*>(
- host_impl->active_tree()->root_layer_for_testing());
- child_picture = static_cast<FakePictureLayerImpl*>(
- host_impl->active_tree()->LayerById(child_->id()));
- grandchild_picture = static_cast<FakePictureLayerImpl*>(
- host_impl->active_tree()->LayerById(grandchild_->id()));
-
- ++num_commits_;
+ // Root layer isn't attached on first activation so the static_cast will
+ // fail before second activation.
+ if (num_commits_ >= 2) {
+ root_picture = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->root_layer_for_testing());
+ child_picture = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(child_->id()));
+ grandchild_picture = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(grandchild_->id()));
+ }
switch (num_commits_) {
case 1:
+ // Because setting the colorspace on the first activation releases
+ // resources, don't attach the layers until the first activation.
+ // Because of single thread vs multi thread differences (i.e.
+ // commit to active tree), if this delay is not done, then the
+ // active tree layers will have a different number of resource
+ // releasing.
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostContextTestLayersNotified::AttachTree,
+ base::Unretained(this)));
+ break;
+ case 2:
EXPECT_EQ(0u, root_picture->release_resources_count());
EXPECT_EQ(0u, child_picture->release_resources_count());
EXPECT_EQ(0u, grandchild_picture->release_resources_count());
@@ -850,7 +866,7 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
LoseContext();
times_to_fail_create_ = 1;
break;
- case 2:
+ case 3:
EXPECT_TRUE(root_picture->release_resources_count());
EXPECT_TRUE(child_picture->release_resources_count());
EXPECT_TRUE(grandchild_picture->release_resources_count());
@@ -1617,14 +1633,19 @@ class TileResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ auto* context_provider = static_cast<viz::TestContextProvider*>(
+ impl->layer_tree_frame_sink()->worker_context_provider());
+ viz::TestSharedImageInterface* sii =
+ context_provider->SharedImageInterface();
switch (impl->active_tree()->source_frame_number()) {
case 0:
// The PicturLayer has a texture for a tile, that has been exported to
// the display compositor now.
EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
EXPECT_EQ(1u, impl->resource_pool()->resource_count());
- // Shows that the tile texture is allocated with the current context.
- num_textures_ = gl_->NumTextures();
+ // Shows that the tile texture is allocated with the current worker
+ // context.
+ num_textures_ = sii->shared_image_count();
EXPECT_GT(num_textures_, 0u);
// Lose the LayerTreeFrameSink connection. The tile resource should
@@ -1638,8 +1659,8 @@ class TileResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
EXPECT_EQ(1u, impl->resource_pool()->resource_count());
// Shows that the replacement tile texture is re-allocated with the
- // current context, not just the previous one.
- EXPECT_EQ(num_textures_, gl_->NumTextures());
+ // current worker context, not just the previous one.
+ EXPECT_EQ(num_textures_, sii->shared_image_count());
EndTest();
}
}
@@ -1736,9 +1757,12 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
return;
deferred_ = true;
- // Defer commits before the BeginFrame completes, causing it to be delayed.
- scoped_defer_commits_ = layer_tree_host()->DeferCommits();
- // Meanwhile, lose the context while we are in defer commits.
+ // TODO(schenney): This should switch back to defer_commits_ because there
+ // is no way in the real code to start deferring main frame updates when
+ // inside WillBeginMainFrame. Defer commits before the BeginFrame completes,
+ // causing it to be delayed.
+ scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
+ // Meanwhile, lose the context while we are in defer BeginMainFrame.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&LayerTreeHostContextTestLoseAfterSendingBeginMainFrame::
@@ -1746,8 +1770,8 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
base::Unretained(this)));
// After the first frame, we will lose the context and then not start
- // allowing commits until that happens. The 2nd frame should not happen
- // before DidInitializeLayerTreeFrameSink occurs.
+ // lifecycle updates and commits until that happens. The 2nd frame should
+ // not happen before DidInitializeLayerTreeFrameSink occurs.
lost_ = true;
}
@@ -1759,15 +1783,18 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
void LoseContextOnImplThread() {
LoseContext();
+ // TODO(schenney): This should switch back to defer_commits_ to match the
+ // change above.
// After losing the context, stop deferring commits.
- PostReturnDeferCommitsToMainThread(std::move(scoped_defer_commits_));
+ PostReturnDeferMainFrameUpdateToMainThread(
+ std::move(scoped_defer_main_frame_update_));
}
void DidCommitAndDrawFrame() override { EndTest(); }
void AfterTest() override {}
- std::unique_ptr<ScopedDeferCommits> scoped_defer_commits_;
+ std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
bool deferred_ = false;
bool lost_ = true;
};
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 83daa78f332..2bc31da1d37 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -7,6 +7,7 @@
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
@@ -336,8 +337,8 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
EXPECT_EQ(1, callback_count_);
// Prevent drawing so we can't make a copy of the impl_destroyed layer.
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation());
break;
case 2:
// Flush the message loops and make sure the callbacks run.
@@ -736,7 +737,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
// Prevent drawing.
layer_tree_host()->SetViewportSizeAndScale(gfx::Size(0, 0), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
AddCopyRequest(copy_layer_.get());
}
@@ -751,8 +752,8 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
void DidCommit() override {
if (layer_tree_host()->SourceFrameNumber() == 1) {
// Allow drawing.
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(root_->bounds()),
- 1.f, viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(root_->bounds()), 1.f, viz::LocalSurfaceIdAllocation());
AddCopyRequest(copy_layer_.get());
}
@@ -1097,8 +1098,8 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
base::Unretained(this)));
copy_layer_->RequestCopyOfOutput(std::move(request));
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation());
break;
}
case 2:
@@ -1111,7 +1112,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
// Allow us to draw now.
layer_tree_host()->SetViewportSizeAndScale(
layer_tree_host()->root_layer()->bounds(), 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
break;
case 4:
EXPECT_EQ(1, callback_count_);
@@ -1178,8 +1179,8 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
base::Unretained(this)));
copy_layer_->RequestCopyOfOutput(std::move(request));
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation());
break;
}
case 2:
diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
index c84926bc3bc..809985aa5f2 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
@@ -108,8 +108,8 @@ class LayerTreeHostDamageTestSetViewportSizeAndScale
void DidCommitAndDrawFrame() override {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(15, 15), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(15, 15), 1.f, viz::LocalSurfaceIdAllocation());
break;
}
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
index b1615f0eb7e..d0dfd9b9ba7 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_host.h"
+#include "base/time/time.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_recording_source.h"
#include "cc/test/layer_tree_test.h"
@@ -532,8 +533,8 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
gfx::Size double_root_size(200, 200);
- layer_tree_host()->SetViewportSizeAndScale(double_root_size, 2.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ double_root_size, 2.f, viz::LocalSurfaceIdAllocation());
break;
}
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index 205d1f2c648..7eed6e1c428 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_host.h"
+#include "base/time/time.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
@@ -192,8 +193,8 @@ class LayerTreeHostPictureTestResizeViewportWithGpuRaster
// Change the picture layer's size along with the viewport, so it will
// consider picking a new tile size.
picture_->SetBounds(gfx::Size(768, 1056));
- layer_tree_host()->SetViewportSizeAndScale(gfx::Size(768, 1056), 1.f,
- viz::LocalSurfaceId());
+ layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(768, 1056), 1.f, viz::LocalSurfaceIdAllocation());
break;
case 2:
EndTest();
@@ -599,7 +600,7 @@ class LayerTreeHostPictureTestForceRecalculateScales
layer_tree_host()->SetRootLayer(root);
layer_tree_host()->SetViewportSizeAndScale(size, 1.f,
- viz::LocalSurfaceId());
+ viz::LocalSurfaceIdAllocation());
client_.set_fill_with_nonsolid_color(true);
client_.set_bounds(size);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
index 9d207e792be..b918f70e69a 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -423,4 +423,123 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA
MULTI_THREAD_TEST_F(LayerTreeHostProxyTestCommitWaitsForActivationMFBA);
+// Tests that SingleThreadProxy correctly reports pending animations when
+// requested from the impl-side.
+class LayerTreeHostProxyTestImplFrameCausesAnimatePending
+ : public LayerTreeHostProxyTest {
+ protected:
+ LayerTreeHostProxyTestImplFrameCausesAnimatePending() = default;
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ switch (host_impl->sync_tree()->source_frame_number()) {
+ case 0: {
+ EXPECT_FALSE(proxy()->RequestedAnimatePending());
+ host_impl->SetNeedsOneBeginImplFrame();
+ EXPECT_TRUE(proxy()->RequestedAnimatePending());
+ PostSetNeedsCommitToMainThread();
+ break;
+ }
+ case 1: {
+ EXPECT_FALSE(proxy()->RequestedAnimatePending());
+ EndTest();
+ break;
+ }
+ default: { NOTREACHED(); }
+ }
+ }
+
+ void AfterTest() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestImplFrameCausesAnimatePending);
+};
+
+SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestImplFrameCausesAnimatePending);
+
+// Test that the SingleThreadProxy correctly records and clears commit requests
+// from the impl-side.
+class LayerTreeHostProxyTestNeedsCommitFromImpl
+ : public LayerTreeHostProxyTest {
+ protected:
+ LayerTreeHostProxyTestNeedsCommitFromImpl() = default;
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ switch (host_impl->sync_tree()->source_frame_number()) {
+ case 0: {
+ host_impl->SetNeedsCommit();
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostProxyTestNeedsCommitFromImpl::
+ CheckCommitRequested,
+ base::Unretained(this)));
+ break;
+ }
+ case 1: {
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostProxyTestNeedsCommitFromImpl::
+ CheckRequestClearedAndEnd,
+ base::Unretained(this)));
+ break;
+ }
+ default: { NOTREACHED(); }
+ }
+ }
+
+ void CheckCommitRequested() { EXPECT_TRUE(proxy()->CommitRequested()); }
+
+ void CheckRequestClearedAndEnd() {
+ EXPECT_FALSE(proxy()->CommitRequested());
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestNeedsCommitFromImpl);
+};
+
+SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestNeedsCommitFromImpl);
+
+// Test that a commit is correctly delayed but is not lost when turning
+// invisible, and after turning visible, the commit is executed.
+// This is a regression test for https://crbug.com/890008
+class LayerTreeHostProxyTestDelayedCommitDueToVisibility
+ : public LayerTreeHostProxyTest {
+ protected:
+ LayerTreeHostProxyTestDelayedCommitDueToVisibility() = default;
+ ~LayerTreeHostProxyTestDelayedCommitDueToVisibility() override = default;
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillSendBeginMainFrameOnThread(LayerTreeHostImpl*) override {
+ if (!set_invisible_once_) {
+ set_invisible_once_ = true;
+ PostSetVisibleToMainThread(false);
+ }
+ }
+
+ void BeginMainFrameAbortedOnThread(LayerTreeHostImpl*,
+ CommitEarlyOutReason reason) override {
+ EXPECT_EQ(CommitEarlyOutReason::ABORTED_NOT_VISIBLE, reason);
+ PostSetVisibleToMainThread(true);
+ }
+
+ void DidCommit() override { EndTest(); }
+
+ void AfterTest() override {}
+
+ private:
+ bool set_invisible_once_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestDelayedCommitDueToVisibility);
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostProxyTestDelayedCommitDueToVisibility);
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index f3e04c1d449..db91dda80b5 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -20,7 +20,7 @@
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
@@ -85,6 +85,7 @@ LayerTreeImpl::LayerTreeImpl(
page_scale_factor_(page_scale_factor),
min_page_scale_factor_(0),
max_page_scale_factor_(0),
+ external_page_scale_factor_(1.f),
device_scale_factor_(1.f),
painted_device_scale_factor_(1.f),
content_source_id_(0),
@@ -476,6 +477,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
// tree so only the limits need to be provided.
target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
max_page_scale_factor());
+ target_tree->SetExternalPageScaleFactor(external_page_scale_factor_);
target_tree->SetRasterColorSpace(raster_color_space_id_, raster_color_space_);
target_tree->elastic_overscroll()->PushPendingToActive();
@@ -489,11 +491,15 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
if (TakeNewLocalSurfaceIdRequest())
target_tree->RequestNewLocalSurfaceId();
- target_tree->SetLocalSurfaceIdFromParent(local_surface_id_from_parent());
+ target_tree->SetLocalSurfaceIdAllocationFromParent(
+ local_surface_id_allocation_from_parent());
target_tree->pending_page_scale_animation_ =
std::move(pending_page_scale_animation_);
+ if (TakeForceSendMetadataRequest())
+ target_tree->RequestForceSendMetadata();
+
target_tree->RegisterSelection(selection_);
// This should match the property synchronization in
@@ -523,6 +529,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->HandleTickmarksVisibilityChange();
target_tree->HandleScrollbarShowRequestsFromMain();
target_tree->AddPresentationCallbacks(std::move(presentation_callbacks_));
+ presentation_callbacks_.clear();
}
void LayerTreeImpl::HandleTickmarksVisibilityChange() {
@@ -610,7 +617,7 @@ LayerImplList::reverse_iterator LayerTreeImpl::rend() {
}
bool LayerTreeImpl::IsElementInLayerList(ElementId element_id) const {
- return elements_in_layer_list_.count(element_id);
+ return elements_in_property_trees_.count(element_id);
}
ElementListType LayerTreeImpl::GetElementTypeForAnimation() const {
@@ -619,9 +626,6 @@ ElementListType LayerTreeImpl::GetElementTypeForAnimation() const {
void LayerTreeImpl::AddToElementLayerList(ElementId element_id,
LayerImpl* layer) {
- DCHECK(layer);
- DCHECK(layer->element_id() == element_id);
-
if (!element_id)
return;
@@ -631,17 +635,17 @@ void LayerTreeImpl::AddToElementLayerList(ElementId element_id,
#if DCHECK_IS_ON()
bool element_id_collision_detected =
- elements_in_layer_list_.count(element_id);
+ elements_in_property_trees_.count(element_id);
DCHECK(!element_id_collision_detected);
#endif
- elements_in_layer_list_.insert(element_id);
+ elements_in_property_trees_.insert(element_id);
host_impl_->mutator_host()->RegisterElement(element_id,
GetElementTypeForAnimation());
- if (layer->scrollable())
+ if (layer && layer->scrollable())
AddScrollableLayer(layer);
}
@@ -656,7 +660,7 @@ void LayerTreeImpl::RemoveFromElementLayerList(ElementId element_id) {
host_impl_->mutator_host()->UnregisterElement(element_id,
GetElementTypeForAnimation());
- elements_in_layer_list_.erase(element_id);
+ elements_in_property_trees_.erase(element_id);
element_id_to_scrollable_layer_.erase(element_id);
}
@@ -841,8 +845,12 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id,
TransformNode* LayerTreeImpl::PageScaleTransformNode() {
auto* page_scale = PageScaleLayer();
- if (!page_scale)
- return nullptr;
+ if (!page_scale) {
+ // TODO(crbug.com/909750): Check all other callers of PageScaleLayer() and
+ // switch to viewport_property_ids_.page_scale_transform if needed.
+ return property_trees()->transform_tree.Node(
+ viewport_property_ids_.page_scale_transform);
+ }
return property_trees()->transform_tree.Node(
page_scale->transform_tree_index());
@@ -857,8 +865,8 @@ void LayerTreeImpl::UpdatePageScaleNode() {
// When the page scale layer is also the root layer (this happens in the UI
// compositor), the node should also store the combined scale factor and not
// just the page scale factor.
- // TODO(bokan): Need to implement this behavior for
- // BlinkGeneratedPropertyTrees. i.e. (no page scale layer).
+ // TODO(crbug.com/909750): Implement this behavior without PageScaleLayer,
+ // e.g. when we switch the UI compositor to create property trees.
float device_scale_factor_for_page_scale_layer = 1.f;
gfx::Transform device_transform_for_page_scale_layer;
if (IsRootLayer(PageScaleLayer())) {
@@ -968,6 +976,8 @@ bool LayerTreeImpl::ClampBrowserControlsShownRatio() {
}
bool LayerTreeImpl::SetCurrentBrowserControlsShownRatio(float ratio) {
+ TRACE_EVENT1("cc", "LayerTreeImpl::SetCurrentBrowserControlsShownRatio",
+ "ratio", ratio);
bool changed = top_controls_shown_ratio_->SetCurrent(ratio);
changed |= ClampBrowserControlsShownRatio();
return changed;
@@ -1040,9 +1050,11 @@ void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
host_impl_->SetNeedUpdateGpuRasterizationStatus();
}
-void LayerTreeImpl::SetLocalSurfaceIdFromParent(
- const viz::LocalSurfaceId& local_surface_id_from_parent) {
- local_surface_id_from_parent_ = local_surface_id_from_parent;
+void LayerTreeImpl::SetLocalSurfaceIdAllocationFromParent(
+ const viz::LocalSurfaceIdAllocation&
+ local_surface_id_allocation_from_parent) {
+ local_surface_id_allocation_from_parent_ =
+ local_surface_id_allocation_from_parent;
}
void LayerTreeImpl::RequestNewLocalSurfaceId() {
@@ -1099,6 +1111,15 @@ void LayerTreeImpl::SetRasterColorSpace(
raster_color_space_ = raster_color_space;
}
+void LayerTreeImpl::SetExternalPageScaleFactor(
+ float external_page_scale_factor) {
+ if (external_page_scale_factor_ == external_page_scale_factor)
+ return;
+
+ external_page_scale_factor_ = external_page_scale_factor;
+ DidUpdatePageScale();
+}
+
SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
return page_scale_factor_.get();
}
@@ -1383,22 +1404,14 @@ const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
}
gfx::SizeF LayerTreeImpl::ScrollableSize() const {
- LayerImpl* root_scroll_layer = nullptr;
- LayerImpl* root_container_layer = nullptr;
- if (OuterViewportScrollLayer()) {
- root_scroll_layer = OuterViewportScrollLayer();
- root_container_layer = OuterViewportContainerLayer();
- } else if (InnerViewportScrollLayer()) {
- root_scroll_layer = InnerViewportScrollLayer();
- root_container_layer = InnerViewportContainerLayer();
- }
-
- if (!root_scroll_layer || !root_container_layer)
+ auto* scroll_node = OuterViewportScrollNode() ? OuterViewportScrollNode()
+ : InnerViewportScrollNode();
+ if (!scroll_node)
return gfx::SizeF();
-
- gfx::SizeF content_size = root_scroll_layer->BoundsForScrolling();
- content_size.SetToMax(root_container_layer->BoundsForScrolling());
- return content_size;
+ const auto& scroll_tree = property_trees()->scroll_tree;
+ auto size = scroll_tree.scroll_bounds(scroll_node->id);
+ size.SetToMax(gfx::SizeF(scroll_tree.container_bounds(scroll_node->id)));
+ return size;
}
LayerImpl* LayerTreeImpl::LayerById(int id) const {
@@ -2309,6 +2322,12 @@ LayerTreeImpl::TakePendingPageScaleAnimation() {
return std::move(pending_page_scale_animation_);
}
+bool LayerTreeImpl::TakeForceSendMetadataRequest() {
+ bool force_send_metadata_request = force_send_metadata_request_;
+ force_send_metadata_request_ = false;
+ return force_send_metadata_request;
+}
+
void LayerTreeImpl::ResetAllChangeTracking() {
layers_that_should_push_properties_.clear();
// Iterate over all layers, including masks.
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index f5dd26f151f..a7a3674f440 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -13,6 +13,7 @@
#include "base/containers/flat_set.h"
#include "base/macros.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "cc/base/synced_property.h"
#include "cc/input/event_listener_properties.h"
@@ -180,6 +181,7 @@ class CC_EXPORT LayerTreeImpl {
void PushPropertyTreesTo(LayerTreeImpl* tree_impl);
void PushPropertiesTo(LayerTreeImpl* tree_impl);
void PushSurfaceRangesTo(LayerTreeImpl* tree_impl);
+ void PushRegisteredElementIdsTo(LayerTreeImpl* tree_impl);
void MoveChangeTrackingToLayers();
@@ -284,6 +286,11 @@ class CC_EXPORT LayerTreeImpl {
const_cast<const LayerTreeImpl*>(this)->OuterViewportScrollNode());
}
+ void set_viewport_property_ids(
+ const LayerTreeHost::ViewportPropertyIds& ids) {
+ viewport_property_ids_ = ids;
+ }
+
void ApplySentScrollAndScaleDeltasFromAbortedCommit();
SkColor background_color() const { return background_color_; }
@@ -319,9 +326,12 @@ class CC_EXPORT LayerTreeImpl {
void set_content_source_id(uint32_t id) { content_source_id_ = id; }
uint32_t content_source_id() { return content_source_id_; }
- void SetLocalSurfaceIdFromParent(const viz::LocalSurfaceId& id);
- const viz::LocalSurfaceId& local_surface_id_from_parent() const {
- return local_surface_id_from_parent_;
+ void SetLocalSurfaceIdAllocationFromParent(
+ const viz::LocalSurfaceIdAllocation&
+ local_surface_id_allocation_from_parent);
+ const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent()
+ const {
+ return local_surface_id_allocation_from_parent_;
}
void RequestNewLocalSurfaceId();
@@ -344,6 +354,10 @@ class CC_EXPORT LayerTreeImpl {
void SetRasterColorSpace(int raster_color_space_id,
const gfx::ColorSpace& raster_color_space);
+ void SetExternalPageScaleFactor(float external_page_scale_factor);
+ float external_page_scale_factor() const {
+ return external_page_scale_factor_;
+ }
const gfx::ColorSpace& raster_color_space() const {
return raster_color_space_;
}
@@ -545,6 +559,10 @@ class CC_EXPORT LayerTreeImpl {
std::unique_ptr<PendingPageScaleAnimation> pending_animation);
std::unique_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation();
+ // Requests that we force send RenderFrameMetadata with the next frame.
+ void RequestForceSendMetadata() { force_send_metadata_request_ = true; }
+ bool TakeForceSendMetadataRequest();
+
void DidUpdateScrollOffset(ElementId id);
// Mark the scrollbar geometries (e.g., thumb size and position) as needing an
@@ -599,6 +617,11 @@ class CC_EXPORT LayerTreeImpl {
LayerTreeLifecycle& lifecycle() { return lifecycle_; }
+ const std::unordered_set<ElementId, ElementIdHash>&
+ elements_in_property_trees() {
+ return elements_in_property_trees_;
+ }
+
protected:
float ClampPageScaleFactorToLimits(float page_scale_factor) const;
void PushPageScaleFactorAndLimits(const float* page_scale_factor,
@@ -611,6 +634,8 @@ class CC_EXPORT LayerTreeImpl {
bool ClampBrowserControlsShownRatio();
private:
+ friend class LayerTreeHost;
+
TransformNode* PageScaleTransformNode();
void UpdatePageScaleNode();
@@ -632,12 +657,14 @@ class CC_EXPORT LayerTreeImpl {
int last_scrolled_scroll_node_index_;
ViewportLayerIds viewport_layer_ids_;
+ LayerTreeHost::ViewportPropertyIds viewport_property_ids_;
LayerSelection selection_;
scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor_;
float min_page_scale_factor_;
float max_page_scale_factor_;
+ float external_page_scale_factor_;
float device_scale_factor_;
float painted_device_scale_factor_;
@@ -645,7 +672,7 @@ class CC_EXPORT LayerTreeImpl {
gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_from_parent_;
+ viz::LocalSurfaceIdAllocation local_surface_id_allocation_from_parent_;
bool new_local_surface_id_request_ = false;
gfx::Size device_viewport_size_;
@@ -663,7 +690,7 @@ class CC_EXPORT LayerTreeImpl {
base::flat_set<LayerImpl*> layers_that_should_push_properties_;
// Set of ElementIds which are present in the |layer_list_|.
- std::unordered_set<ElementId, ElementIdHash> elements_in_layer_list_;
+ std::unordered_set<ElementId, ElementIdHash> elements_in_property_trees_;
std::unordered_map<ElementId, float, ElementIdHash>
element_id_to_opacity_animations_;
@@ -735,6 +762,10 @@ class CC_EXPORT LayerTreeImpl {
std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
+ // Whether we have a request to force-send RenderFrameMetadata with the next
+ // frame.
+ bool force_send_metadata_request_ = false;
+
// Tracks the lifecycle which is used for enforcing dependencies between
// lifecycle states. See: |LayerTreeLifecycle|.
LayerTreeLifecycle lifecycle_;
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index 9cd9d6ce6af..1c35945d640 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -2276,6 +2276,29 @@ TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) {
EXPECT_EQ(2, result_layer->id());
}
+// When using layer lists, we may not have layers for the outer viewport. This
+// test verifies that scroll size can be calculated using property tree nodes.
+TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) {
+ const gfx::Size inner_viewport_size(1000, 1000);
+ const gfx::Size outer_viewport_size(1000, 1000);
+ const gfx::Size scroll_layer_size(2000, 2000);
+
+ auto* tree_impl = host_impl().active_tree();
+ LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport(
+ &host_impl(), tree_impl, 50, inner_viewport_size, outer_viewport_size,
+ scroll_layer_size);
+
+ // With viewport layers the scrollable size should be correct.
+ EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize());
+
+ // The scrollable size should be correct without non-outer viewport layers.
+ LayerTreeImpl::ViewportLayerIds updated_viewport_ids;
+ updated_viewport_ids.outer_viewport_scroll =
+ tree_impl->OuterViewportScrollLayer()->id();
+ tree_impl->SetViewportLayersFromIds(updated_viewport_ids);
+ EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize());
+}
+
namespace {
class StubSwapPromise : public SwapPromise,
diff --git a/chromium/cc/trees/layer_tree_mutator.cc b/chromium/cc/trees/layer_tree_mutator.cc
index 845ed7dc60f..491eec54fa7 100644
--- a/chromium/cc/trees/layer_tree_mutator.cc
+++ b/chromium/cc/trees/layer_tree_mutator.cc
@@ -12,11 +12,13 @@ AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState(
WorkletAnimationId worklet_animation_id,
std::string name,
double current_time,
- std::unique_ptr<AnimationOptions> options)
+ std::unique_ptr<AnimationOptions> options,
+ int num_effects)
: worklet_animation_id(worklet_animation_id),
name(name),
current_time(current_time),
- options(std::move(options)) {}
+ options(std::move(options)),
+ num_effects(num_effects) {}
AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState(
AddAndUpdateState&&) = default;
AnimationWorkletInput::AddAndUpdateState::~AddAndUpdateState() = default;
@@ -97,11 +99,10 @@ std::unique_ptr<AnimationWorkletInput> MutatorInputState::TakeWorkletState(
AnimationWorkletOutput::AnimationWorkletOutput() = default;
AnimationWorkletOutput::~AnimationWorkletOutput() = default;
-AnimationWorkletOutput::AnimationState::AnimationState(
- WorkletAnimationId id,
- base::Optional<base::TimeDelta> time)
- : worklet_animation_id(id), local_time(time) {}
+AnimationWorkletOutput::AnimationState::AnimationState(WorkletAnimationId id)
+ : worklet_animation_id(id) {}
AnimationWorkletOutput::AnimationState::AnimationState(const AnimationState&) =
default;
+AnimationWorkletOutput::AnimationState::~AnimationState() = default;
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index dd702c49458..42cc317740e 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -40,11 +40,13 @@ struct CC_EXPORT AnimationWorkletInput {
// Worklet animation's current time, from its associated timeline.
double current_time;
std::unique_ptr<AnimationOptions> options;
+ int num_effects;
AddAndUpdateState(WorkletAnimationId worklet_animation_id,
std::string name,
double current_time,
- std::unique_ptr<AnimationOptions> options);
+ std::unique_ptr<AnimationOptions> options,
+ int num_effects);
AddAndUpdateState(AddAndUpdateState&&);
~AddAndUpdateState();
@@ -109,16 +111,12 @@ class CC_EXPORT MutatorInputState {
struct CC_EXPORT AnimationWorkletOutput {
struct CC_EXPORT AnimationState {
- AnimationState(WorkletAnimationId,
- base::Optional<base::TimeDelta> local_time);
+ explicit AnimationState(WorkletAnimationId);
AnimationState(const AnimationState&);
+ ~AnimationState();
WorkletAnimationId worklet_animation_id;
- // The animator effect's local time.
- // TODO(majidvp): This assumes each animator has a single output effect
- // which does not hold once we state support group effects.
- // http://crbug.com/767043
- base::Optional<base::TimeDelta> local_time;
+ std::vector<base::Optional<base::TimeDelta>> local_times;
};
AnimationWorkletOutput();
diff --git a/chromium/cc/trees/layer_tree_painter.h b/chromium/cc/trees/layer_tree_painter.h
new file mode 100644
index 00000000000..f85707460d5
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_painter.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_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 389e25b5eec..7f074dd977e 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -165,6 +165,12 @@ class CC_EXPORT LayerTreeSettings {
// DidReceiveCompositorFrameAck, used by the Compositor but not the
// LayerTreeView.
bool send_compositor_frame_ack = true;
+
+ // When false, scroll deltas accumulated on the impl thread are rounded to
+ // integer values when sent to Blink on commit. This flag should eventually
+ // go away and CC should send Blink fractional values:
+ // https://crbug.com/414283.
+ bool commit_fractional_scroll_deltas = false;
};
} // namespace cc
diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc
index 906eab95421..3c73e1d45bf 100644
--- a/chromium/cc/trees/occlusion_tracker.cc
+++ b/chromium/cc/trees/occlusion_tracker.cc
@@ -224,8 +224,8 @@ static void ReduceOcclusionBelowSurface(
return;
gfx::Rect affected_area_in_target =
- contributing_surface->BackgroundFilters().MapRectReverse(target_rect,
- SkMatrix::I());
+ contributing_surface->BackdropFilters().MapRectReverse(target_rect,
+ SkMatrix::I());
// Unite target_rect because we only care about positive outsets.
affected_area_in_target.Union(target_rect);
@@ -288,7 +288,7 @@ void OcclusionTracker::LeaveToRenderTarget(
old_surface->draw_transform());
gfx::Rect unoccluded_surface_rect;
- if (old_surface->BackgroundFilters().HasFilterThatMovesPixels()) {
+ if (old_surface->BackdropFilters().HasFilterThatMovesPixels()) {
Occlusion surface_occlusion = GetCurrentOcclusionForContributingSurface(
old_surface->draw_transform());
unoccluded_surface_rect =
@@ -320,7 +320,7 @@ void OcclusionTracker::LeaveToRenderTarget(
}
}
- if (!old_surface->BackgroundFilters().HasFilterThatMovesPixels())
+ if (!old_surface->BackdropFilters().HasFilterThatMovesPixels())
return;
ReduceOcclusionBelowSurface(old_surface, unoccluded_surface_rect,
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index 8893f46dc88..0ba135b2fae 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -1255,10 +1255,10 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
-class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
+class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter
: public OcclusionTrackerTest {
protected:
- explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
+ explicit OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter(
bool opaque_layers)
: OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
@@ -1282,13 +1282,13 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
// Make a 50x50 filtered surface that is adjacent to occluding layers
// which are above it in the z-order in various configurations. The
// surface is scaled to test that the pixel moving is done in the target
- // space, where the background filter is applied.
+ // space, where the backdrop filter is applied.
TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
LayerImpl* filtered_surface = this->CreateDrawingLayer(
parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100),
false);
- filtered_surface->test_properties()->background_filters = filters;
+ filtered_surface->test_properties()->backdrop_filters = filters;
gfx::Rect occlusion_rect;
switch (i) {
case LEFT:
@@ -1333,7 +1333,7 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
EXPECT_EQ(occlusion_inside_surface.ToString(),
occlusion.occlusion_from_outside_target().ToString());
- // The surface has a background blur, so it needs pixels that are
+ // The surface has a backdrop blur, so it needs pixels that are
// currently considered occluded in order to be drawn. The pixels it
// needs should be removed from the occluded area, so that they are drawn
// when we get to the parent.
@@ -1367,12 +1367,12 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
+ OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter);
-class OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter
+class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter
: public OcclusionTrackerTest {
protected:
- explicit OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter(
+ explicit OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter(
bool opaque_layers)
: OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
@@ -1397,13 +1397,13 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter
// Make a 50x50 filtered surface that is adjacent to occluding layers
// which are above it in the z-order in various configurations. The
// surface is scaled to test that the pixel moving is done in the target
- // space, where the background filter is applied.
+ // space, where the backdrop filter is applied.
TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
LayerImpl* filtered_surface = this->CreateDrawingLayer(
parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100),
false);
- filtered_surface->test_properties()->background_filters = filters;
+ filtered_surface->test_properties()->backdrop_filters = filters;
gfx::Rect occlusion_rect;
switch (i) {
case LEFT:
@@ -1448,7 +1448,7 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter
EXPECT_EQ(occlusion_inside_surface.ToString(),
occlusion.occlusion_from_outside_target().ToString());
- // The surface has a background filter, so it needs pixels that are
+ // The surface has a backdrop filter, so it needs pixels that are
// currently considered occluded in order to be drawn. The pixels it
// needs should be removed from the occluded area, so that they are drawn
// when we get to the parent.
@@ -1459,7 +1459,7 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter
switch (i) {
case LEFT:
// The right half of the occlusion is close enough to cast a shadow
- // that would be visible in the background filter. The shadow reaches
+ // that would be visible in the backdrop filter. The shadow reaches
// 3*5 + 10 = 25 pixels to the right.
expected_occlusion = gfx::Rect(0, 0, 25, 200);
break;
@@ -1488,12 +1488,12 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestPixelsNeededForDropShadowBackgroundFilter);
+ OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter);
-class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
+class OcclusionTrackerTestTwoBackdropFiltersReduceOcclusionTwice
: public OcclusionTrackerTest {
protected:
- explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
+ explicit OcclusionTrackerTestTwoBackdropFiltersReduceOcclusionTwice(
bool opaque_layers)
: OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
@@ -1520,8 +1520,8 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
filtered_surface2->test_properties()->force_render_surface = true;
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(1.f));
- filtered_surface1->test_properties()->background_filters = filters;
- filtered_surface2->test_properties()->background_filters = filters;
+ filtered_surface1->test_properties()->backdrop_filters = filters;
+ filtered_surface2->test_properties()->backdrop_filters = filters;
this->CalcDrawEtc(root);
@@ -1554,12 +1554,12 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
+ OcclusionTrackerTestTwoBackdropFiltersReduceOcclusionTwice);
-class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
+class OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter
: public OcclusionTrackerTest {
protected:
- explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
+ explicit OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter(
bool opaque_layers)
: OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
@@ -1568,7 +1568,7 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
// Make a 50x50 surface, with a smaller 30x30 layer centered below it.
// The surface is scaled to test that the pixel moving is done in the target
- // space, where the background filter is applied, and the surface appears at
+ // space, where the backdrop filter is applied, and the surface appears at
// 50, 50.
TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
@@ -1583,13 +1583,13 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
filtered_surface->test_properties()->force_render_surface = true;
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
- filtered_surface->test_properties()->background_filters = filters;
+ filtered_surface->test_properties()->backdrop_filters = filters;
this->CalcDrawEtc(parent);
TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
- // The surface has a background blur, so it blurs non-opaque pixels below
+ // The surface has a backdrop blur, so it blurs non-opaque pixels below
// it.
this->VisitLayer(filtered_surface, &occlusion);
this->VisitContributingSurface(filtered_surface, &occlusion);
@@ -1616,12 +1616,12 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
+ OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter);
-class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
+class OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded
: public OcclusionTrackerTest {
protected:
- explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
+ explicit OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded(
bool opaque_layers)
: OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
@@ -1631,7 +1631,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
// Make a 50x50 filtered surface that is completely occluded by an opaque
// layer which is above it in the z-order. The surface is
// scaled to test that the pixel moving is done in the target space, where
- // the background filter is applied, and the surface appears at 50, 50.
+ // the backdrop filter is applied, and the surface appears at 50, 50.
TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
LayerImpl* filtered_surface =
@@ -1645,7 +1645,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
filtered_surface->test_properties()->force_render_surface = true;
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
- filtered_surface->test_properties()->background_filters = filters;
+ filtered_surface->test_properties()->backdrop_filters = filters;
this->CalcDrawEtc(parent);
@@ -1664,7 +1664,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
occlusion.occlusion_from_outside_target().ToString());
}
- // The surface has a background blur, so it blurs non-opaque pixels below
+ // The surface has a backdrop blur, so it blurs non-opaque pixels below
// it.
this->VisitContributingSurface(filtered_surface, &occlusion);
{
@@ -1681,7 +1681,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
+ OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded);
class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
: public OcclusionTrackerTest {
@@ -1695,7 +1695,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
// Make a 50x50 surface which is partially occluded by opaque layers which
// are above it in the z-order. The surface is scaled to test that the
- // pixel moving is done in the target space, where the background filter is
+ // pixel moving is done in the target space, where the backdrop filter is
// applied, but the surface appears at 50, 50.
TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
@@ -1713,7 +1713,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
filtered_surface->test_properties()->force_render_surface = true;
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
- filtered_surface->test_properties()->background_filters = filters;
+ filtered_surface->test_properties()->backdrop_filters = filters;
this->CalcDrawEtc(parent);
@@ -1722,7 +1722,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
this->VisitLayer(beside_surface_layer, &occlusion);
this->VisitLayer(above_surface_layer, &occlusion);
- // The surface has a background blur, so it blurs non-opaque pixels below
+ // The surface has a backdrop blur, so it blurs non-opaque pixels below
// it.
this->VisitLayer(filtered_surface, &occlusion);
this->VisitContributingSurface(filtered_surface, &occlusion);
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index c4fa5bc4a19..b3fff07a268 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -10,7 +10,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/checked_math.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/layers/layer_impl.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/effect_node.h"
@@ -784,7 +784,7 @@ void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) {
// Exceptions:
// 1) Nodes that contribute to copy requests, whether hidden or not, must be
// drawn.
- // 2) Nodes that have a background filter.
+ // 2) Nodes that have a backdrop filter.
// 3) Nodes with animating screen space opacity on main thread or pending tree
// are drawn if their parent is drawn irrespective of their opacity.
if (node->has_copy_request || node->cache_render_surface)
@@ -792,7 +792,7 @@ void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) {
else if (EffectiveOpacity(node) == 0.f &&
(!node->has_potential_opacity_animation ||
property_trees()->is_active) &&
- node->background_filters.IsEmpty())
+ node->backdrop_filters.IsEmpty())
node->is_drawn = false;
else if (parent_node)
node->is_drawn = parent_node->is_drawn;
@@ -1305,14 +1305,7 @@ void ScrollTree::clear() {
gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const {
const ScrollNode* scroll_node = Node(scroll_node_id);
- gfx::SizeF scroll_bounds =
- gfx::SizeF(scroll_node->bounds.width(), scroll_node->bounds.height());
-
- if (scroll_node->scrolls_inner_viewport) {
- scroll_bounds.Enlarge(
- property_trees()->inner_viewport_scroll_bounds_delta().x(),
- property_trees()->inner_viewport_scroll_bounds_delta().y());
- }
+ gfx::SizeF scroll_bounds = this->scroll_bounds(scroll_node_id);
if (!scroll_node->scrollable || scroll_bounds.IsEmpty())
return gfx::ScrollOffset();
@@ -1337,6 +1330,16 @@ gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const {
return max_offset;
}
+gfx::SizeF ScrollTree::scroll_bounds(int scroll_node_id) const {
+ const ScrollNode* scroll_node = Node(scroll_node_id);
+ gfx::SizeF bounds(scroll_node->bounds);
+ if (scroll_node->scrolls_inner_viewport) {
+ const auto& delta = property_trees()->inner_viewport_scroll_bounds_delta();
+ bounds.Enlarge(delta.x(), delta.y());
+ }
+ return bounds;
+}
+
void ScrollTree::OnScrollOffsetAnimated(ElementId id,
int scroll_tree_index,
const gfx::ScrollOffset& scroll_offset,
@@ -1472,10 +1475,17 @@ const gfx::ScrollOffset ScrollTree::GetPixelSnappedScrollOffset(
}
gfx::ScrollOffset ScrollTree::PullDeltaForMainThread(
- SyncedScrollOffset* scroll_offset) {
+ SyncedScrollOffset* scroll_offset,
+ bool use_fractional_deltas) {
DCHECK(property_trees()->is_active);
+
+ // Once this setting is enabled, all the complicated rounding logic below can
+ // go away.
+ if (use_fractional_deltas)
+ return scroll_offset->PullDeltaForMainThread();
+
// TODO(flackr): We should pass the fractional scroll deltas when Blink fully
- // supports fractional scrolls.
+ // supports fractional scrolls. crbug.com/414283.
// TODO(flackr): We should ideally round the fractional scrolls in the same
// direction as the scroll will be snapped but for common cases this is
// equivalent to rounding to the nearest integer offset.
@@ -1495,26 +1505,25 @@ gfx::ScrollOffset ScrollTree::PullDeltaForMainThread(
return delta;
}
-void ScrollTree::CollectScrollDeltas(
- ScrollAndScaleSet* scroll_info,
- ElementId inner_viewport_scroll_element_id) {
+void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
+ ElementId inner_viewport_scroll_element_id,
+ bool use_fractional_deltas) {
DCHECK(!property_trees()->is_main_thread);
for (auto map_entry : synced_scroll_offset_map_) {
gfx::ScrollOffset scroll_delta =
- PullDeltaForMainThread(map_entry.second.get());
+ PullDeltaForMainThread(map_entry.second.get(), use_fractional_deltas);
- gfx::Vector2d scroll_delta_vector(scroll_delta.x(), scroll_delta.y());
ElementId id = map_entry.first;
if (!scroll_delta.IsZero()) {
if (id == inner_viewport_scroll_element_id) {
// Inner (visual) viewport is stored separately.
scroll_info->inner_viewport_scroll.element_id = id;
- scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta_vector;
+ scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta;
} else {
LayerTreeHostCommon::ScrollUpdateInfo scroll;
scroll.element_id = id;
- scroll.scroll_delta = scroll_delta_vector;
+ scroll.scroll_delta = scroll_delta;
scroll_info->scrolls.push_back(scroll);
}
}
@@ -1522,8 +1531,11 @@ void ScrollTree::CollectScrollDeltas(
}
void ScrollTree::CollectScrollDeltasForTesting() {
+ LayerTreeSettings settings;
+ bool use_fractional_deltas = settings.commit_fractional_scroll_deltas;
+
for (auto map_entry : synced_scroll_offset_map_) {
- PullDeltaForMainThread(map_entry.second.get());
+ PullDeltaForMainThread(map_entry.second.get(), use_fractional_deltas);
}
}
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 85abe4979ad..89118ace357 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -406,6 +406,7 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
const gfx::ScrollOffset& scroll_offset,
LayerTreeImpl* layer_tree_impl);
gfx::Size container_bounds(int scroll_node_id) const;
+ gfx::SizeF scroll_bounds(int scroll_node_id) const;
ScrollNode* CurrentlyScrollingNode();
const ScrollNode* CurrentlyScrollingNode() const;
#if DCHECK_IS_ON()
@@ -437,7 +438,8 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
// reported to the main thread during the main frame. As such, should only be
// called on the impl thread side PropertyTrees.
void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
- ElementId inner_viewport_scroll_element_id);
+ ElementId inner_viewport_scroll_element_id,
+ bool use_fractional_deltas);
// Applies deltas sent in the previous main frame onto the impl thread state.
// Should only be called on the impl thread side PropertyTrees.
@@ -500,7 +502,8 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
SyncedScrollOffsetMap synced_scroll_offset_map_;
SyncedScrollOffset* GetOrCreateSyncedScrollOffset(ElementId id);
- gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset);
+ gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset,
+ bool use_fractional_deltas);
};
struct AnimationScaleData {
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index fd6c3edb5f6..674b121c370 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -740,12 +740,12 @@ static inline const gfx::PointF FiltersOrigin(LayerImpl* layer) {
return layer->test_properties()->filters_origin;
}
-static inline const FilterOperations& BackgroundFilters(Layer* layer) {
- return layer->background_filters();
+static inline const FilterOperations& BackdropFilters(Layer* layer) {
+ return layer->backdrop_filters();
}
-static inline const FilterOperations& BackgroundFilters(LayerImpl* layer) {
- return layer->test_properties()->background_filters;
+static inline const FilterOperations& BackdropFilters(LayerImpl* layer) {
+ return layer->test_properties()->backdrop_filters;
}
static inline float BackdropFilterQuality(Layer* layer) {
@@ -802,7 +802,7 @@ bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
}
// If the layer uses a CSS filter.
- if (!Filters(layer).IsEmpty() || !BackgroundFilters(layer).IsEmpty()) {
+ if (!Filters(layer).IsEmpty() || !BackdropFilters(layer).IsEmpty()) {
return true;
}
@@ -991,7 +991,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
node->cache_render_surface = CacheRenderSurface(layer);
node->has_copy_request = HasCopyRequest(layer);
node->filters = Filters(layer);
- node->background_filters = BackgroundFilters(layer);
+ node->backdrop_filters = BackdropFilters(layer);
node->backdrop_filter_quality = BackdropFilterQuality(layer);
node->filters_origin = FiltersOrigin(layer);
node->trilinear_filtering = TrilinearFiltering(layer);
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index 42d4fd2975c..b9bb0318420 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -36,6 +36,9 @@ class CC_EXPORT Proxy {
virtual ~Proxy() {}
virtual bool IsStarted() const = 0;
+
+ // This function retruns true if the commits go directly to active tree by
+ // skipping commit to pending tree.
virtual bool CommitToActiveTree() const = 0;
virtual void SetLayerTreeFrameSink(
@@ -56,9 +59,9 @@ class CC_EXPORT Proxy {
virtual void NotifyInputThrottledUntilCommit() = 0;
- // Defers commits until it is reset. It is only supported when using a
- // scheduler.
- virtual void SetDeferCommits(bool defer_commits) = 0;
+ // Defers LayerTreeHost::BeginMainFrameUpdate and commits until it is
+ // reset. It is only supported when using a scheduler.
+ virtual void SetDeferMainFrameUpdate(bool defer_main_frame_update) = 0;
virtual bool CommitRequested() const = 0;
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index 6aff668ee58..d3fc4b7ab4b 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -11,7 +11,7 @@
#include "base/auto_reset.h"
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
@@ -40,13 +40,22 @@ unsigned int nextBeginFrameId = 0;
} // namespace
+// Ensures that a CompletionEvent is always signaled.
+class ScopedCompletionEvent {
+ public:
+ explicit ScopedCompletionEvent(CompletionEvent* event) : event_(event) {}
+ ~ScopedCompletionEvent() { event_->Signal(); }
+
+ private:
+ CompletionEvent* const event_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedCompletionEvent);
+};
+
ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
LayerTreeHost* layer_tree_host,
TaskRunnerProvider* task_runner_provider)
: layer_tree_host_id_(layer_tree_host->GetId()),
commit_completion_waits_for_activation_(false),
- commit_completion_event_(nullptr),
- activation_completion_event_(nullptr),
next_frame_is_newly_committed_frame_(false),
inside_draw_(false),
input_throttled_until_commit_(false),
@@ -154,9 +163,10 @@ void ProxyImpl::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {
RenewTreePriority();
}
-void ProxyImpl::SetDeferCommitsOnImpl(bool defer_commits) const {
+void ProxyImpl::SetDeferMainFrameUpdateOnImpl(
+ bool defer_main_frame_update) const {
DCHECK(IsImplThread());
- scheduler_->SetDeferCommits(defer_commits);
+ scheduler_->SetDeferMainFrameUpdate(defer_main_frame_update);
}
void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
@@ -260,7 +270,8 @@ void ProxyImpl::NotifyReadyToCommitOnImpl(
host_impl_->ReadyToCommit();
- commit_completion_event_ = completion;
+ commit_completion_event_ =
+ std::make_unique<ScopedCompletionEvent>(completion);
commit_completion_waits_for_activation_ = hold_commit_for_activation;
DCHECK(!blocked_main_commit().layer_tree_host);
@@ -439,7 +450,6 @@ void ProxyImpl::DidActivateSyncTree() {
if (activation_completion_event_) {
TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
TRACE_EVENT_SCOPE_THREAD);
- activation_completion_event_->Signal();
activation_completion_event_ = nullptr;
}
}
@@ -503,6 +513,11 @@ void ProxyImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
host_impl_->DidNotProduceFrame(ack);
}
+void ProxyImpl::WillNotReceiveBeginFrame() {
+ DCHECK(IsImplThread());
+ host_impl_->DidNotNeedBeginFrame();
+}
+
void ProxyImpl::ScheduledActionSendBeginMainFrame(
const viz::BeginFrameArgs& args) {
DCHECK(IsImplThread());
@@ -518,6 +533,7 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(
host_impl_->EvictedUIResourcesExist();
begin_main_frame_state->completed_image_decode_requests =
host_impl_->TakeCompletedImageDecodeRequests();
+ host_impl_->WillSendBeginMainFrame();
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
@@ -572,9 +588,7 @@ void ProxyImpl::ScheduledActionCommit() {
// already activated if there was no work to be done.
TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
commit_completion_waits_for_activation_ = false;
- activation_completion_event_ = commit_completion_event_;
- } else {
- commit_completion_event_->Signal();
+ activation_completion_event_ = std::move(commit_completion_event_);
}
commit_completion_event_ = nullptr;
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 4bfbf73cd40..038d3752605 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -20,6 +20,8 @@ class LayerTreeHost;
class ProxyMain;
class RenderFrameMetadataObserver;
+class ScopedCompletionEvent;
+
// This class aggregates all the interactions that the main side of the
// compositor needs to have with the impl side.
// The class is created and lives on the impl thread.
@@ -39,7 +41,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr);
void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator);
void SetInputThrottledUntilCommitOnImpl(bool is_throttled);
- void SetDeferCommitsOnImpl(bool defer_commits) const;
+ void SetDeferMainFrameUpdateOnImpl(bool defer_main_frame_update) const;
void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect);
void SetNeedsCommitOnImpl();
void BeginMainFrameAbortedOnImpl(
@@ -109,6 +111,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
void DidFinishImplFrame() override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
+ void WillNotReceiveBeginFrame() override;
void ScheduledActionSendBeginMainFrame(
const viz::BeginFrameArgs& args) override;
DrawResult ScheduledActionDrawIfPossible() override;
@@ -122,6 +125,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void SendBeginMainFrameNotExpectedSoon() override;
void ScheduledActionBeginMainFrameNotExpectedUntil(
base::TimeTicks time) override;
+ void FrameIntervalUpdated(base::TimeDelta interval) override {}
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
@@ -141,10 +145,10 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
bool commit_completion_waits_for_activation_;
// Set when the main thread is waiting on a commit to complete.
- CompletionEvent* commit_completion_event_;
+ std::unique_ptr<ScopedCompletionEvent> commit_completion_event_;
// Set when the main thread is waiting for activation to complete.
- CompletionEvent* activation_completion_event_;
+ std::unique_ptr<ScopedCompletionEvent> activation_completion_event_;
// Set when the next draw should post DidCommitAndDrawFrame to the main
// thread.
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index c89bd779b18..9bee3eff2c2 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -8,7 +8,7 @@
#include <string>
#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/completion_event.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
@@ -36,7 +36,7 @@ ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host,
deferred_final_pipeline_stage_(NO_PIPELINE_STAGE),
commit_waits_for_activation_(false),
started_(false),
- defer_commits_(false),
+ defer_main_frame_update_(false),
frame_sink_bound_weak_factory_(this),
weak_factory_(this) {
TRACE_EVENT0("cc", "ProxyMain::ProxyMain");
@@ -138,10 +138,26 @@ void ProxyMain::BeginMainFrame(
layer_tree_host_->GetSwapPromiseManager());
// We need to issue image decode callbacks whether or not we will abort this
- // commit, since the request ids are only stored in |begin_main_frame_state|.
+ // update and commit, since the request ids are only stored in
+ // |begin_main_frame_state|.
layer_tree_host_->ImageDecodesFinished(
std::move(begin_main_frame_state->completed_image_decode_requests));
+ // Visibility check needs to happen before setting
+ // max_requested_pipeline_stage_. Otherwise a requested commit could get lost
+ // after tab becomes visible again.
+ if (!layer_tree_host_->IsVisible()) {
+ TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
+ std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::ABORTED_NOT_VISIBLE,
+ begin_main_frame_start_time,
+ base::Passed(&empty_swap_promises)));
+ return;
+ }
+
final_pipeline_stage_ = max_requested_pipeline_stage_;
max_requested_pipeline_stage_ = NO_PIPELINE_STAGE;
@@ -150,8 +166,8 @@ void ProxyMain::BeginMainFrame(
// have side effects on page loading behavior.
bool skip_commit = begin_main_frame_state->begin_frame_args.animate_only;
- // If commits are deferred, skip the entire pipeline.
- bool skip_full_pipeline = defer_commits_;
+ // If main frame updates and commits are deferred, skip the entire pipeline.
+ bool skip_full_pipeline = defer_main_frame_update_;
// We may have previously skipped paint and commit. If we should still skip it
// now, and there was no intermediate request for a commit since the last
@@ -180,18 +196,6 @@ void ProxyMain::BeginMainFrame(
std::max(final_pipeline_stage_, deferred_final_pipeline_stage_);
deferred_final_pipeline_stage_ = NO_PIPELINE_STAGE;
- if (!layer_tree_host_->IsVisible()) {
- TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
- std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
- base::Unretained(proxy_impl_.get()),
- CommitEarlyOutReason::ABORTED_NOT_VISIBLE,
- begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
- return;
- }
-
current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE;
// Synchronizes scroll offsets and page scale deltas (for pinch zoom) from the
@@ -219,11 +223,15 @@ void ProxyMain::BeginMainFrame(
// See LayerTreeHostClient::MainFrameUpdate for more documentation on
// what this does.
- layer_tree_host_->RequestMainFrameUpdate();
+ layer_tree_host_->RequestMainFrameUpdate(
+ true /* record_main_frame_metrics */);
+ // TODO(schenney) This will be changed to defer_commits_ when we introduce
+ // the separation between deferring of main frame updates and deferring of
+ // commits.
// At this point the main frame may have deferred commits to avoid committing
// right now.
- skip_commit |= defer_commits_;
+ skip_commit |= defer_main_frame_update_;
if (skip_commit) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
@@ -429,21 +437,21 @@ void ProxyMain::NotifyInputThrottledUntilCommit() {
base::Unretained(proxy_impl_.get()), true));
}
-void ProxyMain::SetDeferCommits(bool defer_commits) {
+void ProxyMain::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
DCHECK(IsMainThread());
- if (defer_commits_ == defer_commits)
+ if (defer_main_frame_update_ == defer_main_frame_update)
return;
- defer_commits_ = defer_commits;
- if (defer_commits_)
- TRACE_EVENT_ASYNC_BEGIN0("cc", "ProxyMain::SetDeferCommits", this);
+ defer_main_frame_update_ = defer_main_frame_update;
+ if (defer_main_frame_update_)
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "ProxyMain::SetDeferMainFrameUpdate", this);
else
- TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferCommits", this);
+ TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferMainFrameUpdate", this);
ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&ProxyImpl::SetDeferCommitsOnImpl,
- base::Unretained(proxy_impl_.get()), defer_commits));
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetDeferMainFrameUpdateOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ defer_main_frame_update));
}
bool ProxyMain::CommitRequested() const {
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index 9e32ce2d311..0005a6e1bfe 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -81,7 +81,7 @@ class CC_EXPORT ProxyMain : public Proxy {
void SetNextCommitWaitsForActivation() override;
bool RequestedAnimatePending() override;
void NotifyInputThrottledUntilCommit() override;
- void SetDeferCommits(bool defer_commits) override;
+ void SetDeferMainFrameUpdate(bool defer_main_frame_update) override;
bool CommitRequested() const override;
void Start() override;
void Stop() override;
@@ -134,7 +134,7 @@ class CC_EXPORT ProxyMain : public Proxy {
// stopped using Proxy::Stop().
bool started_;
- bool defer_commits_;
+ bool defer_main_frame_update_;
// ProxyImpl is created and destroyed on the impl thread, and should only be
// accessed on the impl thread.
diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc
index 304b451b2c3..b666e9c6633 100644
--- a/chromium/cc/trees/render_frame_metadata.cc
+++ b/chromium/cc/trees/render_frame_metadata.cc
@@ -32,6 +32,7 @@ bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
device_scale_factor == other.device_scale_factor &&
viewport_size_in_pixels == other.viewport_size_in_pixels &&
page_scale_factor == other.page_scale_factor &&
+ external_page_scale_factor == other.external_page_scale_factor &&
top_controls_height == other.top_controls_height &&
top_controls_shown_ratio == other.top_controls_shown_ratio &&
#if defined(OS_ANDROID)
@@ -44,7 +45,7 @@ bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
root_layer_size == other.root_layer_size &&
has_transparent_background == other.has_transparent_background &&
#endif
- local_surface_id == other.local_surface_id;
+ local_surface_id_allocation == other.local_surface_id_allocation;
}
bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) const {
diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h
index 8b6c45da6c4..400eeaefe0d 100644
--- a/chromium/cc/trees/render_frame_metadata.h
+++ b/chromium/cc/trees/render_frame_metadata.h
@@ -6,10 +6,11 @@
#define CC_TREES_RENDER_FRAME_METADATA_H_
#include "base/optional.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/cc_export.h"
#include "components/viz/common/quads/selection.h"
-#include "components/viz/common/surfaces/local_surface_id.h"
+#include "components/viz/common/surfaces/local_surface_id_allocation.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
@@ -61,10 +62,13 @@ class CC_EXPORT RenderFrameMetadata {
// the size of the root render pass.
gfx::Size viewport_size_in_pixels;
- // The last viz::LocalSurfaceId used to submit a CompositorFrame.
- base::Optional<viz::LocalSurfaceId> local_surface_id;
+ // The last viz::LocalSurfaceIdAllocation used to submit a CompositorFrame.
+ base::Optional<viz::LocalSurfaceIdAllocation> local_surface_id_allocation;
+ // Page scale factor (always 1.f for sub-frame renderers).
float page_scale_factor = 1.f;
+ // Used for testing propagation of page scale factor to sub-frame renderers.
+ float external_page_scale_factor = 1.f;
// Used to position the location top bar and page content, whose precise
// position is computed by the renderer compositor.
diff --git a/chromium/cc/trees/render_frame_metadata_observer.h b/chromium/cc/trees/render_frame_metadata_observer.h
index 69037c5ef5b..13b0263c5c4 100644
--- a/chromium/cc/trees/render_frame_metadata_observer.h
+++ b/chromium/cc/trees/render_frame_metadata_observer.h
@@ -32,7 +32,8 @@ class CC_EXPORT RenderFrameMetadataObserver {
// the display compositor.
virtual void OnRenderFrameSubmission(
const RenderFrameMetadata& render_frame_metadata,
- viz::CompositorFrameMetadata* compositor_frame_metadata) = 0;
+ viz::CompositorFrameMetadata* compositor_frame_metadata,
+ bool force_send) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderFrameMetadataObserver);
diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc
index 9a19d4b4b57..069c731ae98 100644
--- a/chromium/cc/trees/scroll_node.cc
+++ b/chromium/cc/trees/scroll_node.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/trace_event/trace_event_argument.h"
+#include "cc/trees/scroll_node.h"
+
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/layer.h"
#include "cc/trees/element_id.h"
#include "cc/trees/property_tree.h"
-#include "cc/trees/scroll_node.h"
+
+#include "base/trace_event/traced_value.h"
namespace cc {
diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h
index b96b696e1b3..de9f9343c8d 100644
--- a/chromium/cc/trees/scroll_node.h
+++ b/chromium/cc/trees/scroll_node.h
@@ -10,6 +10,7 @@
#include "cc/input/overscroll_behavior.h"
#include "cc/input/scroll_snap_data.h"
#include "cc/paint/filter_operations.h"
+#include "cc/trees/element_id.h"
#include "ui/gfx/geometry/size.h"
namespace base {
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 8e79bbbb4fb..2e3b7c613c1 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -9,6 +9,7 @@
#include "base/trace_event/trace_event.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
+#include "cc/input/browser_controls_offset_manager.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/compositor_timing_history.h"
@@ -46,10 +47,11 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
inside_impl_frame_(false),
#endif
inside_draw_(false),
- defer_commits_(false),
+ defer_main_frame_update_(false),
animate_requested_(false),
commit_requested_(false),
inside_synchronous_composite_(false),
+ needs_impl_frame_(false),
layer_tree_frame_sink_creation_requested_(false),
layer_tree_frame_sink_lost_(true),
frame_sink_bound_weak_factory_(this),
@@ -258,24 +260,26 @@ void SingleThreadProxy::SetNextCommitWaitsForActivation() {
}
bool SingleThreadProxy::RequestedAnimatePending() {
- return animate_requested_ || commit_requested_;
+ return animate_requested_ || commit_requested_ || needs_impl_frame_;
}
-void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
+void SingleThreadProxy::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
DCHECK(task_runner_provider_->IsMainThread());
// Deferring commits only makes sense if there's a scheduler.
if (!scheduler_on_impl_thread_)
return;
- if (defer_commits_ == defer_commits)
+ if (defer_main_frame_update_ == defer_main_frame_update)
return;
- if (defer_commits)
- TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
+ if (defer_main_frame_update)
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
+ this);
else
- TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
+ TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
+ this);
- defer_commits_ = defer_commits;
- scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
+ defer_main_frame_update_ = defer_main_frame_update;
+ scheduler_on_impl_thread_->SetDeferMainFrameUpdate(defer_main_frame_update);
}
bool SingleThreadProxy::CommitRequested() const {
@@ -346,6 +350,7 @@ void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() {
single_thread_client_->RequestScheduleComposite();
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame();
+ needs_impl_frame_ = true;
}
void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
@@ -358,6 +363,7 @@ void SingleThreadProxy::SetNeedsCommitOnImplThread() {
single_thread_client_->RequestScheduleComposite();
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
+ commit_requested_ = true;
}
void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
@@ -528,6 +534,7 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
DCHECK(inside_impl_frame_);
#endif
animate_requested_ = false;
+ needs_impl_frame_ = false;
// Prevent new commits from being requested inside DoBeginMainFrame.
// Note: We do not want to prevent SetNeedsAnimate from requesting
// a commit here.
@@ -660,6 +667,14 @@ void SingleThreadProxy::SetRenderFrameObserver(
host_impl_->SetRenderFrameObserver(std::move(observer));
}
+void SingleThreadProxy::UpdateBrowserControlsState(
+ BrowserControlsState constraints,
+ BrowserControlsState current,
+ bool animate) {
+ host_impl_->browser_controls_manager()->UpdateBrowserControlsState(
+ constraints, current, animate);
+}
+
bool SingleThreadProxy::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
DebugScopedSetImplThread impl(task_runner_provider_);
#if DCHECK_IS_ON()
@@ -685,12 +700,18 @@ void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
<< "BeginMainFrame should only be sent inside a BeginImplFrame";
#endif
+ host_impl_->WillSendBeginMainFrame();
task_runner_provider_->MainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
weak_factory_.GetWeakPtr(), begin_frame_args));
host_impl_->DidSendBeginMainFrame();
}
+void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
+ DebugScopedSetMainThread main(task_runner_provider_);
+ single_thread_client_->FrameIntervalUpdated(interval);
+}
+
void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
layer_tree_host_->BeginMainFrameNotExpectedSoon();
}
@@ -713,9 +734,10 @@ void SingleThreadProxy::BeginMainFrame(
}
commit_requested_ = false;
+ needs_impl_frame_ = false;
animate_requested_ = false;
- if (defer_commits_) {
+ if (defer_main_frame_update_) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
TRACE_EVENT_SCOPE_THREAD);
BeginMainFrameAbortedOnImplThread(
@@ -742,7 +764,7 @@ void SingleThreadProxy::BeginMainFrame(
// At this point the main frame may have deferred commits to avoid committing
// right now.
- if (defer_commits_ || begin_frame_args.animate_only) {
+ if (defer_main_frame_update_ || begin_frame_args.animate_only) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
TRACE_EVENT_SCOPE_THREAD);
BeginMainFrameAbortedOnImplThread(
@@ -775,7 +797,8 @@ void SingleThreadProxy::DoBeginMainFrame(
layer_tree_host_->WillBeginMainFrame();
layer_tree_host_->BeginMainFrame(begin_frame_args);
layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
- layer_tree_host_->RequestMainFrameUpdate();
+ layer_tree_host_->RequestMainFrameUpdate(
+ false /* record_main_frame_metrics */);
}
void SingleThreadProxy::DoPainting() {
@@ -877,6 +900,10 @@ void SingleThreadProxy::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
host_impl_->DidNotProduceFrame(ack);
}
+void SingleThreadProxy::WillNotReceiveBeginFrame() {
+ host_impl_->DidNotNeedBeginFrame();
+}
+
void SingleThreadProxy::DidReceiveCompositorFrameAck() {
layer_tree_host_->DidReceiveCompositorFrameAck();
}
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 0ff0f79de6e..ca922056575 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -51,7 +51,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void SetNextCommitWaitsForActivation() override;
bool RequestedAnimatePending() override;
void NotifyInputThrottledUntilCommit() override {}
- void SetDeferCommits(bool defer_commits) override;
+ void SetDeferMainFrameUpdate(bool defer_main_frame_update) override;
bool CommitRequested() const override;
void Start() override;
void Stop() override;
@@ -67,16 +67,15 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
- // Blink layout tests might call into this even though an unthreaded CC
- // doesn't have BrowserControls itself.
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
- bool animate) override {}
+ bool animate) override;
// SchedulerClient implementation
bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
void DidFinishImplFrame() override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
+ void WillNotReceiveBeginFrame() override;
void ScheduledActionSendBeginMainFrame(
const viz::BeginFrameArgs& args) override;
DrawResult ScheduledActionDrawIfPossible() override;
@@ -90,6 +89,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void SendBeginMainFrameNotExpectedSoon() override;
void ScheduledActionBeginMainFrameNotExpectedUntil(
base::TimeTicks time) override;
+ void FrameIntervalUpdated(base::TimeDelta interval) override;
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
@@ -174,10 +174,11 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
bool inside_impl_frame_;
#endif
bool inside_draw_;
- bool defer_commits_;
+ bool defer_main_frame_update_;
bool animate_requested_;
bool commit_requested_;
bool inside_synchronous_composite_;
+ bool needs_impl_frame_;
// True if a request to the LayerTreeHostClient to create an output surface
// is still outstanding.
diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc
index c43fd23fbe1..9964f16880b 100644
--- a/chromium/cc/trees/transform_node.cc
+++ b/chromium/cc/trees/transform_node.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/trace_event/trace_event_argument.h"
+#include "cc/trees/transform_node.h"
+#include "base/trace_event/traced_value.h"
#include "cc/base/math_util.h"
#include "cc/layers/layer.h"
#include "cc/trees/property_tree.h"
-#include "cc/trees/transform_node.h"
#include "ui/gfx/geometry/point3_f.h"
namespace cc {
diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h
index 931867550f8..c8f8ebf8505 100644
--- a/chromium/cc/trees/transform_node.h
+++ b/chromium/cc/trees/transform_node.h
@@ -6,6 +6,7 @@
#define CC_TREES_TRANSFORM_NODE_H_
#include "cc/cc_export.h"
+#include "cc/trees/element_id.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/transform.h"
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index c4b44c933c8..c31289f46cf 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -87,6 +87,25 @@ void PushLayerList(OwnedLayerImplMap* old_layers,
}
template <typename LayerTreeType>
+void PushElementsInPropertyTreesTo(LayerTreeType* host,
+ LayerTreeImpl* tree_impl) {
+ for (auto id_iter = tree_impl->elements_in_property_trees().begin();
+ id_iter != tree_impl->elements_in_property_trees().end();) {
+ const auto& id = *(id_iter++);
+ if (!host->elements_in_property_trees().count(id))
+ tree_impl->RemoveFromElementLayerList(id);
+ }
+
+ for (const auto& id : host->elements_in_property_trees()) {
+ if (!tree_impl->IsElementInLayerList(id)) {
+ // TODO(flackr): We should expose adding element ids without a
+ // layer pointer.
+ tree_impl->AddToElementLayerList(id, nullptr);
+ }
+ }
+}
+
+template <typename LayerTreeType>
void SynchronizeTreesInternal(LayerTreeType* source_tree,
LayerTreeImpl* tree_impl,
PropertyTrees* property_trees) {
@@ -154,6 +173,8 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeImpl* pending_tree,
PushLayerPropertiesInternal(layers.begin(), layers.end(), active_tree);
PushLayerPropertiesInternal(picture_layers.begin(), picture_layers.end(),
active_tree);
+ if (pending_tree->settings().use_layer_lists)
+ PushElementsInPropertyTreesTo(pending_tree, active_tree);
pending_tree->ClearLayersThatShouldPushProperties();
}
@@ -163,6 +184,10 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeHost* host_tree,
TRACE_EVENT1("cc", "TreeSynchronizer::PushLayerPropertiesTo.Main",
"layer_count", layers.size());
PushLayerPropertiesInternal(layers.begin(), layers.end(), 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())
+ PushElementsInPropertyTreesTo(host_tree, impl_tree);
host_tree->ClearLayersThatShouldPushProperties();
}
diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc
index c49b0f0fb1c..547dccae6ef 100644
--- a/chromium/cc/trees/tree_synchronizer_unittest.cc
+++ b/chromium/cc/trees/tree_synchronizer_unittest.cc
@@ -131,13 +131,44 @@ void ExpectTreesAreIdentical(Layer* root_layer,
}
class TreeSynchronizerTest : public testing::Test {
+ public:
+ void ResetLayerTreeHost(const LayerTreeSettings& settings) {
+ host_ = FakeLayerTreeHost::Create(&client_, &task_graph_runner_,
+ animation_host_.get(), settings);
+ host_->host_impl()->CreatePendingTree();
+ }
+
+ scoped_refptr<Layer> SetupScrollLayer() {
+ FakeLayerTreeHostImpl* host_impl = host_->host_impl();
+
+ scoped_refptr<Layer> layer_tree_root = Layer::Create();
+ scoped_refptr<Layer> scroll_layer = Layer::Create();
+
+ ElementId scroll_element_id = ElementId(5);
+ scroll_layer->SetElementId(scroll_element_id);
+
+ layer_tree_root->AddChild(scroll_layer);
+
+ scroll_layer->SetScrollable(gfx::Size(1, 1));
+ scroll_layer->SetBounds(gfx::Size(10, 10));
+
+ host_->SetRootLayer(layer_tree_root);
+ host_->BuildPropertyTreesForTesting();
+ host_->CommitAndCreatePendingTree();
+ host_impl->ActivateSyncTree();
+
+ ExpectTreesAreIdentical(layer_tree_root.get(),
+ host_impl->active_tree()->root_layer_for_testing(),
+ host_impl->active_tree());
+
+ return scroll_layer;
+ }
+
protected:
TreeSynchronizerTest()
- : animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)),
- host_(FakeLayerTreeHost::Create(&client_,
- &task_graph_runner_,
- animation_host_.get())) {
- host_->host_impl()->CreatePendingTree();
+ : animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)) {
+ LayerTreeSettings settings;
+ ResetLayerTreeHost(settings);
}
FakeLayerTreeHostClient client_;
@@ -658,7 +689,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) {
// Pull ScrollOffset delta for main thread, and change offset on main thread
std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
- scroll_tree.CollectScrollDeltas(scroll_info.get(), ElementId());
+ scroll_tree.CollectScrollDeltas(scroll_info.get(), ElementId(),
+ settings.commit_fractional_scroll_deltas);
host_->proxy()->SetNeedsCommit();
host_->ApplyScrollAndScale(scroll_info.get());
EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->CurrentScrollOffset());
@@ -741,5 +773,53 @@ TEST_F(TreeSynchronizerTest, RefreshPropertyTreesCachedData) {
transform_layer->transform_tree_index(), host_impl->active_tree()));
}
+TEST_F(TreeSynchronizerTest, RoundedScrollDeltasOnCommit) {
+ LayerTreeSettings settings;
+ settings.commit_fractional_scroll_deltas = false;
+ ResetLayerTreeHost(settings);
+
+ host_->InitializeSingleThreaded(&single_thread_client_,
+ base::ThreadTaskRunnerHandle::Get());
+
+ scoped_refptr<Layer> scroll_layer = SetupScrollLayer();
+
+ // Scroll the layer by a fractional amount.
+ FakeLayerTreeHostImpl* host_impl = host_->host_impl();
+ LayerImpl* scroll_layer_impl =
+ host_impl->active_tree()->LayerById(scroll_layer->id());
+ scroll_layer_impl->ScrollBy(gfx::Vector2dF(0, 1.75f));
+
+ // When we collect the scroll deltas, we should have truncated the fractional
+ // part because the commit_fractional_scroll_deltas setting is enabled.
+ std::unique_ptr<ScrollAndScaleSet> scroll_info =
+ host_impl->ProcessScrollDeltas();
+ ASSERT_EQ(1u, scroll_info->scrolls.size());
+ EXPECT_EQ(2.f, scroll_info->scrolls[0].scroll_delta.y());
+}
+
+TEST_F(TreeSynchronizerTest, PreserveFractionalScrollDeltasOnCommit) {
+ LayerTreeSettings settings;
+ settings.commit_fractional_scroll_deltas = true;
+ ResetLayerTreeHost(settings);
+
+ host_->InitializeSingleThreaded(&single_thread_client_,
+ base::ThreadTaskRunnerHandle::Get());
+
+ scoped_refptr<Layer> scroll_layer = SetupScrollLayer();
+
+ // Scroll the layer by a fractional amount.
+ FakeLayerTreeHostImpl* host_impl = host_->host_impl();
+ LayerImpl* scroll_layer_impl =
+ host_impl->active_tree()->LayerById(scroll_layer->id());
+ scroll_layer_impl->ScrollBy(gfx::Vector2dF(0, 1.75f));
+
+ // When we collect the scroll deltas, we should keep the fractional part
+ // because the commit_fractional_scroll_deltas setting is disabled.
+ std::unique_ptr<ScrollAndScaleSet> scroll_info =
+ host_impl->ProcessScrollDeltas();
+ ASSERT_EQ(1u, scroll_info->scrolls.size());
+ EXPECT_EQ(1.75f, scroll_info->scrolls[0].scroll_delta.y());
+}
+
} // namespace
} // namespace cc