summaryrefslogtreecommitdiff
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-24 12:15:48 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:30:04 +0000
commitb014812705fc80bff0a5c120dfcef88f349816dc (patch)
tree25a2e2d9fa285f1add86aa333389a839f81a39ae /chromium/cc
parent9f4560b1027ae06fdb497023cdcaf91b8511fa74 (diff)
downloadqtwebengine-chromium-b014812705fc80bff0a5c120dfcef88f349816dc.tar.gz
BASELINE: Update Chromium to 68.0.3440.125
Change-Id: I23f19369e01f688e496f5bf179abb521ad73874f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn29
-rw-r--r--chromium/cc/DEPS2
-rw-r--r--chromium/cc/OWNERS3
-rw-r--r--chromium/cc/PRESUBMIT.py20
-rw-r--r--chromium/cc/animation/animation.cc2
-rw-r--r--chromium/cc/animation/animation.h2
-rw-r--r--chromium/cc/animation/animation_curve.h10
-rw-r--r--chromium/cc/animation/animation_host.cc16
-rw-r--r--chromium/cc/animation/animation_host.h3
-rw-r--r--chromium/cc/animation/keyframe_effect.cc24
-rw-r--r--chromium/cc/animation/keyframe_effect.h11
-rw-r--r--chromium/cc/animation/keyframe_model.cc73
-rw-r--r--chromium/cc/animation/keyframe_model.h16
-rw-r--r--chromium/cc/animation/keyframe_model_unittest.cc56
-rw-r--r--chromium/cc/animation/keyframed_animation_curve.cc22
-rw-r--r--chromium/cc/animation/keyframed_animation_curve.h2
-rw-r--r--chromium/cc/animation/keyframed_animation_curve_unittest.cc26
-rw-r--r--chromium/cc/animation/timing_function.cc15
-rw-r--r--chromium/cc/animation/timing_function.h5
-rw-r--r--chromium/cc/animation/worklet_animation.cc34
-rw-r--r--chromium/cc/animation/worklet_animation.h14
-rw-r--r--chromium/cc/animation/worklet_animation_player_unittest.cc135
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc30
-rw-r--r--chromium/cc/base/list_container.h16
-rw-r--r--chromium/cc/base/list_container_unittest.cc226
-rw-r--r--chromium/cc/base/switches.cc9
-rw-r--r--chromium/cc/base/switches.h2
-rw-r--r--chromium/cc/blink/BUILD.gn75
-rw-r--r--chromium/cc/blink/DEPS3
-rw-r--r--chromium/cc/blink/OWNERS1
-rw-r--r--chromium/cc/blink/cc_blink_export.h29
-rw-r--r--chromium/cc/blink/scrollbar_impl.cc137
-rw-r--r--chromium/cc/blink/scrollbar_impl.h59
-rw-r--r--chromium/cc/blink/web_blend_mode.h107
-rw-r--r--chromium/cc/blink/web_compositor_support_impl.cc90
-rw-r--r--chromium/cc/blink/web_compositor_support_impl.h50
-rw-r--r--chromium/cc/blink/web_content_layer_impl.cc95
-rw-r--r--chromium/cc/blink/web_content_layer_impl.h53
-rw-r--r--chromium/cc/blink/web_display_item_list_impl.cc209
-rw-r--r--chromium/cc/blink/web_display_item_list_impl.h79
-rw-r--r--chromium/cc/blink/web_display_item_list_impl_unittest.cc91
-rw-r--r--chromium/cc/blink/web_external_texture_layer_impl.cc65
-rw-r--r--chromium/cc/blink/web_external_texture_layer_impl.h45
-rw-r--r--chromium/cc/blink/web_image_layer_impl.cc40
-rw-r--r--chromium/cc/blink/web_image_layer_impl.h39
-rw-r--r--chromium/cc/blink/web_layer_impl.cc523
-rw-r--r--chromium/cc/blink/web_layer_impl.h149
-rw-r--r--chromium/cc/blink/web_layer_impl_fixed_bounds.cc97
-rw-r--r--chromium/cc/blink/web_layer_impl_fixed_bounds.h51
-rw-r--r--chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc181
-rw-r--r--chromium/cc/blink/web_scrollbar_layer_impl.cc80
-rw-r--r--chromium/cc/blink/web_scrollbar_layer_impl.h52
-rw-r--r--chromium/cc/input/input_handler.h6
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.cc78
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.h80
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason_unittest.cc38
-rw-r--r--chromium/cc/input/scrollbar_animation_controller_unittest.cc2
-rw-r--r--chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc2
-rw-r--r--chromium/cc/input/snap_fling_controller.cc92
-rw-r--r--chromium/cc/input/snap_fling_controller.h106
-rw-r--r--chromium/cc/input/snap_fling_controller_unittest.cc157
-rw-r--r--chromium/cc/input/snap_fling_curve.cc119
-rw-r--r--chromium/cc/input/snap_fling_curve.h78
-rw-r--r--chromium/cc/input/snap_fling_curve_unittest.cc71
-rw-r--r--chromium/cc/ipc/BUILD.gn40
-rw-r--r--chromium/cc/ipc/DEPS10
-rw-r--r--chromium/cc/ipc/OWNERS11
-rw-r--r--chromium/cc/ipc/cc_ipc_export.h29
-rw-r--r--chromium/cc/ipc/cc_param_traits.cc1006
-rw-r--r--chromium/cc/ipc/cc_param_traits.h160
-rw-r--r--chromium/cc/ipc/cc_param_traits_macros.h205
-rw-r--r--chromium/cc/ipc/cc_param_traits_unittest.cc665
-rw-r--r--chromium/cc/ipc/cc_serialization_perftest.cc466
-rw-r--r--chromium/cc/layers/content_layer_client.h6
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc35
-rw-r--r--chromium/cc/layers/layer.cc42
-rw-r--r--chromium/cc/layers/layer.h47
-rw-r--r--chromium/cc/layers/layer_client.h10
-rw-r--r--chromium/cc/layers/layer_impl.cc29
-rw-r--r--chromium/cc/layers/layer_impl.h9
-rw-r--r--chromium/cc/layers/layer_unittest.cc37
-rw-r--r--chromium/cc/layers/nine_patch_layer_impl.h1
-rw-r--r--chromium/cc/layers/nine_patch_layer_unittest.cc1
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc15
-rw-r--r--chromium/cc/layers/picture_layer_impl.h9
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc18
-rw-r--r--chromium/cc/layers/render_surface_impl.cc213
-rw-r--r--chromium/cc/layers/render_surface_impl.h2
-rw-r--r--chromium/cc/layers/render_surface_impl_unittest.cc5
-rw-r--r--chromium/cc/layers/render_surface_unittest.cc4
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc4
-rw-r--r--chromium/cc/layers/solid_color_layer_impl_unittest.cc4
-rw-r--r--chromium/cc/layers/surface_layer.cc8
-rw-r--r--chromium/cc/layers/surface_layer.h13
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc8
-rw-r--r--chromium/cc/layers/surface_layer_impl.h6
-rw-r--r--chromium/cc/layers/texture_layer.cc45
-rw-r--r--chromium/cc/layers/texture_layer.h10
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc60
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl.h2
-rw-r--r--chromium/cc/layers/ui_resource_layer_unittest.cc1
-rw-r--r--chromium/cc/layers/video_frame_provider_client_impl_unittest.cc2
-rw-r--r--chromium/cc/layers/video_layer_impl.cc7
-rw-r--r--chromium/cc/layers/viewport.cc1
-rw-r--r--chromium/cc/layers/viewport.h3
-rw-r--r--chromium/cc/output/overlay_candidate.cc395
-rw-r--r--chromium/cc/output/overlay_candidate.h142
-rw-r--r--chromium/cc/paint/BUILD.gn5
-rw-r--r--chromium/cc/paint/DEPS1
-rw-r--r--chromium/cc/paint/display_item_list.h3
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc11
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.h3
-rw-r--r--chromium/cc/paint/oop_pixeltest.cc326
-rw-r--r--chromium/cc/paint/paint_filter.cc3
-rw-r--r--chromium/cc/paint/paint_image.cc8
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc189
-rw-r--r--chromium/cc/paint/paint_op_buffer.h42
-rw-r--r--chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc24
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc65
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.cc125
-rw-r--r--chromium/cc/paint/paint_op_buffer_serializer.h26
-rw-r--r--chromium/cc/paint/paint_op_buffer_unittest.cc435
-rw-r--r--chromium/cc/paint/paint_op_perftest.cc18
-rw-r--r--chromium/cc/paint/paint_op_reader.cc168
-rw-r--r--chromium/cc/paint/paint_op_reader.h13
-rw-r--r--chromium/cc/paint/paint_op_writer.cc216
-rw-r--r--chromium/cc/paint/paint_op_writer.h37
-rw-r--r--chromium/cc/paint/paint_shader.cc121
-rw-r--r--chromium/cc/paint/paint_shader.h39
-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/scoped_raster_flags.cc88
-rw-r--r--chromium/cc/paint/scoped_raster_flags.h5
-rw-r--r--chromium/cc/paint/scoped_raster_flags_unittest.cc6
-rw-r--r--chromium/cc/paint/shader_transfer_cache_entry.cc31
-rw-r--r--chromium/cc/paint/shader_transfer_cache_entry.h46
-rw-r--r--chromium/cc/paint/skia_paint_canvas.cc36
-rw-r--r--chromium/cc/paint/skia_paint_canvas.h3
-rw-r--r--chromium/cc/paint/skia_paint_image_generator.cc4
-rw-r--r--chromium/cc/paint/skia_paint_image_generator.h2
-rw-r--r--chromium/cc/paint/solid_color_analyzer.cc9
-rw-r--r--chromium/cc/paint/transfer_cache_deserialize_helper.h12
-rw-r--r--chromium/cc/paint/transfer_cache_entry.cc8
-rw-r--r--chromium/cc/paint/transfer_cache_entry.h4
-rw-r--r--chromium/cc/paint/transfer_cache_unittest.cc55
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc18
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.h6
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc55
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.h13
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc42
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.h21
-rw-r--r--chromium/cc/raster/raster_buffer_provider.cc32
-rw-r--r--chromium/cc/raster/raster_buffer_provider.h16
-rw-r--r--chromium/cc/raster/raster_buffer_provider_perftest.cc50
-rw-r--r--chromium/cc/raster/raster_buffer_provider_unittest.cc48
-rw-r--r--chromium/cc/raster/staging_buffer_pool.cc8
-rw-r--r--chromium/cc/raster/staging_buffer_pool.h11
-rw-r--r--chromium/cc/raster/staging_buffer_pool_unittest.cc5
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.cc30
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.h13
-rw-r--r--chromium/cc/resources/display_resource_provider.cc829
-rw-r--r--chromium/cc/resources/display_resource_provider.h315
-rw-r--r--chromium/cc/resources/display_resource_provider_unittest.cc548
-rw-r--r--chromium/cc/resources/layer_tree_resource_provider.cc817
-rw-r--r--chromium/cc/resources/layer_tree_resource_provider.h291
-rw-r--r--chromium/cc/resources/layer_tree_resource_provider_unittest.cc336
-rw-r--r--chromium/cc/resources/resource.h52
-rw-r--r--chromium/cc/resources/resource_pool.cc25
-rw-r--r--chromium/cc/resources/resource_pool.h20
-rw-r--r--chromium/cc/resources/resource_pool_unittest.cc41
-rw-r--r--chromium/cc/resources/resource_provider.cc301
-rw-r--r--chromium/cc/resources/resource_provider.h133
-rw-r--r--chromium/cc/resources/resource_provider_unittest.cc3709
-rw-r--r--chromium/cc/resources/resource_util_unittest.cc171
-rw-r--r--chromium/cc/resources/return_callback.h18
-rw-r--r--chromium/cc/resources/video_resource_updater.cc118
-rw-r--r--chromium/cc/resources/video_resource_updater.h22
-rw-r--r--chromium/cc/resources/video_resource_updater_unittest.cc146
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.cc30
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.h2
-rw-r--r--chromium/cc/scheduler/compositor_timing_history_unittest.cc144
-rw-r--r--chromium/cc/scheduler/scheduler.cc2
-rw-r--r--chromium/cc/scheduler/scheduler.h1
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc2
-rw-r--r--chromium/cc/tiles/checker_image_tracker.cc31
-rw-r--r--chromium/cc/tiles/checker_image_tracker_unittest.cc8
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.cc6
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.h9
-rw-r--r--chromium/cc/tiles/decoded_image_tracker_unittest.cc4
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc167
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.h27
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc121
-rw-r--r--chromium/cc/tiles/image_decode_cache.h6
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_set_unittest.cc9
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc25
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.h1
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest.cc112
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.cc11
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.h6
-rw-r--r--chromium/cc/tiles/tile_manager.cc23
-rw-r--r--chromium/cc/tiles/tile_manager.h8
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc140
-rw-r--r--chromium/cc/trees/draw_property_utils.cc20
-rw-r--r--chromium/cc/trees/draw_property_utils.h2
-rw-r--r--chromium/cc/trees/latency_info_swap_promise.cc3
-rw-r--r--chromium/cc/trees/latency_info_swap_promise_monitor.cc23
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.cc4
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h35
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h8
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_unittest.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host.cc125
-rw-r--r--chromium/cc/trees/layer_tree_host.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc491
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc404
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc39
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc73
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc686
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc61
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc57
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_masks.cc666
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc18
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc4
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc30
-rw-r--r--chromium/cc/trees/layer_tree_impl.h17
-rw-r--r--chromium/cc/trees/layer_tree_settings.cc3
-rw-r--r--chromium/cc/trees/layer_tree_settings.h6
-rw-r--r--chromium/cc/trees/mutator_host.h1
-rw-r--r--chromium/cc/trees/proxy_impl.cc4
-rw-r--r--chromium/cc/trees/proxy_impl.h1
-rw-r--r--chromium/cc/trees/proxy_main.cc2
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc24
-rw-r--r--chromium/cc/trees/render_frame_metadata.h32
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc12
-rw-r--r--chromium/cc/trees/single_thread_proxy.h1
240 files changed, 6085 insertions, 16111 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index 19828e3374a..4f6b936f03f 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# Copyright 2014 T/e 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.
@@ -33,6 +33,7 @@ cc_component("cc") {
"input/input_handler.h",
"input/layer_selection_bound.cc",
"input/layer_selection_bound.h",
+ "input/main_thread_scrolling_reason.cc",
"input/main_thread_scrolling_reason.h",
"input/overscroll_behavior.h",
"input/page_scale_animation.cc",
@@ -49,6 +50,10 @@ cc_component("cc") {
"input/scrollbar_animation_controller.h",
"input/single_scrollbar_animation_controller_thinning.cc",
"input/single_scrollbar_animation_controller_thinning.h",
+ "input/snap_fling_controller.cc",
+ "input/snap_fling_controller.h",
+ "input/snap_fling_curve.cc",
+ "input/snap_fling_curve.h",
"input/touch_action.h",
"layers/append_quads_data.cc",
"layers/append_quads_data.h",
@@ -137,8 +142,6 @@ cc_component("cc") {
"layers/video_layer_impl.h",
"layers/viewport.cc",
"layers/viewport.h",
- "output/overlay_candidate.cc",
- "output/overlay_candidate.h",
"raster/bitmap_raster_buffer_provider.cc",
"raster/bitmap_raster_buffer_provider.h",
"raster/gpu_raster_buffer_provider.cc",
@@ -177,17 +180,12 @@ cc_component("cc") {
"raster/zero_copy_raster_buffer_provider.h",
"resources/cross_thread_shared_bitmap.cc",
"resources/cross_thread_shared_bitmap.h",
- "resources/display_resource_provider.cc",
- "resources/display_resource_provider.h",
"resources/layer_tree_resource_provider.cc",
"resources/layer_tree_resource_provider.h",
"resources/memory_history.cc",
"resources/memory_history.h",
- "resources/resource.h",
"resources/resource_pool.cc",
"resources/resource_pool.h",
- "resources/resource_provider.cc",
- "resources/resource_provider.h",
"resources/scoped_ui_resource.cc",
"resources/scoped_ui_resource.h",
"resources/shared_bitmap_id_registrar.cc",
@@ -509,6 +507,8 @@ cc_static_library("test_support") {
"test/test_layer_tree_host_base.cc",
"test/test_layer_tree_host_base.h",
"test/test_occlusion_tracker.h",
+ "test/test_options_provider.cc",
+ "test/test_options_provider.h",
"test/test_skcanvas.cc",
"test/test_skcanvas.h",
"test/test_task_graph_runner.cc",
@@ -527,6 +527,7 @@ cc_static_library("test_support") {
":cc",
"//cc/animation",
"//gpu:test_support",
+ "//testing/gmock",
]
deps = [
"//base",
@@ -545,7 +546,6 @@ cc_static_library("test_support") {
"//gpu/skia_bindings",
"//media",
"//skia",
- "//testing/gmock",
"//testing/gtest",
"//ui/gfx",
"//ui/gfx:test_support",
@@ -579,11 +579,13 @@ cc_test("cc_unittests") {
"benchmarks/micro_benchmark_controller_unittest.cc",
"debug/rendering_stats_unittest.cc",
"input/browser_controls_offset_manager_unittest.cc",
+ "input/main_thread_scrolling_reason_unittest.cc",
"input/scroll_snap_data_unittest.cc",
"input/scroll_state_unittest.cc",
"input/scrollbar_animation_controller_unittest.cc",
"input/single_scrollbar_animation_controller_thinning_unittest.cc",
- "ipc/cc_param_traits_unittest.cc",
+ "input/snap_fling_controller_unittest.cc",
+ "input/snap_fling_curve_unittest.cc",
"layers/effect_tree_layer_list_iterator_unittest.cc",
"layers/heads_up_display_layer_impl_unittest.cc",
"layers/heads_up_display_unittest.cc",
@@ -638,11 +640,8 @@ cc_test("cc_unittests") {
"raster/synchronous_task_graph_runner_unittest.cc",
"raster/task_graph_work_queue_unittest.cc",
"raster/texture_compressor_etc1_unittest.cc",
- "resources/display_resource_provider_unittest.cc",
"resources/layer_tree_resource_provider_unittest.cc",
"resources/resource_pool_unittest.cc",
- "resources/resource_provider_unittest.cc",
- "resources/resource_util_unittest.cc",
"resources/video_resource_updater_unittest.cc",
"scheduler/compositor_timing_history_unittest.cc",
"scheduler/scheduler_state_machine_unittest.cc",
@@ -677,6 +676,7 @@ cc_test("cc_unittests") {
"trees/layer_tree_host_unittest_context.cc",
"trees/layer_tree_host_unittest_copyrequest.cc",
"trees/layer_tree_host_unittest_damage.cc",
+ "trees/layer_tree_host_unittest_masks.cc",
"trees/layer_tree_host_unittest_occlusion.cc",
"trees/layer_tree_host_unittest_picture.cc",
"trees/layer_tree_host_unittest_proxy.cc",
@@ -729,7 +729,6 @@ cc_test("cc_unittests") {
":cc",
":test_support",
"//base/test:test_support",
- "//cc/ipc",
"//cc/paint",
"//components/ukm:test_support",
"//components/viz/common",
@@ -765,7 +764,6 @@ cc_test("cc_perftests") {
sources = [
"animation/animation_host_perftest.cc",
"base/rtree_perftest.cc",
- "ipc/cc_serialization_perftest.cc",
"layers/layer_perftest.cc",
"layers/picture_layer_impl_perftest.cc",
"paint/paint_op_perftest.cc",
@@ -786,7 +784,6 @@ cc_test("cc_perftests") {
":test_support",
"//base",
"//base/test:test_support",
- "//cc/ipc",
"//cc/paint",
"//components/viz/common",
"//components/viz/test:test_support",
diff --git a/chromium/cc/DEPS b/chromium/cc/DEPS
index fb06dd1e017..2e684073776 100644
--- a/chromium/cc/DEPS
+++ b/chromium/cc/DEPS
@@ -27,10 +27,10 @@ include_rules = [
"+third_party/khronos/GLES2/gl2ext.h",
"+third_party/libyuv",
"+third_party/skia/include",
+ "+third_party/skia/src/core/SkRemoteGlyphCache.h",
"+ui/latency/latency_info.h",
"+ui/gfx",
"+ui/gl",
- "-cc/blink",
]
specific_include_rules = {
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index 169e4a1ea5f..5a453bed667 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -59,6 +59,9 @@ vmpstr@chromium.org
fsamuel@chromium.org
kylechar@chromium.org
+# input, scrolling
+bokan@chromium.org
+
# we miss you
# jamesr@chromium.org
# nduca@chromium.org
diff --git a/chromium/cc/PRESUBMIT.py b/chromium/cc/PRESUBMIT.py
index 3ddbde82ec0..3e27d70855f 100644
--- a/chromium/cc/PRESUBMIT.py
+++ b/chromium/cc/PRESUBMIT.py
@@ -275,25 +275,6 @@ def CheckForUseOfWrongClock(input_api,
else:
return []
-def CheckIpcUpdatedWithMojo(input_api, output_api):
- """Make sure IPC is updated whenever Mojo serialization is updated"""
- def match_ipc(affected_file):
- match = re.match(r'.*_param_traits.*', affected_file.LocalPath())
- return match is not None
-
- def match_mojo(affected_file):
- mojo_patterns = (r'.*_struct_traits.*', r'.*\.mojom$', r'.*\.typemap$')
- matches = (re.match(pattern, affected_file.LocalPath())
- for pattern in mojo_patterns)
- return any(matches)
-
- ipc_files = input_api.AffectedFiles(file_filter=match_ipc)
- mojo_files = input_api.AffectedFiles(file_filter=match_mojo)
- if mojo_files and not ipc_files:
- return [output_api.PresubmitPromptOrNotify(
- 'Make sure to update IPC ParamTraits along with mojo types.\n\n'),]
- return []
-
def CheckChangeOnUpload(input_api, output_api):
results = []
results += CheckAsserts(input_api, output_api)
@@ -305,7 +286,6 @@ def CheckChangeOnUpload(input_api, output_api):
results += CheckNamespace(input_api, output_api)
results += CheckForUseOfWrongClock(input_api, output_api)
results += FindUselessIfdefs(input_api, output_api)
- results += CheckIpcUpdatedWithMojo(input_api, output_api)
return results
def PostUploadHook(cl, change, output_api):
diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc
index 8dd68bea444..57af2598821 100644
--- a/chromium/cc/animation/animation.cc
+++ b/chromium/cc/animation/animation.cc
@@ -243,7 +243,7 @@ void Animation::PushPropertiesTo(Animation* animation_impl) {
void Animation::Tick(base::TimeTicks monotonic_time) {
DCHECK(!monotonic_time.is_null());
for (auto& keyframe_effect : keyframe_effects_)
- keyframe_effect->Tick(monotonic_time, nullptr);
+ keyframe_effect->Tick(monotonic_time);
}
void Animation::UpdateState(bool start_ready_animations,
diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h
index 64ddcae8eb6..6ac050dfabe 100644
--- a/chromium/cc/animation/animation.h
+++ b/chromium/cc/animation/animation.h
@@ -90,7 +90,7 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
void AbortKeyframeModels(TargetProperty::Type target_property,
bool needs_completion);
- virtual void PushPropertiesTo(Animation* animation_impl);
+ void PushPropertiesTo(Animation* animation_impl);
void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
virtual void Tick(base::TimeTicks monotonic_time);
diff --git a/chromium/cc/animation/animation_curve.h b/chromium/cc/animation/animation_curve.h
index 9865878afd8..34979f7b57c 100644
--- a/chromium/cc/animation/animation_curve.h
+++ b/chromium/cc/animation/animation_curve.h
@@ -13,10 +13,6 @@
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/transform.h"
-namespace gfx {
-class BoxF;
-}
-
namespace cc {
class ColorAnimationCurve;
@@ -81,12 +77,6 @@ class CC_ANIMATION_EXPORT TransformAnimationCurve : public AnimationCurve {
virtual TransformOperations GetValue(base::TimeDelta t) const = 0;
- // Sets |bounds| to be the bounding box for the region within which |box|
- // will move during this animation. If this region cannot be computed,
- // returns false.
- virtual bool AnimatedBoundsForBox(const gfx::BoxF& box,
- gfx::BoxF* bounds) const = 0;
-
// Returns true if this animation is a translation.
virtual bool IsTranslation() const = 0;
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index 0b17d50a78e..cc1f51ad0f3 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -257,8 +257,6 @@ void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_impl) {
scroll_offset_animations_->PushPropertiesTo(
host_impl->scroll_offset_animations_impl_.get());
host_impl->main_thread_animations_count_ = main_thread_animations_count_;
- host_impl->main_thread_compositable_animations_count_ =
- main_thread_compositable_animations_count_;
host_impl->current_frame_had_raf_ = current_frame_had_raf_;
host_impl->next_frame_has_pending_raf_ = next_frame_has_pending_raf_;
}
@@ -319,6 +317,7 @@ bool AnimationHost::TickAnimations(base::TimeTicks monotonic_time,
bool did_animate = false;
if (NeedsTickAnimations()) {
+ TRACE_EVENT_INSTANT0("cc", "NeedsTickAnimations", TRACE_EVENT_SCOPE_THREAD);
AnimationsList ticking_animations_copy = ticking_animations_;
for (auto& it : ticking_animations_copy)
it->Tick(monotonic_time);
@@ -654,7 +653,6 @@ size_t AnimationHost::CompositedAnimationsCount() const {
void AnimationHost::SetAnimationCounts(
size_t total_animations_count,
- size_t main_thread_compositable_animations_count,
bool current_frame_had_raf,
bool next_frame_has_pending_raf) {
// If an animation is being run on the compositor, it will have a ticking
@@ -669,14 +667,6 @@ void AnimationHost::SetAnimationCounts(
DCHECK_GE(main_thread_animations_count_, 0u);
SetNeedsPushProperties();
}
- if (main_thread_compositable_animations_count_ !=
- main_thread_compositable_animations_count) {
- main_thread_compositable_animations_count_ =
- main_thread_compositable_animations_count;
- SetNeedsPushProperties();
- }
- DCHECK_GE(main_thread_animations_count_,
- main_thread_compositable_animations_count_);
if (current_frame_had_raf != current_frame_had_raf_) {
current_frame_had_raf_ = current_frame_had_raf;
SetNeedsPushProperties();
@@ -691,10 +681,6 @@ size_t AnimationHost::MainThreadAnimationsCount() const {
return main_thread_animations_count_;
}
-size_t AnimationHost::MainThreadCompositableAnimationsCount() const {
- return main_thread_compositable_animations_count_;
-}
-
bool AnimationHost::CurrentFrameHadRAF() const {
return current_frame_had_raf_;
}
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
index 6a639b15e60..beae9903713 100644
--- a/chromium/cc/animation/animation_host.h
+++ b/chromium/cc/animation/animation_host.h
@@ -183,11 +183,9 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
- size_t MainThreadCompositableAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
bool NextFrameHasPendingRAF() const override;
void SetAnimationCounts(size_t total_animations_count,
- size_t main_thread_compositable_animations_count,
bool current_frame_had_raf,
bool next_frame_has_pending_raf);
@@ -229,7 +227,6 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
std::unique_ptr<LayerTreeMutator> mutator_;
size_t main_thread_animations_count_ = 0;
- size_t main_thread_compositable_animations_count_ = 0;
bool current_frame_had_raf_ = false;
bool next_frame_has_pending_raf_ = false;
diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc
index 95ab3acab26..9b01eda5754 100644
--- a/chromium/cc/animation/keyframe_effect.cc
+++ b/chromium/cc/animation/keyframe_effect.cc
@@ -104,8 +104,7 @@ void KeyframeEffect::DetachElement() {
element_id_ = ElementId();
}
-void KeyframeEffect::Tick(base::TimeTicks monotonic_time,
- const AnimationTimeProvider* tick_provider) {
+void KeyframeEffect::Tick(base::TimeTicks monotonic_time) {
DCHECK(has_bound_element_animations());
if (!element_animations_->has_element_in_any_list())
return;
@@ -113,12 +112,8 @@ void KeyframeEffect::Tick(base::TimeTicks monotonic_time,
if (needs_to_start_keyframe_models_)
StartKeyframeModels(monotonic_time);
- base::TimeTicks tick_time = monotonic_time;
for (auto& keyframe_model : keyframe_models_) {
- if (tick_provider)
- tick_time = tick_provider->GetTimeForKeyframeModel(*keyframe_model);
-
- TickKeyframeModel(tick_time, keyframe_model.get(),
+ TickKeyframeModel(monotonic_time, keyframe_model.get(),
element_animations_.get());
}
@@ -225,6 +220,19 @@ void KeyframeEffect::UpdateTickingState(UpdateTickingType type) {
}
}
+void KeyframeEffect::Pause(base::TimeDelta pause_offset) {
+ for (auto& keyframe_model : keyframe_models_) {
+ base::TimeTicks pause_time = keyframe_model->time_offset() +
+ keyframe_model->start_time() + pause_offset;
+ keyframe_model->SetRunState(KeyframeModel::PAUSED, pause_time);
+ }
+
+ if (has_bound_element_animations()) {
+ animation_->SetNeedsCommit();
+ SetNeedsPushProperties();
+ }
+}
+
void KeyframeEffect::AddKeyframeModel(
std::unique_ptr<KeyframeModel> keyframe_model) {
AnimationHost* animation_host = animation_->animation_host();
@@ -699,7 +707,7 @@ void KeyframeEffect::PushNewKeyframeModelsToImplThread(
KeyframeModel::RunState initial_run_state =
KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY;
std::unique_ptr<KeyframeModel> to_add(
- keyframe_model->CloneAndInitialize(initial_run_state));
+ keyframe_model->CreateImplInstance(initial_run_state));
DCHECK(!to_add->needs_synchronized_start_time());
to_add->set_affects_active_elements(false);
keyframe_effect_impl->AddKeyframeModel(std::move(to_add));
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index 8db169e783b..4ee5176e517 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -41,12 +41,6 @@ typedef size_t KeyframeEffectId;
// given target.
class CC_ANIMATION_EXPORT KeyframeEffect {
public:
- class AnimationTimeProvider {
- public:
- virtual base::TimeTicks GetTimeForKeyframeModel(
- const KeyframeModel&) const = 0;
- };
-
explicit KeyframeEffect(KeyframeEffectId id);
~KeyframeEffect();
@@ -87,8 +81,7 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
void AttachElement(ElementId element_id);
void DetachElement();
- void Tick(base::TimeTicks monotonic_time,
- const AnimationTimeProvider* tick_provider);
+ void Tick(base::TimeTicks monotonic_time);
static void TickKeyframeModel(base::TimeTicks monotonic_time,
KeyframeModel* keyframe_model,
AnimationTarget* target);
@@ -98,6 +91,8 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
void UpdateTickingState(UpdateTickingType type);
+ void Pause(base::TimeDelta pause_offset);
+
void AddKeyframeModel(std::unique_ptr<KeyframeModel> keyframe_model);
void PauseKeyframeModel(int keyframe_model_id, double time_offset);
void RemoveKeyframeModel(int keyframe_model_id);
diff --git a/chromium/cc/animation/keyframe_model.cc b/chromium/cc/animation/keyframe_model.cc
index 3597a967501..d8495a62ff1 100644
--- a/chromium/cc/animation/keyframe_model.cc
+++ b/chromium/cc/animation/keyframe_model.cc
@@ -54,6 +54,28 @@ std::unique_ptr<KeyframeModel> KeyframeModel::Create(
group_id, target_property_id));
}
+std::unique_ptr<KeyframeModel> KeyframeModel::CreateImplInstance(
+ RunState initial_run_state) const {
+ // Should never clone a model that is the controlling instance as it ends up
+ // creating multiple controlling instances.
+ DCHECK(!is_controlling_instance_);
+ std::unique_ptr<KeyframeModel> to_return(
+ new KeyframeModel(curve_->Clone(), id_, group_, target_property_id_));
+ to_return->run_state_ = initial_run_state;
+ to_return->iterations_ = iterations_;
+ to_return->iteration_start_ = iteration_start_;
+ to_return->start_time_ = start_time_;
+ to_return->pause_time_ = pause_time_;
+ to_return->total_paused_time_ = total_paused_time_;
+ to_return->time_offset_ = time_offset_;
+ to_return->direction_ = direction_;
+ to_return->playback_rate_ = playback_rate_;
+ to_return->fill_mode_ = fill_mode_;
+ DCHECK(!to_return->is_controlling_instance_);
+ to_return->is_controlling_instance_ = true;
+ return to_return;
+}
+
KeyframeModel::KeyframeModel(std::unique_ptr<AnimationCurve> curve,
int keyframe_model_id,
int group_id,
@@ -70,7 +92,6 @@ KeyframeModel::KeyframeModel(std::unique_ptr<AnimationCurve> curve,
fill_mode_(FillMode::BOTH),
needs_synchronized_start_time_(false),
received_finished_event_(false),
- suspended_(false),
is_controlling_instance_(false),
is_impl_only_(false),
affects_active_elements_(true),
@@ -83,9 +104,6 @@ KeyframeModel::~KeyframeModel() {
void KeyframeModel::SetRunState(RunState run_state,
base::TimeTicks monotonic_time) {
- if (suspended_)
- return;
-
char name_buffer[256];
base::snprintf(name_buffer, sizeof(name_buffer), "%s-%d-%d",
s_curveTypeNames[curve_->Type()], target_property_id_, group_);
@@ -122,16 +140,6 @@ void KeyframeModel::SetRunState(RunState run_state,
TRACE_STR_COPY(name_buffer), "State", TRACE_STR_COPY(state_buffer));
}
-void KeyframeModel::Suspend(base::TimeTicks monotonic_time) {
- SetRunState(PAUSED, monotonic_time);
- suspended_ = true;
-}
-
-void KeyframeModel::Resume(base::TimeTicks monotonic_time) {
- suspended_ = false;
- SetRunState(RUNNING, monotonic_time);
-}
-
bool KeyframeModel::IsFinishedAt(base::TimeTicks monotonic_time) const {
if (is_finished())
return true;
@@ -152,21 +160,6 @@ bool KeyframeModel::InEffect(base::TimeTicks monotonic_time) const {
(fill_mode_ == FillMode::BOTH || fill_mode_ == FillMode::BACKWARDS);
}
-base::TimeTicks KeyframeModel::ConvertFromActiveTime(
- base::TimeDelta active_time) const {
- // When waiting on receiving a start time, then our global clock is 'stuck' at
- // the initial state.
- if ((run_state_ == STARTING && !has_set_start_time()) ||
- needs_synchronized_start_time())
- return base::TimeTicks();
-
- // If we're paused, time is 'stuck' at the pause time.
- if (run_state_ == PAUSED)
- return pause_time_ - time_offset_;
-
- return active_time - time_offset_ + start_time_ + total_paused_time_;
-}
-
base::TimeDelta KeyframeModel::ConvertToActiveTime(
base::TimeTicks monotonic_time) const {
// If we're just starting or we're waiting on receiving a start time,
@@ -254,28 +247,6 @@ base::TimeDelta KeyframeModel::TrimTimeToCurrentIteration(
return iteration_time;
}
-std::unique_ptr<KeyframeModel> KeyframeModel::CloneAndInitialize(
- RunState initial_run_state) const {
- // Should never clone a model that is the controlling instance as it ends up
- // creating multiple controlling instances.
- DCHECK(!is_controlling_instance_);
- std::unique_ptr<KeyframeModel> to_return(
- new KeyframeModel(curve_->Clone(), id_, group_, target_property_id_));
- to_return->run_state_ = initial_run_state;
- to_return->iterations_ = iterations_;
- to_return->iteration_start_ = iteration_start_;
- to_return->start_time_ = start_time_;
- to_return->pause_time_ = pause_time_;
- to_return->total_paused_time_ = total_paused_time_;
- to_return->time_offset_ = time_offset_;
- to_return->direction_ = direction_;
- to_return->playback_rate_ = playback_rate_;
- to_return->fill_mode_ = fill_mode_;
- DCHECK(!to_return->is_controlling_instance_);
- to_return->is_controlling_instance_ = true;
- return to_return;
-}
-
void KeyframeModel::PushPropertiesTo(KeyframeModel* other) const {
// Currently, we only push changes due to pausing and resuming KeyframeModels
// on the main thread.
diff --git a/chromium/cc/animation/keyframe_model.h b/chromium/cc/animation/keyframe_model.h
index 517d8bed557..9d770995dd8 100644
--- a/chromium/cc/animation/keyframe_model.h
+++ b/chromium/cc/animation/keyframe_model.h
@@ -60,6 +60,9 @@ class CC_ANIMATION_EXPORT KeyframeModel {
int group_id,
int target_property_id);
+ std::unique_ptr<KeyframeModel> CreateImplInstance(
+ RunState initial_run_state) const;
+
virtual ~KeyframeModel();
int id() const { return id_; }
@@ -92,9 +95,6 @@ class CC_ANIMATION_EXPORT KeyframeModel {
time_offset_ = monotonic_time;
}
- void Suspend(base::TimeTicks monotonic_time);
- void Resume(base::TimeTicks monotonic_time);
-
Direction direction() { return direction_; }
void set_direction(Direction direction) { direction_ = direction; }
@@ -140,11 +140,6 @@ class CC_ANIMATION_EXPORT KeyframeModel {
base::TimeDelta TrimTimeToCurrentIteration(
base::TimeTicks monotonic_time) const;
- base::TimeTicks ConvertFromActiveTime(base::TimeDelta active_time) const;
-
- std::unique_ptr<KeyframeModel> CloneAndInitialize(
- RunState initial_run_state) const;
-
void set_is_controlling_instance_for_test(bool is_controlling_instance) {
is_controlling_instance_ = is_controlling_instance;
}
@@ -204,11 +199,6 @@ class CC_ANIMATION_EXPORT KeyframeModel {
bool needs_synchronized_start_time_;
bool received_finished_event_;
- // When a keyframe model is suspended, it behaves as if it is paused and it
- // also ignores all run state changes until it is resumed. This is used for
- // testing purposes.
- bool suspended_;
-
// These are used in TrimTimeToCurrentIteration to account for time
// spent while paused. This is not included in AnimationState since it
// there is absolutely no need for clients of this controller to know
diff --git a/chromium/cc/animation/keyframe_model_unittest.cc b/chromium/cc/animation/keyframe_model_unittest.cc
index ac13921648b..3757df9ee9f 100644
--- a/chromium/cc/animation/keyframe_model_unittest.cc
+++ b/chromium/cc/animation/keyframe_model_unittest.cc
@@ -488,51 +488,6 @@ TEST(KeyframeModelTest, TrimTimePauseResumeReverse) {
.InSecondsF());
}
-TEST(KeyframeModelTest, TrimTimeSuspendResume) {
- std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
- keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
- EXPECT_EQ(0,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
- .InSecondsF());
- EXPECT_EQ(0.5,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
- .InSecondsF());
- keyframe_model->Suspend(TicksFromSecondsF(0.5));
- EXPECT_EQ(
- 0.5, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
- .InSecondsF());
- keyframe_model->Resume(TicksFromSecondsF(1024));
- EXPECT_EQ(
- 0.5, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
- .InSecondsF());
- EXPECT_EQ(
- 1, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.5))
- .InSecondsF());
-}
-
-TEST(KeyframeModelTest, TrimTimeSuspendResumeReverse) {
- std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
- keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
- EXPECT_EQ(1.0,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
- .InSecondsF());
- EXPECT_EQ(0.75,
- keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
- .InSecondsF());
- keyframe_model->Suspend(TicksFromSecondsF(0.75));
- EXPECT_EQ(0.25, keyframe_model
- ->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
- .InSecondsF());
- keyframe_model->Resume(TicksFromSecondsF(1024));
- EXPECT_EQ(0.25, keyframe_model
- ->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.0))
- .InSecondsF());
- EXPECT_EQ(
- 0, keyframe_model->TrimTimeToCurrentIteration(TicksFromSecondsF(1024.25))
- .InSecondsF());
-}
-
TEST(KeyframeModelTest, TrimTimeZeroDuration) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(0, 0));
keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
@@ -716,17 +671,6 @@ TEST(KeyframeModelTest, IsFinishedNeedsSynchronizedStartTime) {
EXPECT_TRUE(keyframe_model->is_finished());
}
-TEST(KeyframeModelTest, RunStateChangesIgnoredWhileSuspended) {
- std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1));
- keyframe_model->Suspend(TicksFromSecondsF(0));
- EXPECT_EQ(KeyframeModel::PAUSED, keyframe_model->run_state());
- keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
- EXPECT_EQ(KeyframeModel::PAUSED, keyframe_model->run_state());
- keyframe_model->Resume(TicksFromSecondsF(0));
- keyframe_model->SetRunState(KeyframeModel::RUNNING, TicksFromSecondsF(0.0));
- EXPECT_EQ(KeyframeModel::RUNNING, keyframe_model->run_state());
-}
-
TEST(KeyframeModelTest, TrimTimePlaybackNormal) {
std::unique_ptr<KeyframeModel> keyframe_model(CreateKeyframeModel(1, 1, 1));
EXPECT_EQ(0,
diff --git a/chromium/cc/animation/keyframed_animation_curve.cc b/chromium/cc/animation/keyframed_animation_curve.cc
index 89f088a8dc4..ed44328d053 100644
--- a/chromium/cc/animation/keyframed_animation_curve.cc
+++ b/chromium/cc/animation/keyframed_animation_curve.cc
@@ -381,28 +381,6 @@ TransformOperations KeyframedTransformAnimationCurve::GetValue(
return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
}
-bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
- const gfx::BoxF& box,
- gfx::BoxF* bounds) const {
- DCHECK_GE(keyframes_.size(), 2ul);
- *bounds = gfx::BoxF();
- for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
- gfx::BoxF bounds_for_step;
- float min_progress = 0.0;
- float max_progress = 1.0;
- if (keyframes_[i]->timing_function())
- keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
- if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
- keyframes_[i]->Value(),
- min_progress,
- max_progress,
- &bounds_for_step))
- return false;
- bounds->Union(bounds_for_step);
- }
- return true;
-}
-
bool KeyframedTransformAnimationCurve::PreservesAxisAlignment() const {
for (const auto& keyframe : keyframes_) {
if (!keyframe->Value().PreservesAxisAlignment())
diff --git a/chromium/cc/animation/keyframed_animation_curve.h b/chromium/cc/animation/keyframed_animation_curve.h
index 037805603d1..582a26c2f6c 100644
--- a/chromium/cc/animation/keyframed_animation_curve.h
+++ b/chromium/cc/animation/keyframed_animation_curve.h
@@ -238,8 +238,6 @@ class CC_ANIMATION_EXPORT KeyframedTransformAnimationCurve
// TransformAnimationCurve implementation
TransformOperations GetValue(base::TimeDelta t) const override;
- bool AnimatedBoundsForBox(const gfx::BoxF& box,
- gfx::BoxF* bounds) const override;
bool PreservesAxisAlignment() const override;
bool IsTranslation() const override;
bool AnimationStartScale(bool forward_direction,
diff --git a/chromium/cc/animation/keyframed_animation_curve_unittest.cc b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
index 7a13c743e4e..b71f127780f 100644
--- a/chromium/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
@@ -658,32 +658,6 @@ TEST(KeyframedAnimationCurveTest, FramesTimingFunction) {
}
}
-// Tests that animated bounds are computed as expected.
-TEST(KeyframedAnimationCurveTest, AnimatedBounds) {
- std::unique_ptr<KeyframedTransformAnimationCurve> curve(
- KeyframedTransformAnimationCurve::Create());
-
- TransformOperations operations1;
- curve->AddKeyframe(
- TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
- operations1.AppendTranslate(2.0, 3.0, -1.0);
- curve->AddKeyframe(TransformKeyframe::Create(
- base::TimeDelta::FromSecondsD(0.5f), operations1, nullptr));
- TransformOperations operations2;
- operations2.AppendTranslate(4.0, 1.0, 2.0);
- curve->AddKeyframe(TransformKeyframe::Create(
- base::TimeDelta::FromSecondsD(1.f), operations2,
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE)));
-
- gfx::BoxF box(2.f, 3.f, 4.f, 1.f, 3.f, 2.f);
- gfx::BoxF bounds;
-
- EXPECT_TRUE(curve->AnimatedBoundsForBox(box, &bounds));
- EXPECT_EQ(gfx::BoxF(2.f, 3.f, 3.f, 5.f, 6.f, 5.f).ToString(),
- bounds.ToString());
-}
-
// Tests that animations that are translations are correctly identified.
TEST(KeyframedAnimationCurveTest, IsTranslation) {
std::unique_ptr<KeyframedTransformAnimationCurve> curve(
diff --git a/chromium/cc/animation/timing_function.cc b/chromium/cc/animation/timing_function.cc
index e3df8deb03a..ad73588c6e4 100644
--- a/chromium/cc/animation/timing_function.cc
+++ b/chromium/cc/animation/timing_function.cc
@@ -65,11 +65,6 @@ float CubicBezierTimingFunction::Velocity(double x) const {
return static_cast<float>(bezier_.Slope(x));
}
-void CubicBezierTimingFunction::Range(float* min, float* max) const {
- *min = static_cast<float>(bezier_.range_min());
- *max = static_cast<float>(bezier_.range_max());
-}
-
std::unique_ptr<TimingFunction> CubicBezierTimingFunction::Clone() const {
return base::WrapUnique(new CubicBezierTimingFunction(*this));
}
@@ -97,11 +92,6 @@ std::unique_ptr<TimingFunction> StepsTimingFunction::Clone() const {
return base::WrapUnique(new StepsTimingFunction(*this));
}
-void StepsTimingFunction::Range(float* min, float* max) const {
- *min = 0.0f;
- *max = 1.0f;
-}
-
float StepsTimingFunction::Velocity(double x) const {
return 0.0f;
}
@@ -150,11 +140,6 @@ std::unique_ptr<TimingFunction> FramesTimingFunction::Clone() const {
return base::WrapUnique(new FramesTimingFunction(*this));
}
-void FramesTimingFunction::Range(float* min, float* max) const {
- *min = 0.0f;
- *max = 1.0f;
-}
-
float FramesTimingFunction::Velocity(double x) const {
return 0.0f;
}
diff --git a/chromium/cc/animation/timing_function.h b/chromium/cc/animation/timing_function.h
index 5ff8d3561bd..32bbf95fe56 100644
--- a/chromium/cc/animation/timing_function.h
+++ b/chromium/cc/animation/timing_function.h
@@ -24,8 +24,6 @@ class CC_ANIMATION_EXPORT TimingFunction {
virtual Type GetType() const = 0;
virtual float GetValue(double t) const = 0;
virtual float Velocity(double time) const = 0;
- // The smallest and largest values returned by GetValue for inputs in [0, 1].
- virtual void Range(float* min, float* max) const = 0;
virtual std::unique_ptr<TimingFunction> Clone() const = 0;
protected:
@@ -50,7 +48,6 @@ class CC_ANIMATION_EXPORT CubicBezierTimingFunction : public TimingFunction {
Type GetType() const override;
float GetValue(double time) const override;
float Velocity(double time) const override;
- void Range(float* min, float* max) const override;
std::unique_ptr<TimingFunction> Clone() const override;
EaseType ease_type() const { return ease_type_; }
@@ -83,7 +80,6 @@ class CC_ANIMATION_EXPORT StepsTimingFunction : public TimingFunction {
Type GetType() const override;
float GetValue(double t) const override;
std::unique_ptr<TimingFunction> Clone() const override;
- void Range(float* min, float* max) const override;
float Velocity(double time) const override;
int steps() const { return steps_; }
@@ -110,7 +106,6 @@ class CC_ANIMATION_EXPORT FramesTimingFunction : public TimingFunction {
Type GetType() const override;
float GetValue(double t) const override;
std::unique_ptr<TimingFunction> Clone() const override;
- void Range(float* min, float* max) const override;
float Velocity(double time) const override;
int frames() const { return frames_; }
diff --git a/chromium/cc/animation/worklet_animation.cc b/chromium/cc/animation/worklet_animation.cc
index 5db8231c413..a905b94ce12 100644
--- a/chromium/cc/animation/worklet_animation.cc
+++ b/chromium/cc/animation/worklet_animation.cc
@@ -11,11 +11,13 @@ namespace cc {
WorkletAnimation::WorkletAnimation(
int id,
const std::string& name,
- std::unique_ptr<ScrollTimeline> scroll_timeline)
+ std::unique_ptr<ScrollTimeline> scroll_timeline,
+ bool is_controlling_instance)
: SingleKeyframeEffectAnimation(id),
name_(name),
scroll_timeline_(std::move(scroll_timeline)),
- last_current_time_(base::nullopt) {}
+ last_current_time_(base::nullopt),
+ is_impl_instance_(is_controlling_instance) {}
WorkletAnimation::~WorkletAnimation() = default;
@@ -24,7 +26,7 @@ scoped_refptr<WorkletAnimation> WorkletAnimation::Create(
const std::string& name,
std::unique_ptr<ScrollTimeline> scroll_timeline) {
return WrapRefCounted(
- new WorkletAnimation(id, name, std::move(scroll_timeline)));
+ new WorkletAnimation(id, name, std::move(scroll_timeline), false));
}
scoped_refptr<Animation> WorkletAnimation::CreateImplInstance() const {
@@ -33,7 +35,7 @@ scoped_refptr<Animation> WorkletAnimation::CreateImplInstance() const {
impl_timeline = scroll_timeline_->CreateImplInstance();
return WrapRefCounted(
- new WorkletAnimation(id(), name(), std::move(impl_timeline)));
+ new WorkletAnimation(id(), name(), std::move(impl_timeline), true));
}
void WorkletAnimation::SetLocalTime(base::TimeDelta local_time) {
@@ -42,7 +44,17 @@ void WorkletAnimation::SetLocalTime(base::TimeDelta local_time) {
}
void WorkletAnimation::Tick(base::TimeTicks monotonic_time) {
- keyframe_effect()->Tick(monotonic_time, this);
+ // Do not tick worklet animations on main thread. This should be removed if we
+ // skip ticking all animations on main thread in http://crbug.com/762717.
+ if (!is_impl_instance_)
+ return;
+ // As the output of a WorkletAnimation is driven by a script-provided local
+ // time, we don't want the underlying effect to participate in the normal
+ // animations lifecycle. To avoid this we pause the underlying keyframe effect
+ // at the local time obtained from the user script - essentially turning each
+ // call to |WorkletAnimation::Tick| into a seek in the effect.
+ keyframe_effect()->Pause(local_time_);
+ keyframe_effect()->Tick(monotonic_time);
}
// TODO(crbug.com/780151): The current time returned should be an offset against
@@ -66,18 +78,6 @@ bool WorkletAnimation::NeedsUpdate(base::TimeTicks monotonic_time,
return needs_update;
}
-base::TimeTicks WorkletAnimation::GetTimeForKeyframeModel(
- const KeyframeModel& keyframe_model) const {
- // Animation local time is equivalent to animation active time. So we have to
- // convert it from active time to monotonic time.
- return keyframe_model.ConvertFromActiveTime(local_time_);
-}
-
-void WorkletAnimation::PushPropertiesTo(Animation* animation_impl) {
- SingleKeyframeEffectAnimation::PushPropertiesTo(animation_impl);
- static_cast<WorkletAnimation*>(animation_impl)->SetLocalTime(local_time_);
-}
-
bool WorkletAnimation::IsWorkletAnimation() const {
return true;
}
diff --git a/chromium/cc/animation/worklet_animation.h b/chromium/cc/animation/worklet_animation.h
index 27371100efc..cdde572fd28 100644
--- a/chromium/cc/animation/worklet_animation.h
+++ b/chromium/cc/animation/worklet_animation.h
@@ -19,12 +19,12 @@ class ScrollTimeline;
// timing to be controlled by an animator instance that is running in a
// AnimationWorkletGlobalScope.
class CC_ANIMATION_EXPORT WorkletAnimation final
- : public SingleKeyframeEffectAnimation,
- KeyframeEffect::AnimationTimeProvider {
+ : public SingleKeyframeEffectAnimation {
public:
WorkletAnimation(int id,
const std::string& name,
- std::unique_ptr<ScrollTimeline> scroll_timeline);
+ std::unique_ptr<ScrollTimeline> scroll_timeline,
+ bool is_controlling_instance);
static scoped_refptr<WorkletAnimation> Create(
int id,
const std::string& name,
@@ -51,12 +51,6 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
bool NeedsUpdate(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree);
- // KeyframeEffect::AnimationTimeProvider:
- base::TimeTicks GetTimeForKeyframeModel(
- const KeyframeModel& keyframe_model) const override;
-
- void PushPropertiesTo(Animation* animation_impl) override;
-
private:
~WorkletAnimation() override;
@@ -73,6 +67,8 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
base::TimeDelta local_time_;
base::Optional<double> last_current_time_;
+
+ bool is_impl_instance_;
};
} // namespace cc
diff --git a/chromium/cc/animation/worklet_animation_player_unittest.cc b/chromium/cc/animation/worklet_animation_player_unittest.cc
deleted file mode 100644
index d77e0a7bb5d..00000000000
--- a/chromium/cc/animation/worklet_animation_player_unittest.cc
+++ /dev/null
@@ -1,135 +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/animation/worklet_animation_player.h"
-
-#include "cc/animation/scroll_timeline.h"
-#include "cc/test/animation_test_common.h"
-#include "cc/test/animation_timelines_test_common.h"
-#include "cc/test/mock_layer_tree_mutator.h"
-#include "cc/trees/property_tree.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using ::testing::Mock;
-using ::testing::Return;
-using ::testing::_;
-
-namespace cc {
-
-namespace {
-
-class WorkletAnimationPlayerTest : public AnimationTimelinesTest {
- public:
- WorkletAnimationPlayerTest() = default;
- ~WorkletAnimationPlayerTest() override = default;
-
- int worklet_player_id_ = 11;
-};
-
-class MockScrollTimeline : public ScrollTimeline {
- public:
- MockScrollTimeline()
- : ScrollTimeline(ElementId(), ScrollTimeline::Vertical, 0) {}
- MOCK_CONST_METHOD1(CurrentTime, double(const ScrollTree&));
-};
-
-TEST_F(WorkletAnimationPlayerTest, LocalTimeIsUsedWithAnimations) {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
-
- const float start_opacity = .7f;
- const float end_opacity = .3f;
- const double duration = 1.;
-
- const float expected_opacity =
- start_opacity + (end_opacity - start_opacity) / 2;
-
- scoped_refptr<WorkletAnimationPlayer> worklet_player_ =
- WorkletAnimationPlayer::Create(worklet_player_id_, "test_name", nullptr);
-
- worklet_player_->AttachElement(element_id_);
- host_->AddAnimationTimeline(timeline_);
- timeline_->AttachPlayer(worklet_player_);
-
- AddOpacityTransitionToPlayer(worklet_player_.get(), duration, start_opacity,
- end_opacity, true);
-
- host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
-
- // TODO(majidvp): At the moment the player does not use the local time when
- // it is starting. This is because KeyframeModel::ConvertToActiveTime always
- // returns the time_offset when starting. We need to change this.
- base::TimeTicks time;
- time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 1u);
-
- base::TimeDelta local_time = base::TimeDelta::FromSecondsD(duration / 2);
- worklet_player_->SetLocalTime(local_time);
-
- host_->PushPropertiesTo(host_impl_);
-
- TickAnimationsTransferEvents(time, 0u);
-
- client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
- expected_opacity);
-
- client_impl_.ExpectOpacityPropertyMutated(
- element_id_, ElementListType::ACTIVE, expected_opacity);
-}
-
-// Tests that verify interaction of AnimationHost with LayerTreeMutator.
-// TODO(majidvp): Perhaps moves these to AnimationHostTest.
-TEST_F(WorkletAnimationPlayerTest,
- LayerTreeMutatorsIsMutatedWithCorrectInputState) {
- MockLayerTreeMutator* mock_mutator = new MockLayerTreeMutator();
- host_impl_->SetLayerTreeMutator(
- base::WrapUnique<LayerTreeMutator>(mock_mutator));
-
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
-
- const float start_opacity = .7f;
- const float end_opacity = .3f;
- const double duration = 1.;
-
- scoped_refptr<WorkletAnimationPlayer> worklet_player_ =
- WorkletAnimationPlayer::Create(worklet_player_id_, "test_name", nullptr);
-
- worklet_player_->AttachElement(element_id_);
- host_->AddAnimationTimeline(timeline_);
- timeline_->AttachPlayer(worklet_player_);
-
- AddOpacityTransitionToPlayer(worklet_player_.get(), duration, start_opacity,
- end_opacity, true);
-
- host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
-
- EXPECT_CALL(*mock_mutator, MutateRef(_));
-
- base::TimeTicks time;
- time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 1u);
-
- Mock::VerifyAndClearExpectations(mock_mutator);
-}
-
-TEST_F(WorkletAnimationPlayerTest, CurrentTimeCorrectlyUsesScrolltimeline) {
- auto scroll_timeline = std::make_unique<MockScrollTimeline>();
- EXPECT_CALL(*scroll_timeline, CurrentTime(_)).WillOnce(Return(1234));
- scoped_refptr<WorkletAnimationPlayer> worklet_player =
- WorkletAnimationPlayer::Create(worklet_player_id_, "test_name",
- std::move(scroll_timeline));
-
- ScrollTree scroll_tree;
- EXPECT_EQ(1234,
- worklet_player->CurrentTime(base::TimeTicks::Now(), scroll_tree));
-}
-
-} // namespace
-
-} // namespace cc
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index ef89d6fb11f..5e3020b75e9 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -36,9 +36,15 @@ class WorkletAnimationTest : public AnimationTimelinesTest {
worklet_animation_->AttachElement(element_id_);
host_->AddAnimationTimeline(timeline_);
timeline_->AttachAnimation(worklet_animation_);
+
+ host_->PushPropertiesTo(host_impl_);
+ timeline_impl_ = host_impl_->GetTimelineById(timeline_id_);
+ worklet_animation_impl_ = static_cast<WorkletAnimation*>(
+ timeline_impl_->GetAnimationById(worklet_animation_id_));
}
scoped_refptr<WorkletAnimation> worklet_animation_;
+ scoped_refptr<WorkletAnimation> worklet_animation_impl_;
int worklet_animation_id_ = 11;
};
@@ -61,26 +67,18 @@ TEST_F(WorkletAnimationTest, LocalTimeIsUsedWithAnimations) {
AddOpacityTransitionToAnimation(worklet_animation_.get(), duration,
start_opacity, end_opacity, true);
+ // Push the opacity animation to the impl thread.
host_->PushPropertiesTo(host_impl_);
host_impl_->ActivateAnimations();
- // TODO(majidvp): At the moment the animation does not use the local time when
- // it is starting. This is because KeyframeModel::ConvertToActiveTime always
- // returns the time_offset when starting. We need to change this.
- base::TimeTicks time;
- time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 1u);
-
base::TimeDelta local_time = base::TimeDelta::FromSecondsD(duration / 2);
- worklet_animation_->SetLocalTime(local_time);
-
- host_->PushPropertiesTo(host_impl_);
-
- TickAnimationsTransferEvents(time, 0u);
+ worklet_animation_impl_->SetLocalTime(local_time);
- client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
- expected_opacity);
+ TickAnimationsTransferEvents(base::TimeTicks(), 0u);
+ TestLayer* layer =
+ client_.FindTestLayer(element_id_, ElementListType::ACTIVE);
+ EXPECT_FALSE(layer->is_property_mutated(TargetProperty::OPACITY));
client_impl_.ExpectOpacityPropertyMutated(
element_id_, ElementListType::ACTIVE, expected_opacity);
}
@@ -109,7 +107,7 @@ TEST_F(WorkletAnimationTest, LayerTreeMutatorsIsMutatedWithCorrectInputState) {
base::TimeTicks time;
time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 1u);
+ TickAnimationsTransferEvents(time, 0u);
Mock::VerifyAndClearExpectations(mock_mutator);
}
@@ -136,7 +134,7 @@ TEST_F(WorkletAnimationTest, LayerTreeMutatorsIsMutatedOnlyWhenInputChanges) {
base::TimeTicks time;
time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 1u);
+ TickAnimationsTransferEvents(time, 0u);
// The time has not changed which means worklet animation input is the same.
// Ticking animations again should not result in mutator being asked to
diff --git a/chromium/cc/base/list_container.h b/chromium/cc/base/list_container.h
index bafee7970ce..81235e1bc0a 100644
--- a/chromium/cc/base/list_container.h
+++ b/chromium/cc/base/list_container.h
@@ -146,22 +146,6 @@ class ListContainer {
helper_.data_.swap(other.helper_.data_);
}
- // Appends a new item without copying. The original item will not be
- // destructed and will be replaced with a new DerivedElementType. The
- // DerivedElementType does not have to match the moved type as a full block
- // of memory will be moved (up to MaxSizeForDerivedClass()). A pointer to
- // the moved element is returned.
- template <typename DerivedElementType>
- DerivedElementType* AppendByMoving(DerivedElementType* item) {
- size_t max_size_for_derived_class = helper_.MaxSizeForDerivedClass();
- void* new_item = helper_.Allocate(alignof(DerivedElementType),
- max_size_for_derived_class);
- memcpy(new_item, static_cast<void*>(item), max_size_for_derived_class);
- // Construct a new element in-place so it can be destructed safely.
- new (item) DerivedElementType;
- return static_cast<DerivedElementType*>(new_item);
- }
-
size_t size() const { return helper_.size(); }
bool empty() const { return helper_.empty(); }
size_t GetCapacityInBytes() const { return helper_.GetCapacityInBytes(); }
diff --git a/chromium/cc/base/list_container_unittest.cc b/chromium/cc/base/list_container_unittest.cc
index f0c5a24849f..e46be3bf875 100644
--- a/chromium/cc/base/list_container_unittest.cc
+++ b/chromium/cc/base/list_container_unittest.cc
@@ -8,7 +8,6 @@
#include <algorithm>
#include <vector>
-#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -103,6 +102,7 @@ class SimpleDerivedElementConstructMagicNumberOne
SimpleDerivedElementConstructMagicNumberOne() {
set_value(kMagicNumberToUseForSimpleDerivedElementOne);
}
+ ~SimpleDerivedElementConstructMagicNumberOne() override = default;
};
class SimpleDerivedElementConstructMagicNumberTwo
@@ -111,6 +111,7 @@ class SimpleDerivedElementConstructMagicNumberTwo
SimpleDerivedElementConstructMagicNumberTwo() {
set_value(kMagicNumberToUseForSimpleDerivedElementTwo);
}
+ ~SimpleDerivedElementConstructMagicNumberTwo() override = default;
};
class SimpleDerivedElementConstructMagicNumberThree
@@ -119,12 +120,40 @@ class SimpleDerivedElementConstructMagicNumberThree
SimpleDerivedElementConstructMagicNumberThree() {
set_value(kMagicNumberToUseForSimpleDerivedElementThree);
}
+ ~SimpleDerivedElementConstructMagicNumberThree() override = default;
};
+// This class' instances are moved by ListContainer via memcpy(). This behavior
+// is not supported by gmock's FunctionMocker, so this class must roll its own
+// mocking code.
class MockDerivedElement : public SimpleDerivedElementConstructMagicNumberOne {
public:
- ~MockDerivedElement() override { Destruct(); }
- MOCK_METHOD0(Destruct, void());
+ ~MockDerivedElement() override {
+ DestructorCalled();
+ CheckDestructExpectation();
+ }
+
+ void SetExpectedDestructorCalls(size_t expected_calls) {
+ expected_destructor_calls_ = expected_calls;
+ has_expected_destructor_calls_ = true;
+ }
+
+ private:
+ void DestructorCalled() { ++destructor_calls_; }
+
+ void CheckDestructExpectation() {
+ if (!has_expected_destructor_calls_)
+ return;
+ EXPECT_EQ(expected_destructor_calls_, destructor_calls_)
+ << "element destructor called the wrong number of times";
+ }
+
+ // Not using base::Optional<size_t> here in order to get a precise destructor
+ // behavior. The tests below need the ability to catch multiple destructor
+ // calls, and base::Optional's destructor might make has_value() return false.
+ size_t expected_destructor_calls_;
+ bool has_expected_destructor_calls_ = false;
+ size_t destructor_calls_ = 0;
};
class MockDerivedElementSubclass : public MockDerivedElement {
@@ -164,7 +193,7 @@ TEST(ListContainerTest, DestructorCalled) {
size_t size = 1;
MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>();
- EXPECT_CALL(*de_1, Destruct());
+ de_1->SetExpectedDestructorCalls(1);
EXPECT_EQ(size, list.size());
EXPECT_EQ(de_1, list.front());
}
@@ -178,18 +207,10 @@ TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
EXPECT_EQ(size, list.size());
EXPECT_EQ(de_1, list.front());
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*de_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*de_1, Destruct()).Times(0);
- }
+ // Make sure destructor is called exactly once during clear.
+ de_1->SetExpectedDestructorCalls(1);
list.clear();
- separator.Call();
}
TEST(ListContainerTest, ClearDoesNotMalloc) {
@@ -235,21 +256,12 @@ TEST(ListContainerTest, ReplaceExistingElement) {
EXPECT_EQ(size, list.size());
EXPECT_EQ(de_1, list.front());
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*de_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*de_1, Destruct()).Times(0);
- }
+ // Make sure destructor is called exactly once during clear.
+ de_1->SetExpectedDestructorCalls(1);
list.ReplaceExistingElement<MockDerivedElementSubclass>(list.begin());
EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo, de_1->get_value());
- separator.Call();
- EXPECT_CALL(*de_1, Destruct());
list.clear();
}
@@ -262,18 +274,10 @@ TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
EXPECT_EQ(size, list.size());
EXPECT_EQ(de_1, list.front());
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*de_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*de_1, Destruct()).Times(0);
- }
+ // Make sure destructor is called exactly once during clear.
+ de_1->SetExpectedDestructorCalls(1);
list.EraseAndInvalidateAllPointers(list.begin());
- separator.Call();
}
TEST(ListContainerTest, SimpleIndexAccessNonDerivedElement) {
@@ -1021,158 +1025,6 @@ TEST(ListContainerTest, RemoveLastIteration) {
check_equal(); // Empty.
}
-TEST(ListContainerTest, AppendByMovingSameList) {
- ListContainer<SimpleDerivedElement> list(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
- list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
-
- list.AppendByMoving(list.front());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list.back()->get_value());
- EXPECT_EQ(2u, list.size());
-
- list.front()->set_value(kMagicNumberToUseForSimpleDerivedElementTwo);
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
- list.front()->get_value());
- list.AppendByMoving(list.front());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
- list.back()->get_value());
- EXPECT_EQ(3u, list.size());
-}
-
-TEST(ListContainerTest, AppendByMovingDoesNotDestruct) {
- ListContainer<DerivedElement> list_1(kCurrentLargestDerivedElementAlign,
- kCurrentLargestDerivedElementSize, 0);
- ListContainer<DerivedElement> list_2(kCurrentLargestDerivedElementAlign,
- kCurrentLargestDerivedElementSize, 0);
- MockDerivedElement* mde_1 = list_1.AllocateAndConstruct<MockDerivedElement>();
-
- // Make sure destructor isn't called during AppendByMoving.
- list_2.AppendByMoving(mde_1);
- EXPECT_CALL(*mde_1, Destruct()).Times(0);
- testing::Mock::VerifyAndClearExpectations(mde_1);
- mde_1 = static_cast<MockDerivedElement*>(list_2.back());
- EXPECT_CALL(*mde_1, Destruct());
-}
-
-TEST(ListContainerTest, AppendByMovingReturnsMovedPointer) {
- ListContainer<SimpleDerivedElement> list_1(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
- ListContainer<SimpleDerivedElement> list_2(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
- SimpleDerivedElement* simple_element =
- list_1.AllocateAndConstruct<SimpleDerivedElement>();
-
- SimpleDerivedElement* moved_1 = list_2.AppendByMoving(simple_element);
- EXPECT_EQ(list_2.back(), moved_1);
-
- SimpleDerivedElement* moved_2 = list_1.AppendByMoving(moved_1);
- EXPECT_EQ(list_1.back(), moved_2);
- EXPECT_NE(moved_1, moved_2);
-}
-
-TEST(ListContainerTest, AppendByMovingReplacesSourceWithNewDerivedElement) {
- ListContainer<SimpleDerivedElementConstructMagicNumberOne> list_1(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
- ListContainer<SimpleDerivedElementConstructMagicNumberTwo> list_2(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
-
- list_1.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list_1.front()->get_value());
-
- list_2.AppendByMoving(list_1.front());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list_1.front()->get_value());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list_2.front()->get_value());
-
- // Change the value of list_2.front() to ensure the value is actually moved.
- list_2.back()->set_value(kMagicNumberToUseForSimpleDerivedElementThree);
-
- list_1.AppendByMoving(list_2.back());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list_1.front()->get_value());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree,
- list_1.back()->get_value());
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
- list_2.back()->get_value());
-
- // AppendByMoving replaces the source element with a new derived element so
- // we do not expect sizes to shrink after AppendByMoving is called.
- EXPECT_EQ(2u, list_1.size()); // One direct allocation, one AppendByMoving.
- EXPECT_EQ(1u, list_2.size()); // One AppendByMoving.
-}
-
-const size_t kLongCountForLongSimpleDerivedElement = 5;
-
-class LongSimpleDerivedElement : public SimpleDerivedElement {
- public:
- ~LongSimpleDerivedElement() override = default;
- void SetAllValues(unsigned long value) {
- for (size_t i = 0; i < kLongCountForLongSimpleDerivedElement; i++)
- values[i] = value;
- }
- bool AreAllValuesEqualTo(size_t value) const {
- for (size_t i = 1; i < kLongCountForLongSimpleDerivedElement; i++) {
- if (values[i] != values[0])
- return false;
- }
- return true;
- }
-
- private:
- unsigned long values[kLongCountForLongSimpleDerivedElement];
-};
-
-const unsigned long kMagicNumberToUseForLongSimpleDerivedElement = 2718ul;
-
-class LongSimpleDerivedElementConstructMagicNumber
- : public LongSimpleDerivedElement {
- public:
- LongSimpleDerivedElementConstructMagicNumber() {
- SetAllValues(kMagicNumberToUseForLongSimpleDerivedElement);
- }
-};
-
-TEST(ListContainerTest, AppendByMovingLongAndSimpleDerivedElements) {
- static_assert(sizeof(LongSimpleDerivedElement) > sizeof(SimpleDerivedElement),
- "LongSimpleDerivedElement should be larger than "
- "SimpleDerivedElement's size.");
- static_assert(sizeof(LongSimpleDerivedElement) <= kLargestDerivedElementSize,
- "LongSimpleDerivedElement should be smaller than the maximum "
- "DerivedElement size.");
-
- ListContainer<SimpleDerivedElement> list(
- kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
- list.AllocateAndConstruct<LongSimpleDerivedElementConstructMagicNumber>();
- list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
-
- EXPECT_TRUE(
- static_cast<LongSimpleDerivedElement*>(list.front())
- ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement));
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list.back()->get_value());
-
- // Test that moving a simple derived element actually moves enough data so
- // that the LongSimpleDerivedElement at this location is entirely moved.
- SimpleDerivedElement* simple_element = list.back();
- list.AppendByMoving(list.front());
- EXPECT_TRUE(
- static_cast<LongSimpleDerivedElement*>(list.back())
- ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement));
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- simple_element->get_value());
-
- LongSimpleDerivedElement* long_element =
- static_cast<LongSimpleDerivedElement*>(list.back());
- list.AppendByMoving(simple_element);
- EXPECT_TRUE(long_element->AreAllValuesEqualTo(
- kMagicNumberToUseForLongSimpleDerivedElement));
- EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
- list.back()->get_value());
-}
-
TEST(ListContainerTest, Swap) {
ListContainer<SimpleDerivedElement> list_1(
kCurrentLargestDerivedElementAlign, kCurrentLargestDerivedElementSize, 0);
diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc
index b3688f98a20..8b70bc435c2 100644
--- a/chromium/cc/base/switches.cc
+++ b/chromium/cc/base/switches.cc
@@ -24,10 +24,8 @@ const char kDisableMainFrameBeforeActivation[] =
const char kEnableMainFrameBeforeActivation[] =
"enable-main-frame-before-activation";
-// Enables defering image decodes to the image decode service.
-const char kEnableCheckerImaging[] = "enable-checker-imaging";
-
-// Disabled defering image decodes to the image decode service.
+// Disabled defering all image decodes to the image decode service, ignoring
+// DecodingMode preferences specified on PaintImage.
const char kDisableCheckerImaging[] = "disable-checker-imaging";
// Percentage of the browser controls need to be hidden before they will auto
@@ -43,9 +41,6 @@ const char kBrowserControlsShowThreshold[] = "top-controls-show-threshold";
// complete, such as --slow-down-raster-scale-factor=25.
const char kSlowDownRasterScaleFactor[] = "slow-down-raster-scale-factor";
-// Compress tile textures for GPUs supporting it.
-const char kEnableTileCompression[] = "enable-tile-compression";
-
// Checks damage early and aborts the frame if no damage, so that clients like
// Android WebView don't invalidate unnecessarily.
const char kCheckDamageEarly[] = "check-damage-early";
diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h
index adbea566bed..7234ee4024c 100644
--- a/chromium/cc/base/switches.h
+++ b/chromium/cc/base/switches.h
@@ -20,13 +20,11 @@ CC_BASE_EXPORT extern const char kDisableThreadedAnimation[];
CC_BASE_EXPORT extern const char kDisableCompositedAntialiasing[];
CC_BASE_EXPORT extern const char kDisableMainFrameBeforeActivation[];
CC_BASE_EXPORT extern const char kEnableMainFrameBeforeActivation[];
-CC_BASE_EXPORT extern const char kEnableCheckerImaging[];
CC_BASE_EXPORT extern const char kDisableCheckerImaging[];
CC_BASE_EXPORT extern const char kBrowserControlsHideThreshold[];
CC_BASE_EXPORT extern const char kBrowserControlsShowThreshold[];
CC_BASE_EXPORT extern const char kSlowDownRasterScaleFactor[];
CC_BASE_EXPORT extern const char kStrictLayerPropertyChangeChecking[];
-CC_BASE_EXPORT extern const char kEnableTileCompression[];
CC_BASE_EXPORT extern const char kCheckDamageEarly[];
// Switches for both the renderer and ui compositors.
diff --git a/chromium/cc/blink/BUILD.gn b/chromium/cc/blink/BUILD.gn
deleted file mode 100644
index 8b48a4097a7..00000000000
--- a/chromium/cc/blink/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//cc/cc.gni")
-
-cc_component("blink") {
- output_name = "cc_blink"
-
- sources = [
- "cc_blink_export.h",
- "scrollbar_impl.cc",
- "scrollbar_impl.h",
- "web_compositor_support_impl.cc",
- "web_compositor_support_impl.h",
- "web_content_layer_impl.cc",
- "web_content_layer_impl.h",
- "web_display_item_list_impl.cc",
- "web_display_item_list_impl.h",
- "web_external_texture_layer_impl.cc",
- "web_external_texture_layer_impl.h",
- "web_image_layer_impl.cc",
- "web_image_layer_impl.h",
- "web_layer_impl.cc",
- "web_layer_impl.h",
- "web_layer_impl_fixed_bounds.cc",
- "web_layer_impl_fixed_bounds.h",
- "web_scrollbar_layer_impl.cc",
- "web_scrollbar_layer_impl.h",
- ]
-
- defines = [ "CC_BLINK_IMPLEMENTATION" ]
-
- public_deps = [
- "//skia",
- ]
-
- deps = [
- "//base",
- "//base/third_party/dynamic_annotations",
- "//cc",
- "//cc/paint",
- "//gpu",
- "//third_party/blink/public:blink",
- "//ui/gfx",
- "//ui/gfx/geometry",
- ]
-}
-
-cc_test("cc_blink_unittests") {
- sources = [
- "web_display_item_list_impl_unittest.cc",
- "web_layer_impl_fixed_bounds_unittest.cc",
-
- # Setup.
- "test/cc_blink_test_suite.cc",
- "test/cc_blink_test_suite.h",
- "test/run_all_unittests.cc",
- ]
-
- deps = [
- ":blink",
- "//base/test:test_support",
- "//base/third_party/dynamic_annotations",
- "//cc",
- "//cc:test_support",
- "//cc/paint",
- "//skia",
- "//testing/gmock",
- "//testing/gtest",
- "//third_party/blink/public:blink",
- "//ui/gfx:test_support",
- "//ui/gfx/geometry",
- ]
-}
diff --git a/chromium/cc/blink/DEPS b/chromium/cc/blink/DEPS
deleted file mode 100644
index fc25dd99ad3..00000000000
--- a/chromium/cc/blink/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+third_party/blink/public/platform"
-]
diff --git a/chromium/cc/blink/OWNERS b/chromium/cc/blink/OWNERS
deleted file mode 100644
index bcf87b10f97..00000000000
--- a/chromium/cc/blink/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# COMPONENT: Blink>Compositing
diff --git a/chromium/cc/blink/cc_blink_export.h b/chromium/cc/blink/cc_blink_export.h
deleted file mode 100644
index 44ce527fc43..00000000000
--- a/chromium/cc/blink/cc_blink_export.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_CC_BLINK_EXPORT_H_
-#define CC_BLINK_CC_BLINK_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(CC_BLINK_IMPLEMENTATION)
-#define CC_BLINK_EXPORT __declspec(dllexport)
-#else
-#define CC_BLINK_EXPORT __declspec(dllimport)
-#endif // defined(CC_BLINK_IMPLEMENTATION)
-
-#else // defined(WIN32)
-#if defined(CC_BLINK_IMPLEMENTATION)
-#define CC_BLINK_EXPORT __attribute__((visibility("default")))
-#else
-#define CC_BLINK_EXPORT
-#endif
-#endif
-
-#else // defined(COMPONENT_BUILD)
-#define CC_BLINK_EXPORT
-#endif
-
-#endif // CC_BLINK_CC_BLINK_EXPORT_H_
diff --git a/chromium/cc/blink/scrollbar_impl.cc b/chromium/cc/blink/scrollbar_impl.cc
deleted file mode 100644
index f92b4acb522..00000000000
--- a/chromium/cc/blink/scrollbar_impl.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/scrollbar_impl.h"
-
-#include "base/logging.h"
-#include "third_party/blink/public/platform/web_scrollbar.h"
-#include "third_party/blink/public/platform/web_scrollbar_theme_geometry.h"
-
-using blink::WebScrollbar;
-
-namespace cc_blink {
-
-ScrollbarImpl::ScrollbarImpl(
- std::unique_ptr<WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry)
- : scrollbar_(std::move(scrollbar)),
- painter_(painter),
- geometry_(std::move(geometry)) {}
-
-ScrollbarImpl::~ScrollbarImpl() = default;
-
-cc::ScrollbarOrientation ScrollbarImpl::Orientation() const {
- if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal)
- return cc::HORIZONTAL;
- return cc::VERTICAL;
-}
-
-bool ScrollbarImpl::IsLeftSideVerticalScrollbar() const {
- return scrollbar_->IsLeftSideVerticalScrollbar();
-}
-
-bool ScrollbarImpl::HasThumb() const {
- return geometry_->HasThumb(scrollbar_.get());
-}
-
-bool ScrollbarImpl::IsOverlay() const {
- return scrollbar_->IsOverlay();
-}
-
-gfx::Point ScrollbarImpl::Location() const {
- return scrollbar_->Location();
-}
-
-int ScrollbarImpl::ThumbThickness() const {
- gfx::Rect thumb_rect = geometry_->ThumbRect(scrollbar_.get());
- if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal)
- return thumb_rect.height();
- return thumb_rect.width();
-}
-
-int ScrollbarImpl::ThumbLength() const {
- gfx::Rect thumb_rect = geometry_->ThumbRect(scrollbar_.get());
- if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal)
- return thumb_rect.width();
- return thumb_rect.height();
-}
-
-gfx::Rect ScrollbarImpl::TrackRect() const {
- return geometry_->TrackRect(scrollbar_.get());
-}
-
-float ScrollbarImpl::ThumbOpacity() const {
- return painter_.ThumbOpacity();
-}
-
-bool ScrollbarImpl::NeedsPaintPart(cc::ScrollbarPart part) const {
- if (part == cc::THUMB)
- return painter_.ThumbNeedsRepaint();
- return painter_.TrackNeedsRepaint();
-}
-
-bool ScrollbarImpl::UsesNinePatchThumbResource() const {
- return painter_.UsesNinePatchThumbResource();
-}
-
-gfx::Size ScrollbarImpl::NinePatchThumbCanvasSize() const {
- return geometry_->NinePatchThumbCanvasSize(scrollbar_.get());
-}
-
-gfx::Rect ScrollbarImpl::NinePatchThumbAperture() const {
- return geometry_->NinePatchThumbAperture(scrollbar_.get());
-}
-
-bool ScrollbarImpl::HasTickmarks() const {
- return scrollbar_->HasTickmarks();
-}
-
-void ScrollbarImpl::PaintPart(cc::PaintCanvas* canvas,
- cc::ScrollbarPart part,
- const gfx::Rect& content_rect) {
- if (part == cc::THUMB) {
- painter_.PaintThumb(canvas, content_rect);
- return;
- }
-
- if (part == cc::TICKMARKS) {
- painter_.PaintTickmarks(canvas, content_rect);
- return;
- }
-
- // The following is a simplification of ScrollbarThemeComposite::paint.
- painter_.PaintScrollbarBackground(canvas, content_rect);
-
- if (geometry_->HasButtons(scrollbar_.get())) {
- gfx::Rect back_button_start_paint_rect =
- geometry_->BackButtonStartRect(scrollbar_.get());
- painter_.PaintBackButtonStart(canvas, back_button_start_paint_rect);
-
- gfx::Rect back_button_end_paint_rect =
- geometry_->BackButtonEndRect(scrollbar_.get());
- painter_.PaintBackButtonEnd(canvas, back_button_end_paint_rect);
-
- gfx::Rect forward_button_start_paint_rect =
- geometry_->ForwardButtonStartRect(scrollbar_.get());
- painter_.PaintForwardButtonStart(canvas, forward_button_start_paint_rect);
-
- gfx::Rect forward_button_end_paint_rect =
- geometry_->ForwardButtonEndRect(scrollbar_.get());
- painter_.PaintForwardButtonEnd(canvas, forward_button_end_paint_rect);
- }
-
- gfx::Rect track_paint_rect = geometry_->TrackRect(scrollbar_.get());
- painter_.PaintTrackBackground(canvas, track_paint_rect);
-
- bool thumb_present = geometry_->HasThumb(scrollbar_.get());
- if (thumb_present) {
- painter_.PaintForwardTrackPart(canvas, track_paint_rect);
- painter_.PaintBackTrackPart(canvas, track_paint_rect);
- }
-
- painter_.PaintTickmarks(canvas, track_paint_rect);
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/scrollbar_impl.h b/chromium/cc/blink/scrollbar_impl.h
deleted file mode 100644
index 40157360fc8..00000000000
--- a/chromium/cc/blink/scrollbar_impl.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_SCROLLBAR_IMPL_H_
-#define CC_BLINK_SCROLLBAR_IMPL_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "cc/input/scrollbar.h"
-#include "cc/paint/paint_canvas.h"
-#include "third_party/blink/public/platform/web_scrollbar_theme_painter.h"
-
-namespace blink {
-class WebScrollbar;
-class WebScrollbarThemeGeometry;
-}
-
-namespace cc_blink {
-
-class ScrollbarImpl : public cc::Scrollbar {
- public:
- ScrollbarImpl(std::unique_ptr<blink::WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry);
- ~ScrollbarImpl() override;
-
- // cc::Scrollbar implementation.
- cc::ScrollbarOrientation Orientation() const override;
- bool IsLeftSideVerticalScrollbar() const override;
- bool HasThumb() const override;
- bool IsOverlay() const override;
- gfx::Point Location() const override;
- int ThumbThickness() const override;
- int ThumbLength() const override;
- gfx::Rect TrackRect() const override;
- float ThumbOpacity() const override;
- bool NeedsPaintPart(cc::ScrollbarPart part) const override;
- bool HasTickmarks() const override;
- void PaintPart(cc::PaintCanvas* canvas,
- cc::ScrollbarPart part,
- const gfx::Rect& content_rect) override;
-
- bool UsesNinePatchThumbResource() const override;
- gfx::Size NinePatchThumbCanvasSize() const override;
- gfx::Rect NinePatchThumbAperture() const override;
-
- private:
- std::unique_ptr<blink::WebScrollbar> scrollbar_;
- blink::WebScrollbarThemePainter painter_;
- std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry_;
-
- DISALLOW_COPY_AND_ASSIGN(ScrollbarImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_SCROLLBAR_IMPL_H_
diff --git a/chromium/cc/blink/web_blend_mode.h b/chromium/cc/blink/web_blend_mode.h
deleted file mode 100644
index 998868c299e..00000000000
--- a/chromium/cc/blink/web_blend_mode.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_BLEND_MODE_H_
-#define CC_BLINK_WEB_BLEND_MODE_H_
-
-#include "third_party/blink/public/platform/web_blend_mode.h"
-#include "third_party/skia/include/core/SkBlendMode.h"
-
-namespace cc_blink {
-
-inline SkBlendMode BlendModeToSkia(blink::WebBlendMode blend_mode) {
- switch (blend_mode) {
- case blink::WebBlendMode::kNormal:
- return SkBlendMode::kSrcOver;
- case blink::WebBlendMode::kMultiply:
- return SkBlendMode::kMultiply;
- case blink::WebBlendMode::kScreen:
- return SkBlendMode::kScreen;
- case blink::WebBlendMode::kOverlay:
- return SkBlendMode::kOverlay;
- case blink::WebBlendMode::kDarken:
- return SkBlendMode::kDarken;
- case blink::WebBlendMode::kLighten:
- return SkBlendMode::kLighten;
- case blink::WebBlendMode::kColorDodge:
- return SkBlendMode::kColorDodge;
- case blink::WebBlendMode::kColorBurn:
- return SkBlendMode::kColorBurn;
- case blink::WebBlendMode::kHardLight:
- return SkBlendMode::kHardLight;
- case blink::WebBlendMode::kSoftLight:
- return SkBlendMode::kSoftLight;
- case blink::WebBlendMode::kDifference:
- return SkBlendMode::kDifference;
- case blink::WebBlendMode::kExclusion:
- return SkBlendMode::kExclusion;
- case blink::WebBlendMode::kHue:
- return SkBlendMode::kHue;
- case blink::WebBlendMode::kSaturation:
- return SkBlendMode::kSaturation;
- case blink::WebBlendMode::kColor:
- return SkBlendMode::kColor;
- case blink::WebBlendMode::kLuminosity:
- return SkBlendMode::kLuminosity;
- }
- return SkBlendMode::kSrcOver;
-}
-
-inline blink::WebBlendMode BlendModeFromSkia(SkBlendMode blend_mode) {
- switch (blend_mode) {
- case SkBlendMode::kSrcOver:
- return blink::WebBlendMode::kNormal;
- case SkBlendMode::kMultiply:
- return blink::WebBlendMode::kMultiply;
- case SkBlendMode::kScreen:
- return blink::WebBlendMode::kScreen;
- case SkBlendMode::kOverlay:
- return blink::WebBlendMode::kOverlay;
- case SkBlendMode::kDarken:
- return blink::WebBlendMode::kDarken;
- case SkBlendMode::kLighten:
- return blink::WebBlendMode::kLighten;
- case SkBlendMode::kColorDodge:
- return blink::WebBlendMode::kColorDodge;
- case SkBlendMode::kColorBurn:
- return blink::WebBlendMode::kColorBurn;
- case SkBlendMode::kHardLight:
- return blink::WebBlendMode::kHardLight;
- case SkBlendMode::kSoftLight:
- return blink::WebBlendMode::kSoftLight;
- case SkBlendMode::kDifference:
- return blink::WebBlendMode::kDifference;
- case SkBlendMode::kExclusion:
- return blink::WebBlendMode::kExclusion;
- case SkBlendMode::kHue:
- return blink::WebBlendMode::kHue;
- case SkBlendMode::kSaturation:
- return blink::WebBlendMode::kSaturation;
- case SkBlendMode::kColor:
- return blink::WebBlendMode::kColor;
- case SkBlendMode::kLuminosity:
- return blink::WebBlendMode::kLuminosity;
-
- // these value are SkBlendModes, but no blend modes.
- case SkBlendMode::kClear:
- case SkBlendMode::kSrc:
- case SkBlendMode::kDst:
- case SkBlendMode::kDstOver:
- case SkBlendMode::kSrcIn:
- case SkBlendMode::kDstIn:
- case SkBlendMode::kSrcOut:
- case SkBlendMode::kDstOut:
- case SkBlendMode::kSrcATop:
- case SkBlendMode::kDstATop:
- case SkBlendMode::kXor:
- case SkBlendMode::kPlus:
- case SkBlendMode::kModulate:
- NOTREACHED();
- }
- return blink::WebBlendMode::kNormal;
-}
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_BLEND_MODE_H_
diff --git a/chromium/cc/blink/web_compositor_support_impl.cc b/chromium/cc/blink/web_compositor_support_impl.cc
deleted file mode 100644
index 04d038b181b..00000000000
--- a/chromium/cc/blink/web_compositor_support_impl.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_compositor_support_impl.h"
-
-#include <utility>
-
-#include "cc/blink/web_content_layer_impl.h"
-#include "cc/blink/web_display_item_list_impl.h"
-#include "cc/blink/web_external_texture_layer_impl.h"
-#include "cc/blink/web_image_layer_impl.h"
-#include "cc/blink/web_layer_impl.h"
-#include "cc/blink/web_scrollbar_layer_impl.h"
-#include "cc/layers/layer.h"
-
-using blink::WebContentLayer;
-using blink::WebContentLayerClient;
-using blink::WebDisplayItemList;
-using blink::WebExternalTextureLayer;
-using blink::WebImageLayer;
-using blink::WebLayer;
-using blink::WebScrollbar;
-using blink::WebScrollbarLayer;
-using blink::WebScrollbarThemeGeometry;
-using blink::WebScrollbarThemePainter;
-
-namespace cc_blink {
-
-WebCompositorSupportImpl::WebCompositorSupportImpl() = default;
-
-WebCompositorSupportImpl::~WebCompositorSupportImpl() = default;
-
-std::unique_ptr<WebLayer> WebCompositorSupportImpl::CreateLayer() {
- return std::make_unique<WebLayerImpl>();
-}
-
-std::unique_ptr<WebLayer> WebCompositorSupportImpl::CreateLayerFromCCLayer(
- cc::Layer* layer) {
- return std::make_unique<WebLayerImpl>(layer);
-}
-
-std::unique_ptr<WebContentLayer> WebCompositorSupportImpl::CreateContentLayer(
- WebContentLayerClient* client) {
- return std::make_unique<WebContentLayerImpl>(client);
-}
-
-std::unique_ptr<WebExternalTextureLayer>
-WebCompositorSupportImpl::CreateExternalTextureLayer(
- cc::TextureLayerClient* client) {
- return std::make_unique<WebExternalTextureLayerImpl>(client);
-}
-
-std::unique_ptr<blink::WebImageLayer>
-WebCompositorSupportImpl::CreateImageLayer() {
- return std::make_unique<WebImageLayerImpl>();
-}
-
-std::unique_ptr<WebScrollbarLayer>
-WebCompositorSupportImpl::CreateScrollbarLayer(
- std::unique_ptr<WebScrollbar> scrollbar,
- WebScrollbarThemePainter painter,
- std::unique_ptr<WebScrollbarThemeGeometry> geometry) {
- return std::make_unique<WebScrollbarLayerImpl>(std::move(scrollbar), painter,
- std::move(geometry),
- /* is overlay */ false);
-}
-
-std::unique_ptr<WebScrollbarLayer>
-WebCompositorSupportImpl::CreateOverlayScrollbarLayer(
- std::unique_ptr<WebScrollbar> scrollbar,
- WebScrollbarThemePainter painter,
- std::unique_ptr<WebScrollbarThemeGeometry> geometry) {
- return std::make_unique<WebScrollbarLayerImpl>(std::move(scrollbar), painter,
- std::move(geometry),
- /* is overlay */ true);
-}
-
-std::unique_ptr<WebScrollbarLayer>
-WebCompositorSupportImpl::CreateSolidColorScrollbarLayer(
- WebScrollbar::Orientation orientation,
- int thumb_thickness,
- int track_start,
- bool is_left_side_vertical_scrollbar) {
- return std::make_unique<WebScrollbarLayerImpl>(
- orientation, thumb_thickness, track_start,
- is_left_side_vertical_scrollbar);
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_compositor_support_impl.h b/chromium/cc/blink/web_compositor_support_impl.h
deleted file mode 100644
index 9a24211b9a2..00000000000
--- a/chromium/cc/blink/web_compositor_support_impl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_COMPOSITOR_SUPPORT_IMPL_H_
-#define CC_BLINK_WEB_COMPOSITOR_SUPPORT_IMPL_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "cc/blink/cc_blink_export.h"
-#include "third_party/blink/public/platform/web_compositor_support.h"
-#include "third_party/blink/public/platform/web_content_layer_client.h"
-#include "third_party/blink/public/platform/web_layer.h"
-
-namespace cc_blink {
-
-class CC_BLINK_EXPORT WebCompositorSupportImpl
- : public blink::WebCompositorSupport {
- public:
- WebCompositorSupportImpl();
- ~WebCompositorSupportImpl() override;
-
- std::unique_ptr<blink::WebLayer> CreateLayer() override;
- std::unique_ptr<blink::WebLayer> CreateLayerFromCCLayer(cc::Layer*) override;
- std::unique_ptr<blink::WebContentLayer> CreateContentLayer(
- blink::WebContentLayerClient* client) override;
- std::unique_ptr<blink::WebExternalTextureLayer> CreateExternalTextureLayer(
- cc::TextureLayerClient* client) override;
- std::unique_ptr<blink::WebImageLayer> CreateImageLayer() override;
- std::unique_ptr<blink::WebScrollbarLayer> CreateScrollbarLayer(
- std::unique_ptr<blink::WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry>) override;
- std::unique_ptr<blink::WebScrollbarLayer> CreateOverlayScrollbarLayer(
- std::unique_ptr<blink::WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry>) override;
- std::unique_ptr<blink::WebScrollbarLayer> CreateSolidColorScrollbarLayer(
- blink::WebScrollbar::Orientation orientation,
- int thumb_thickness,
- int track_start,
- bool is_left_side_vertical_scrollbar) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WebCompositorSupportImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_COMPOSITOR_SUPPORT_IMPL_H_
diff --git a/chromium/cc/blink/web_content_layer_impl.cc b/chromium/cc/blink/web_content_layer_impl.cc
deleted file mode 100644
index 5dc2f9c2d81..00000000000
--- a/chromium/cc/blink/web_content_layer_impl.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_content_layer_impl.h"
-
-#include <stddef.h>
-
-#include "base/command_line.h"
-#include "cc/base/switches.h"
-#include "cc/blink/web_display_item_list_impl.h"
-#include "cc/layers/picture_layer.h"
-#include "third_party/blink/public/platform/web_content_layer_client.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-
-using cc::PictureLayer;
-
-namespace cc_blink {
-
-static blink::WebContentLayerClient::PaintingControlSetting
-PaintingControlToWeb(
- cc::ContentLayerClient::PaintingControlSetting painting_control) {
- switch (painting_control) {
- case cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL:
- return blink::WebContentLayerClient::kPaintDefaultBehavior;
- case cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL_FOR_TEST:
- return blink::WebContentLayerClient::kPaintDefaultBehaviorForTest;
- case cc::ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED:
- return blink::WebContentLayerClient::kDisplayListConstructionDisabled;
- case cc::ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED:
- return blink::WebContentLayerClient::kDisplayListCachingDisabled;
- case cc::ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED:
- return blink::WebContentLayerClient::kDisplayListPaintingDisabled;
- case cc::ContentLayerClient::SUBSEQUENCE_CACHING_DISABLED:
- return blink::WebContentLayerClient::kSubsequenceCachingDisabled;
- case cc::ContentLayerClient::PARTIAL_INVALIDATION:
- return blink::WebContentLayerClient::kPartialInvalidation;
- }
- NOTREACHED();
- return blink::WebContentLayerClient::kPaintDefaultBehavior;
-}
-
-WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client)
- : client_(client) {
- layer_ = std::make_unique<WebLayerImpl>(PictureLayer::Create(this));
- layer_->layer()->SetIsDrawable(true);
-}
-
-WebContentLayerImpl::~WebContentLayerImpl() {
- static_cast<PictureLayer*>(layer_->layer())->ClearClient();
-}
-
-blink::WebLayer* WebContentLayerImpl::Layer() {
- return layer_.get();
-}
-
-void WebContentLayerImpl::SetTransformedRasterizationAllowed(bool allowed) {
- static_cast<PictureLayer*>(layer_->layer())
- ->SetTransformedRasterizationAllowed(allowed);
-}
-
-bool WebContentLayerImpl::TransformedRasterizationAllowed() const {
- return static_cast<PictureLayer*>(layer_->layer())
- ->transformed_rasterization_allowed();
-}
-
-gfx::Rect WebContentLayerImpl::PaintableRegion() {
- return client_->PaintableRegion();
-}
-
-scoped_refptr<cc::DisplayItemList>
-WebContentLayerImpl::PaintContentsToDisplayList(
- cc::ContentLayerClient::PaintingControlSetting painting_control) {
- auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
- if (client_) {
- WebDisplayItemListImpl list(display_list.get());
- client_->PaintContents(&list, PaintingControlToWeb(painting_control));
- }
- display_list->Finalize();
- return display_list;
-}
-
-bool WebContentLayerImpl::FillsBoundsCompletely() const {
- return false;
-}
-
-size_t WebContentLayerImpl::GetApproximateUnsharedMemoryUsage() const {
- return client_->ApproximateUnsharedMemoryUsage();
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_content_layer_impl.h b/chromium/cc/blink/web_content_layer_impl.h
deleted file mode 100644
index 6f82ec478e9..00000000000
--- a/chromium/cc/blink/web_content_layer_impl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_CONTENT_LAYER_IMPL_H_
-#define CC_BLINK_WEB_CONTENT_LAYER_IMPL_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "cc/blink/cc_blink_export.h"
-#include "cc/blink/web_layer_impl.h"
-#include "cc/layers/content_layer_client.h"
-#include "third_party/blink/public/platform/web_content_layer.h"
-
-namespace blink {
-class WebContentLayerClient;
-}
-
-namespace cc_blink {
-
-class WebContentLayerImpl : public blink::WebContentLayer,
- public cc::ContentLayerClient {
- public:
- CC_BLINK_EXPORT explicit WebContentLayerImpl(blink::WebContentLayerClient*);
-
- ~WebContentLayerImpl() override;
-
- // WebContentLayer implementation.
- blink::WebLayer* Layer() override;
- void SetTransformedRasterizationAllowed(bool) override;
- bool TransformedRasterizationAllowed() const override;
-
- protected:
- // ContentLayerClient implementation.
- gfx::Rect PaintableRegion() override;
- scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting painting_control) override;
- bool FillsBoundsCompletely() const override;
- size_t GetApproximateUnsharedMemoryUsage() const override;
-
- std::unique_ptr<WebLayerImpl> layer_;
- blink::WebContentLayerClient* client_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WebContentLayerImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_CONTENT_LAYER_IMPL_H_
diff --git a/chromium/cc/blink/web_display_item_list_impl.cc b/chromium/cc/blink/web_display_item_list_impl.cc
deleted file mode 100644
index 5be83ce9a64..00000000000
--- a/chromium/cc/blink/web_display_item_list_impl.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_display_item_list_impl.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-
-#include "cc/paint/paint_filter.h"
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/paint/render_surface_filters.h"
-#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/skia/include/core/SkColorFilter.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/safe_integer_conversions.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/transform.h"
-
-namespace cc_blink {
-
-namespace {
-
-} // namespace
-
-WebDisplayItemListImpl::WebDisplayItemListImpl()
- : display_item_list_(base::MakeRefCounted<cc::DisplayItemList>()) {}
-
-WebDisplayItemListImpl::WebDisplayItemListImpl(
- cc::DisplayItemList* display_list)
- : display_item_list_(display_list) {
-}
-
-WebDisplayItemListImpl::~WebDisplayItemListImpl() = default;
-
-void WebDisplayItemListImpl::AppendDrawingItem(
- const blink::WebRect& visual_rect,
- sk_sp<const cc::PaintOpBuffer> record) {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::DrawRecordOp>(std::move(record));
- display_item_list_->EndPaintOfUnpaired(visual_rect);
-}
-
-void WebDisplayItemListImpl::AppendClipItem(
- const blink::WebRect& clip_rect,
- const blink::WebVector<SkRRect>& rounded_clip_rects) {
- bool antialias = true;
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveOp>();
- display_item_list_->push<cc::ClipRectOp>(gfx::RectToSkRect(clip_rect),
- SkClipOp::kIntersect, antialias);
- for (const SkRRect& rrect : rounded_clip_rects) {
- if (rrect.isRect()) {
- display_item_list_->push<cc::ClipRectOp>(rrect.rect(),
- SkClipOp::kIntersect, antialias);
- } else {
- display_item_list_->push<cc::ClipRRectOp>(rrect, SkClipOp::kIntersect,
- antialias);
- }
- }
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndClipItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendClipPathItem(const SkPath& clip_path,
- bool antialias) {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveOp>();
- display_item_list_->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect,
- antialias);
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndClipPathItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendFloatClipItem(
- const blink::WebFloatRect& clip_rect) {
- bool antialias = true;
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveOp>();
- display_item_list_->push<cc::ClipRectOp>(gfx::RectFToSkRect(clip_rect),
- SkClipOp::kIntersect, antialias);
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndFloatClipItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendTransformItem(const SkMatrix44& matrix) {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveOp>();
- if (!matrix.isIdentity())
- display_item_list_->push<cc::ConcatOp>(static_cast<SkMatrix>(matrix));
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndTransformItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendCompositingItem(
- float opacity,
- SkBlendMode xfermode,
- SkRect* bounds,
- SkColorFilter* color_filter) {
- DCHECK_GE(opacity, 0.f);
- DCHECK_LE(opacity, 1.f);
-
- // TODO(ajuma): This should really be rounding instead of flooring the alpha
- // value, but that breaks slimming paint reftests.
- auto alpha = static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity));
-
- if (xfermode == SkBlendMode::kSrcOver && !color_filter) {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveLayerAlphaOp>(bounds, alpha, false);
- if (bounds) {
- display_item_list_->push<cc::ClipRectOp>(*bounds, SkClipOp::kIntersect,
- false);
- }
- display_item_list_->EndPaintOfPairedBegin();
- return;
- }
-
- cc::PaintFlags flags;
- flags.setBlendMode(xfermode);
- flags.setAlpha(alpha);
- flags.setColorFilter(sk_ref_sp(color_filter));
-
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveLayerOp>(bounds, &flags);
- if (bounds) {
- display_item_list_->push<cc::ClipRectOp>(*bounds, SkClipOp::kIntersect,
- false);
- }
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndCompositingItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendFilterItem(
- const cc::FilterOperations& filters,
- const blink::WebFloatRect& filter_bounds,
- const blink::WebFloatPoint& origin) {
- display_item_list_->StartPaint();
-
- // TODO(danakj): Skip the save+translate+restore if the origin is 0,0. This
- // should be easier to do when this code is part of the blink DisplayItem
- // which can keep related state.
- display_item_list_->push<cc::SaveOp>();
- display_item_list_->push<cc::TranslateOp>(origin.x, origin.y);
-
- cc::PaintFlags flags;
- flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter(
- filters, gfx::SizeF(filter_bounds.width, filter_bounds.height)));
-
- SkRect layer_bounds = gfx::RectFToSkRect(filter_bounds);
- layer_bounds.offset(-origin.x, -origin.y);
- display_item_list_->push<cc::SaveLayerOp>(&layer_bounds, &flags);
- display_item_list_->push<cc::TranslateOp>(-origin.x, -origin.y);
-
- display_item_list_->EndPaintOfPairedBegin(
- gfx::ToEnclosingRect(filter_bounds));
-}
-
-void WebDisplayItemListImpl::AppendEndFilterItem() {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::RestoreOp>(); // For SaveLayerOp.
- display_item_list_->push<cc::RestoreOp>(); // For SaveOp.
- display_item_list_->EndPaintOfPairedEnd();
-}
-
-void WebDisplayItemListImpl::AppendScrollItem(
- const blink::WebSize& scroll_offset,
- ScrollContainerId) {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::SaveOp>();
- display_item_list_->push<cc::TranslateOp>(
- static_cast<float>(-scroll_offset.width),
- static_cast<float>(-scroll_offset.height));
- display_item_list_->EndPaintOfPairedBegin();
-}
-
-void WebDisplayItemListImpl::AppendEndScrollItem() {
- AppendRestore();
-}
-
-void WebDisplayItemListImpl::AppendRestore() {
- display_item_list_->StartPaint();
- display_item_list_->push<cc::RestoreOp>();
- display_item_list_->EndPaintOfPairedEnd();
-}
-
-cc::DisplayItemList* WebDisplayItemListImpl::GetCcDisplayItemList() {
- return display_item_list_.get();
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_display_item_list_impl.h b/chromium/cc/blink/web_display_item_list_impl.h
deleted file mode 100644
index 5db188c85c8..00000000000
--- a/chromium/cc/blink/web_display_item_list_impl.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_DISPLAY_ITEM_LIST_IMPL_H_
-#define CC_BLINK_WEB_DISPLAY_ITEM_LIST_IMPL_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "cc/blink/cc_blink_export.h"
-#include "cc/paint/display_item_list.h"
-#include "third_party/blink/public/platform/web_display_item_list.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/skia/include/core/SkBlendMode.h"
-#include "ui/gfx/geometry/point_f.h"
-
-class SkColorFilter;
-class SkMatrix44;
-class SkPath;
-class SkRRect;
-
-namespace blink {
-struct WebFloatRect;
-struct WebFloatPoint;
-struct WebRect;
-}
-
-namespace cc {
-class FilterOperations;
-class PaintOpBuffer;
-}
-
-namespace cc_blink {
-
-class CC_BLINK_EXPORT WebDisplayItemListImpl
- : public blink::WebDisplayItemList {
- public:
- WebDisplayItemListImpl();
- explicit WebDisplayItemListImpl(cc::DisplayItemList* display_list);
- ~WebDisplayItemListImpl() override;
-
- // blink::WebDisplayItemList implementation.
- void AppendDrawingItem(const blink::WebRect& visual_rect,
- sk_sp<const cc::PaintOpBuffer> record) override;
- void AppendClipItem(
- const blink::WebRect& clip_rect,
- const blink::WebVector<SkRRect>& rounded_clip_rects) override;
- void AppendEndClipItem() override;
- void AppendClipPathItem(const SkPath& clip_path, bool antialias) override;
- void AppendEndClipPathItem() override;
- void AppendFloatClipItem(const blink::WebFloatRect& clip_rect) override;
- void AppendEndFloatClipItem() override;
- void AppendTransformItem(const SkMatrix44& matrix) override;
- void AppendEndTransformItem() override;
- void AppendCompositingItem(float opacity,
- SkBlendMode,
- SkRect* bounds,
- SkColorFilter*) override;
- void AppendEndCompositingItem() override;
- void AppendFilterItem(const cc::FilterOperations& filters,
- const blink::WebFloatRect& filter_bounds,
- const blink::WebFloatPoint& origin) override;
- void AppendEndFilterItem() override;
- void AppendScrollItem(const blink::WebSize& scrollOffset,
- ScrollContainerId) override;
- void AppendEndScrollItem() override;
- cc::DisplayItemList* GetCcDisplayItemList() override;
-
- private:
- void AppendRestore();
-
- scoped_refptr<cc::DisplayItemList> display_item_list_;
-
- DISALLOW_COPY_AND_ASSIGN(WebDisplayItemListImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_DISPLAY_ITEM_LIST_IMPL_H_
diff --git a/chromium/cc/blink/web_display_item_list_impl_unittest.cc b/chromium/cc/blink/web_display_item_list_impl_unittest.cc
deleted file mode 100644
index f9efd761eed..00000000000
--- a/chromium/cc/blink/web_display_item_list_impl_unittest.cc
+++ /dev/null
@@ -1,91 +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/blink/web_display_item_list_impl.h"
-#include "base/strings/stringprintf.h"
-#include "cc/paint/display_item_list.h"
-#include "cc/paint/paint_op_buffer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-
-namespace cc_blink {
-namespace {
-
-// SkCanvas::saveLayer(Alpha) allows for an optional bounds which is a hint
-// for the backing size to use for the indirect buffer. It is not really
-// a clip though, as Skia is allowed to use any size buffer it wants.
-// Additionally, PaintOpBuffer can drop the bounds when folding
-// save/draw/restore into a single draw-with-alpha. However, in some cases
-// calling code (SVGMask) is drawing unclipped items which really need
-// a clip to not pollute the rest of the painted content with their draw
-// commands. Therefore, this tests that when providing bounds to
-// AppendCompositingItem that a clip is inserted.
-TEST(WebDisplayItemListImpl, ClipWhenCompositing) {
- // Test with two different blend modes to differentiate the saveLayer vs
- // saveLayerAlpha logic inside of AppendCompositingItem;
- SkBlendMode blend_modes[] = {SkBlendMode::kSrc, SkBlendMode::kSrcOver};
- for (size_t i = 0; i < arraysize(blend_modes); ++i) {
- static constexpr int size = 20;
- static constexpr SkColor background_color = SK_ColorMAGENTA;
- static constexpr SkColor clip_color = SK_ColorYELLOW;
-
- blink::WebRect full_bounds(0, 0, size, size);
- blink::WebRect clip_bounds(5, 3, 13, 9);
- SkRect sk_clip_bounds = SkRect::MakeXYWH(
- clip_bounds.x, clip_bounds.y, clip_bounds.width, clip_bounds.height);
- SkIRect clip_irect = sk_clip_bounds.roundOut();
-
- auto cc_list = base::MakeRefCounted<cc::DisplayItemList>();
- cc_blink::WebDisplayItemListImpl web_list(cc_list.get());
-
- // drawColor(background color)
- // saveLayer(should clip)
- // drawColor(clip color)
- // end
- auto background_record = sk_make_sp<cc::PaintRecord>();
- background_record->push<cc::DrawColorOp>(background_color,
- SkBlendMode::kSrcOver);
- web_list.AppendDrawingItem(full_bounds, background_record);
- web_list.AppendCompositingItem(1.f, blend_modes[i], &sk_clip_bounds,
- nullptr);
- auto clip_record = sk_make_sp<cc::PaintRecord>();
- clip_record->push<cc::DrawColorOp>(clip_color, SkBlendMode::kSrcOver);
- web_list.AppendDrawingItem(full_bounds, clip_record);
- web_list.AppendEndCompositingItem();
- cc_list->Finalize();
-
- SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32Premul(size, size));
- SkCanvas canvas(bitmap);
- canvas.drawColor(SK_ColorGRAY);
-
- cc_list->Raster(&canvas);
- uint8_t* pixels = static_cast<uint8_t*>(bitmap.getPixels());
- size_t row_bytes = size * 4;
- for (size_t y = 0; y < size; ++y) {
- size_t y_offset = y * row_bytes;
- for (size_t x = 0; x < size; ++x) {
- size_t x_offset = x * 4;
- uint8_t* pixel = &pixels[y_offset + x_offset];
- SCOPED_TRACE(
- base::StringPrintf("x(%zd) y(%zd) mode(%d)", x, y, blend_modes[i]));
-
- if (clip_irect.contains(x, y)) {
- EXPECT_EQ(SkColorGetR(clip_color), pixel[SK_R32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetG(clip_color), pixel[SK_G32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetB(clip_color), pixel[SK_B32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetA(clip_color), pixel[SK_A32_SHIFT / 8]);
- } else {
- EXPECT_EQ(SkColorGetR(background_color), pixel[SK_R32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetG(background_color), pixel[SK_G32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetB(background_color), pixel[SK_B32_SHIFT / 8]);
- EXPECT_EQ(SkColorGetA(background_color), pixel[SK_A32_SHIFT / 8]);
- }
- }
- }
- }
-}
-
-} // namespace
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_external_texture_layer_impl.cc b/chromium/cc/blink/web_external_texture_layer_impl.cc
deleted file mode 100644
index 64fbf26cbd4..00000000000
--- a/chromium/cc/blink/web_external_texture_layer_impl.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_external_texture_layer_impl.h"
-
-#include "cc/blink/web_layer_impl.h"
-#include "cc/layers/texture_layer.h"
-
-using cc::TextureLayer;
-
-namespace cc_blink {
-
-WebExternalTextureLayerImpl::WebExternalTextureLayerImpl(
- cc::TextureLayerClient* client) {
- scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(client);
- layer->SetIsDrawable(true);
- layer_.reset(new WebLayerImpl(layer));
-}
-
-WebExternalTextureLayerImpl::~WebExternalTextureLayerImpl() {
- static_cast<TextureLayer*>(layer_->layer())->ClearClient();
-}
-
-blink::WebLayer* WebExternalTextureLayerImpl::Layer() {
- return layer_.get();
-}
-
-void WebExternalTextureLayerImpl::ClearTexture() {
- TextureLayer* layer = static_cast<TextureLayer*>(layer_->layer());
- layer->ClearTexture();
-}
-
-void WebExternalTextureLayerImpl::SetOpaque(bool opaque) {
- static_cast<TextureLayer*>(layer_->layer())->SetContentsOpaque(opaque);
-}
-
-void WebExternalTextureLayerImpl::SetFlipped(bool flipped) {
- static_cast<TextureLayer*>(layer_->layer())->SetFlipped(flipped);
-}
-
-void WebExternalTextureLayerImpl::SetPremultipliedAlpha(
- bool premultiplied_alpha) {
- static_cast<TextureLayer*>(layer_->layer())
- ->SetPremultipliedAlpha(premultiplied_alpha);
-}
-
-void WebExternalTextureLayerImpl::SetBlendBackgroundColor(bool blend) {
- static_cast<TextureLayer*>(layer_->layer())->SetBlendBackgroundColor(blend);
-}
-
-void WebExternalTextureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
- static_cast<TextureLayer*>(layer_->layer())
- ->SetNearestNeighbor(nearest_neighbor);
-}
-
-void WebExternalTextureLayerImpl::SetUV(
- const blink::WebFloatPoint left_top,
- const blink::WebFloatPoint right_bottom) {
- static_cast<TextureLayer*>(layer_->layer())
- ->SetUV(gfx::PointF(left_top.x, left_top.y),
- gfx::PointF(right_bottom.x, right_bottom.y));
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_external_texture_layer_impl.h b/chromium/cc/blink/web_external_texture_layer_impl.h
deleted file mode 100644
index 11ca63cf5b1..00000000000
--- a/chromium/cc/blink/web_external_texture_layer_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_EXTERNAL_TEXTURE_LAYER_IMPL_H_
-#define CC_BLINK_WEB_EXTERNAL_TEXTURE_LAYER_IMPL_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "cc/blink/cc_blink_export.h"
-#include "third_party/blink/public/platform/web_external_texture_layer.h"
-
-namespace cc {
-class TextureLayerClient;
-}
-
-namespace cc_blink {
-class WebLayerImpl;
-
-class WebExternalTextureLayerImpl : public blink::WebExternalTextureLayer {
- public:
- CC_BLINK_EXPORT explicit WebExternalTextureLayerImpl(cc::TextureLayerClient*);
- ~WebExternalTextureLayerImpl() override;
-
- // blink::WebExternalTextureLayer implementation.
- blink::WebLayer* Layer() override;
- void ClearTexture() override;
- void SetOpaque(bool opaque) override;
- void SetFlipped(bool flipped) override;
- void SetPremultipliedAlpha(bool premultiplied) override;
- void SetBlendBackgroundColor(bool blend) override;
- void SetNearestNeighbor(bool nearest_neighbor) override;
- void SetUV(const blink::WebFloatPoint left_top,
- const blink::WebFloatPoint right_bottom) override;
-
- private:
- std::unique_ptr<WebLayerImpl> layer_;
-
- DISALLOW_COPY_AND_ASSIGN(WebExternalTextureLayerImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_EXTERNAL_TEXTURE_LAYER_IMPL_H_
diff --git a/chromium/cc/blink/web_image_layer_impl.cc b/chromium/cc/blink/web_image_layer_impl.cc
deleted file mode 100644
index 403bb0cc49f..00000000000
--- a/chromium/cc/blink/web_image_layer_impl.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_image_layer_impl.h"
-
-#include "cc/blink/web_layer_impl.h"
-#include "cc/blink/web_layer_impl_fixed_bounds.h"
-#include "cc/layers/picture_image_layer.h"
-#include "third_party/skia/include/core/SkImage.h"
-
-namespace cc_blink {
-
-WebImageLayerImpl::WebImageLayerImpl() {
- layer_.reset(new WebLayerImplFixedBounds(cc::PictureImageLayer::Create()));
-}
-
-WebImageLayerImpl::~WebImageLayerImpl() = default;
-
-blink::WebLayer* WebImageLayerImpl::Layer() {
- return layer_.get();
-}
-
-void WebImageLayerImpl::SetImage(cc::PaintImage image,
- const SkMatrix& matrix,
- bool uses_width_as_height) {
- gfx::Size size = uses_width_as_height
- ? gfx::Size(image.height(), image.width())
- : gfx::Size(image.width(), image.height());
- static_cast<WebLayerImplFixedBounds*>(layer_.get())->SetFixedBounds(size);
- static_cast<cc::PictureImageLayer*>(layer_->layer())
- ->SetImage(std::move(image), matrix, uses_width_as_height);
-}
-
-void WebImageLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
- static_cast<cc::PictureImageLayer*>(layer_->layer())
- ->SetNearestNeighbor(nearest_neighbor);
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_image_layer_impl.h b/chromium/cc/blink/web_image_layer_impl.h
deleted file mode 100644
index 11b76dc95e7..00000000000
--- a/chromium/cc/blink/web_image_layer_impl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_IMAGE_LAYER_IMPL_H_
-#define CC_BLINK_WEB_IMAGE_LAYER_IMPL_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "cc/blink/cc_blink_export.h"
-#include "cc/paint/paint_image.h"
-#include "third_party/blink/public/platform/web_image_layer.h"
-
-namespace cc_blink {
-
-class WebLayerImpl;
-
-class WebImageLayerImpl : public blink::WebImageLayer {
- public:
- CC_BLINK_EXPORT WebImageLayerImpl();
- ~WebImageLayerImpl() override;
-
- // blink::WebImageLayer implementation.
- blink::WebLayer* Layer() override;
- void SetImage(PaintImage image,
- const SkMatrix& matrix,
- bool uses_width_as_height) override;
- void SetNearestNeighbor(bool nearest_neighbor) override;
-
- private:
- std::unique_ptr<WebLayerImpl> layer_;
-
- DISALLOW_COPY_AND_ASSIGN(WebImageLayerImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_IMAGE_LAYER_IMPL_H_
diff --git a/chromium/cc/blink/web_layer_impl.cc b/chromium/cc/blink/web_layer_impl.cc
deleted file mode 100644
index b8cb7aeb9eb..00000000000
--- a/chromium/cc/blink/web_layer_impl.cc
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_layer_impl.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/containers/flat_map.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_checker.h"
-#include "base/trace_event/trace_event_impl.h"
-#include "cc/base/region.h"
-#include "cc/base/switches.h"
-#include "cc/blink/web_blend_mode.h"
-#include "cc/layers/layer.h"
-#include "cc/layers/layer_position_constraint.h"
-#include "cc/layers/touch_action_region.h"
-#include "cc/trees/element_id.h"
-#include "cc/trees/layer_tree_host.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_layer_position_constraint.h"
-#include "third_party/blink/public/platform/web_layer_scroll_client.h"
-#include "third_party/blink/public/platform/web_layer_sticky_position_constraint.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/vector2d_conversions.h"
-
-using cc::Layer;
-using blink::WebLayer;
-using blink::WebFloatPoint;
-using blink::WebVector;
-using blink::WebRect;
-using blink::WebSize;
-using blink::WebColor;
-using blink::WebOverscrollBehavior;
-
-namespace cc_blink {
-
-WebLayerImpl::WebLayerImpl()
- : layer_(Layer::Create()), contents_opaque_is_fixed_(false) {}
-
-WebLayerImpl::WebLayerImpl(scoped_refptr<Layer> layer)
- : layer_(layer), contents_opaque_is_fixed_(false) {
-}
-
-WebLayerImpl::~WebLayerImpl() {
- layer_->SetLayerClient(nullptr);
-}
-
-int WebLayerImpl::Id() const {
- return layer_->id();
-}
-
-DISABLE_CFI_PERF
-void WebLayerImpl::InvalidateRect(const blink::WebRect& rect) {
- layer_->SetNeedsDisplayRect(rect);
-}
-
-void WebLayerImpl::Invalidate() {
- layer_->SetNeedsDisplay();
-}
-
-void WebLayerImpl::AddChild(WebLayer* child) {
- layer_->AddChild(static_cast<WebLayerImpl*>(child)->layer());
-}
-
-void WebLayerImpl::InsertChild(WebLayer* child, size_t index) {
- layer_->InsertChild(static_cast<WebLayerImpl*>(child)->layer(), index);
-}
-
-void WebLayerImpl::ReplaceChild(WebLayer* reference, WebLayer* new_layer) {
- layer_->ReplaceChild(static_cast<WebLayerImpl*>(reference)->layer(),
- static_cast<WebLayerImpl*>(new_layer)->layer());
-}
-
-void WebLayerImpl::RemoveFromParent() {
- layer_->RemoveFromParent();
-}
-
-void WebLayerImpl::RemoveAllChildren() {
- layer_->RemoveAllChildren();
-}
-
-void WebLayerImpl::SetBounds(const WebSize& size) {
- layer_->SetBounds(size);
-}
-
-WebSize WebLayerImpl::Bounds() const {
- return layer_->bounds();
-}
-
-void WebLayerImpl::SetMasksToBounds(bool masks_to_bounds) {
- layer_->SetMasksToBounds(masks_to_bounds);
-}
-
-bool WebLayerImpl::MasksToBounds() const {
- return layer_->masks_to_bounds();
-}
-
-void WebLayerImpl::SetMaskLayer(WebLayer* maskLayer) {
- layer_->SetMaskLayer(
- maskLayer ? static_cast<WebLayerImpl*>(maskLayer)->layer() : nullptr);
-}
-
-void WebLayerImpl::SetOpacity(float opacity) {
- layer_->SetOpacity(opacity);
-}
-
-float WebLayerImpl::Opacity() const {
- return layer_->opacity();
-}
-
-void WebLayerImpl::SetBlendMode(blink::WebBlendMode blend_mode) {
- layer_->SetBlendMode(BlendModeToSkia(blend_mode));
-}
-
-blink::WebBlendMode WebLayerImpl::BlendMode() const {
- return BlendModeFromSkia(layer_->blend_mode());
-}
-
-void WebLayerImpl::SetIsRootForIsolatedGroup(bool isolate) {
- layer_->SetIsRootForIsolatedGroup(isolate);
-}
-
-bool WebLayerImpl::IsRootForIsolatedGroup() {
- return layer_->is_root_for_isolated_group();
-}
-
-void WebLayerImpl::SetHitTestableWithoutDrawsContent(bool should_hit_test) {
- layer_->SetHitTestableWithoutDrawsContent(should_hit_test);
-}
-
-void WebLayerImpl::SetOpaque(bool opaque) {
- if (contents_opaque_is_fixed_)
- return;
- layer_->SetContentsOpaque(opaque);
-}
-
-bool WebLayerImpl::Opaque() const {
- return layer_->contents_opaque();
-}
-
-void WebLayerImpl::SetPosition(const WebFloatPoint& position) {
- layer_->SetPosition(position);
-}
-
-WebFloatPoint WebLayerImpl::GetPosition() const {
- return layer_->position();
-}
-
-void WebLayerImpl::SetTransform(const SkMatrix44& matrix) {
- gfx::Transform transform;
- transform.matrix() = matrix;
- layer_->SetTransform(transform);
-}
-
-void WebLayerImpl::SetTransformOrigin(const blink::WebFloatPoint3D& point) {
- gfx::Point3F gfx_point = point;
- layer_->SetTransformOrigin(gfx_point);
-}
-
-blink::WebFloatPoint3D WebLayerImpl::TransformOrigin() const {
- return layer_->transform_origin();
-}
-
-SkMatrix44 WebLayerImpl::Transform() const {
- return layer_->transform().matrix();
-}
-
-void WebLayerImpl::SetDrawsContent(bool draws_content) {
- layer_->SetIsDrawable(draws_content);
-}
-
-bool WebLayerImpl::DrawsContent() const {
- return layer_->DrawsContent();
-}
-
-void WebLayerImpl::SetDoubleSided(bool double_sided) {
- layer_->SetDoubleSided(double_sided);
-}
-
-void WebLayerImpl::SetShouldFlattenTransform(bool flatten) {
- layer_->SetShouldFlattenTransform(flatten);
-}
-
-void WebLayerImpl::SetRenderingContext(int context) {
- layer_->Set3dSortingContextId(context);
-}
-
-void WebLayerImpl::SetUseParentBackfaceVisibility(
- bool use_parent_backface_visibility) {
- layer_->SetUseParentBackfaceVisibility(use_parent_backface_visibility);
-}
-
-void WebLayerImpl::SetBackgroundColor(WebColor color) {
- layer_->SetBackgroundColor(color);
-}
-
-WebColor WebLayerImpl::BackgroundColor() const {
- return layer_->background_color();
-}
-
-void WebLayerImpl::SetFilters(const cc::FilterOperations& filters) {
- layer_->SetFilters(filters);
-}
-
-void WebLayerImpl::SetFiltersOrigin(const blink::WebFloatPoint& origin) {
- layer_->SetFiltersOrigin(origin);
-}
-
-void WebLayerImpl::SetBackgroundFilters(const cc::FilterOperations& filters) {
- layer_->SetBackgroundFilters(filters);
-}
-
-bool WebLayerImpl::HasTickingAnimationForTesting() {
- return layer_->HasTickingAnimationForTesting();
-}
-
-void WebLayerImpl::SetScrollable(const blink::WebSize& size) {
- layer_->SetScrollable(size);
-}
-
-void WebLayerImpl::SetScrollPosition(blink::WebFloatPoint position) {
- layer_->SetScrollOffset(gfx::ScrollOffset(position.x, position.y));
-}
-
-blink::WebFloatPoint WebLayerImpl::ScrollPosition() const {
- return blink::WebFloatPoint(layer_->scroll_offset().x(),
- layer_->scroll_offset().y());
-}
-
-bool WebLayerImpl::Scrollable() const {
- return layer_->scrollable();
-}
-
-blink::WebSize WebLayerImpl::ScrollContainerBoundsForTesting() const {
- return layer_->scroll_container_bounds();
-}
-
-void WebLayerImpl::SetUserScrollable(bool horizontal, bool vertical) {
- layer_->SetUserScrollable(horizontal, vertical);
-}
-
-bool WebLayerImpl::UserScrollableHorizontal() const {
- return layer_->user_scrollable_horizontal();
-}
-
-bool WebLayerImpl::UserScrollableVertical() const {
- return layer_->user_scrollable_vertical();
-}
-
-void WebLayerImpl::AddMainThreadScrollingReasons(
- uint32_t main_thread_scrolling_reasons) {
- // WebLayerImpl should only know about non-transient scrolling
- // reasons. Transient scrolling reasons are computed per hit test.
- DCHECK(main_thread_scrolling_reasons);
- DCHECK(cc::MainThreadScrollingReason::MainThreadCanSetScrollReasons(
- main_thread_scrolling_reasons));
- layer_->AddMainThreadScrollingReasons(main_thread_scrolling_reasons);
-}
-
-void WebLayerImpl::ClearMainThreadScrollingReasons(
- uint32_t main_thread_scrolling_reasons_to_clear) {
- layer_->ClearMainThreadScrollingReasons(
- main_thread_scrolling_reasons_to_clear);
-}
-
-uint32_t WebLayerImpl::MainThreadScrollingReasons() {
- return layer_->main_thread_scrolling_reasons();
-}
-
-bool WebLayerImpl::ShouldScrollOnMainThread() const {
- return layer_->should_scroll_on_main_thread();
-}
-
-void WebLayerImpl::SetNonFastScrollableRegion(const WebVector<WebRect>& rects) {
- cc::Region region;
- for (size_t i = 0; i < rects.size(); ++i)
- region.Union(rects[i]);
- layer_->SetNonFastScrollableRegion(region);
-}
-
-WebVector<WebRect> WebLayerImpl::NonFastScrollableRegion() const {
- size_t num_rects = 0;
- for (gfx::Rect rect : layer_->non_fast_scrollable_region()) {
- ALLOW_UNUSED_LOCAL(rect);
- ++num_rects;
- }
-
- WebVector<WebRect> result(num_rects);
- size_t i = 0;
- for (gfx::Rect rect : layer_->non_fast_scrollable_region()) {
- result[i] = rect;
- ++i;
- }
- return result;
-}
-
-void WebLayerImpl::SetTouchEventHandlerRegion(
- const WebVector<blink::WebTouchInfo>& touch_info) {
- base::flat_map<blink::WebTouchAction, cc::Region> region_map;
- for (size_t i = 0; i < touch_info.size(); ++i)
- region_map[touch_info[i].touch_action].Union(touch_info[i].rect);
- layer_->SetTouchActionRegion(cc::TouchActionRegion(region_map));
-}
-
-WebVector<WebRect> WebLayerImpl::TouchEventHandlerRegion() const {
- size_t num_rects = 0;
- for (gfx::Rect rect : layer_->touch_action_region().region()) {
- ALLOW_UNUSED_LOCAL(rect);
- ++num_rects;
- }
-
- WebVector<WebRect> result(num_rects);
- size_t i = 0;
- for (gfx::Rect rect : layer_->touch_action_region().region()) {
- result[i] = rect;
- ++i;
- }
- return result;
-}
-
-WebVector<WebRect>
-WebLayerImpl::TouchEventHandlerRegionForTouchActionForTesting(
- cc::TouchAction touch_action) const {
- size_t num_rects = 0;
- for (gfx::Rect rect :
- layer_->touch_action_region().GetRegionForTouchAction(touch_action)) {
- ALLOW_UNUSED_LOCAL(rect);
- ++num_rects;
- }
-
- WebVector<WebRect> result(num_rects);
- size_t i = 0;
- for (gfx::Rect rect :
- layer_->touch_action_region().GetRegionForTouchAction(touch_action)) {
- result[i] = rect;
- ++i;
- }
- return result;
-}
-
-void WebLayerImpl::SetIsContainerForFixedPositionLayers(bool enable) {
- layer_->SetIsContainerForFixedPositionLayers(enable);
-}
-
-bool WebLayerImpl::IsContainerForFixedPositionLayers() const {
- return layer_->IsContainerForFixedPositionLayers();
-}
-
-void WebLayerImpl::SetIsResizedByBrowserControls(bool enable) {
- layer_->SetIsResizedByBrowserControls(enable);
-}
-
-static blink::WebLayerPositionConstraint ToWebLayerPositionConstraint(
- const cc::LayerPositionConstraint& constraint) {
- blink::WebLayerPositionConstraint web_constraint;
- web_constraint.is_fixed_position = constraint.is_fixed_position();
- web_constraint.is_fixed_to_right_edge = constraint.is_fixed_to_right_edge();
- web_constraint.is_fixed_to_bottom_edge = constraint.is_fixed_to_bottom_edge();
- return web_constraint;
-}
-
-static cc::LayerPositionConstraint ToLayerPositionConstraint(
- const blink::WebLayerPositionConstraint& web_constraint) {
- cc::LayerPositionConstraint constraint;
- constraint.set_is_fixed_position(web_constraint.is_fixed_position);
- constraint.set_is_fixed_to_right_edge(web_constraint.is_fixed_to_right_edge);
- constraint.set_is_fixed_to_bottom_edge(
- web_constraint.is_fixed_to_bottom_edge);
- return constraint;
-}
-
-void WebLayerImpl::SetPositionConstraint(
- const blink::WebLayerPositionConstraint& constraint) {
- layer_->SetPositionConstraint(ToLayerPositionConstraint(constraint));
-}
-
-blink::WebLayerPositionConstraint WebLayerImpl::PositionConstraint() const {
- return ToWebLayerPositionConstraint(layer_->position_constraint());
-}
-
-static blink::WebLayerStickyPositionConstraint
-ToWebLayerStickyPositionConstraint(
- const cc::LayerStickyPositionConstraint& constraint) {
- blink::WebLayerStickyPositionConstraint web_constraint;
- web_constraint.is_sticky = constraint.is_sticky;
- web_constraint.is_anchored_left = constraint.is_anchored_left;
- web_constraint.is_anchored_right = constraint.is_anchored_right;
- web_constraint.is_anchored_top = constraint.is_anchored_top;
- web_constraint.is_anchored_bottom = constraint.is_anchored_bottom;
- web_constraint.left_offset = constraint.left_offset;
- web_constraint.right_offset = constraint.right_offset;
- web_constraint.top_offset = constraint.top_offset;
- web_constraint.bottom_offset = constraint.bottom_offset;
- web_constraint.scroll_container_relative_sticky_box_rect =
- constraint.scroll_container_relative_sticky_box_rect;
- web_constraint.scroll_container_relative_containing_block_rect =
- constraint.scroll_container_relative_containing_block_rect;
- web_constraint.nearest_element_shifting_sticky_box =
- constraint.nearest_element_shifting_sticky_box;
- web_constraint.nearest_element_shifting_containing_block =
- constraint.nearest_element_shifting_containing_block;
- return web_constraint;
-}
-static cc::LayerStickyPositionConstraint ToStickyPositionConstraint(
- const blink::WebLayerStickyPositionConstraint& web_constraint) {
- cc::LayerStickyPositionConstraint constraint;
- constraint.is_sticky = web_constraint.is_sticky;
- constraint.is_anchored_left = web_constraint.is_anchored_left;
- constraint.is_anchored_right = web_constraint.is_anchored_right;
- constraint.is_anchored_top = web_constraint.is_anchored_top;
- constraint.is_anchored_bottom = web_constraint.is_anchored_bottom;
- constraint.left_offset = web_constraint.left_offset;
- constraint.right_offset = web_constraint.right_offset;
- constraint.top_offset = web_constraint.top_offset;
- constraint.bottom_offset = web_constraint.bottom_offset;
- constraint.scroll_container_relative_sticky_box_rect =
- web_constraint.scroll_container_relative_sticky_box_rect;
- constraint.scroll_container_relative_containing_block_rect =
- web_constraint.scroll_container_relative_containing_block_rect;
- constraint.nearest_element_shifting_sticky_box =
- web_constraint.nearest_element_shifting_sticky_box;
- constraint.nearest_element_shifting_containing_block =
- web_constraint.nearest_element_shifting_containing_block;
- return constraint;
-}
-void WebLayerImpl::SetStickyPositionConstraint(
- const blink::WebLayerStickyPositionConstraint& constraint) {
- layer_->SetStickyPositionConstraint(ToStickyPositionConstraint(constraint));
-}
-blink::WebLayerStickyPositionConstraint WebLayerImpl::StickyPositionConstraint()
- const {
- return ToWebLayerStickyPositionConstraint(
- layer_->sticky_position_constraint());
-}
-
-void WebLayerImpl::SetScrollClient(blink::WebLayerScrollClient* scroll_client) {
- if (scroll_client) {
- layer_->set_did_scroll_callback(
- base::Bind(&blink::WebLayerScrollClient::DidScroll,
- base::Unretained(scroll_client)));
- } else {
- layer_->set_did_scroll_callback(
- base::Callback<void(const gfx::ScrollOffset&, const cc::ElementId&)>());
- }
-}
-
-void WebLayerImpl::SetScrollOffsetFromImplSideForTesting(
- const gfx::ScrollOffset& offset) {
- layer_->SetScrollOffsetFromImplSide(offset);
-}
-
-void WebLayerImpl::SetLayerClient(base::WeakPtr<cc::LayerClient> client) {
- layer_->SetLayerClient(std::move(client));
-}
-
-const cc::Layer* WebLayerImpl::CcLayer() const {
- return layer_.get();
-}
-
-cc::Layer* WebLayerImpl::CcLayer() {
- return layer_.get();
-}
-
-void WebLayerImpl::SetElementId(const cc::ElementId& id) {
- layer_->SetElementId(id);
-}
-
-cc::ElementId WebLayerImpl::GetElementId() const {
- return layer_->element_id();
-}
-
-void WebLayerImpl::SetScrollParent(blink::WebLayer* parent) {
- cc::Layer* scroll_parent = nullptr;
- if (parent)
- scroll_parent = static_cast<WebLayerImpl*>(parent)->layer();
- layer_->SetScrollParent(scroll_parent);
-}
-
-void WebLayerImpl::SetClipParent(blink::WebLayer* parent) {
- cc::Layer* clip_parent = nullptr;
- if (parent)
- clip_parent = static_cast<WebLayerImpl*>(parent)->layer();
- layer_->SetClipParent(clip_parent);
-}
-
-Layer* WebLayerImpl::layer() const {
- return layer_.get();
-}
-
-void WebLayerImpl::SetContentsOpaqueIsFixed(bool fixed) {
- contents_opaque_is_fixed_ = fixed;
-}
-
-void WebLayerImpl::SetHasWillChangeTransformHint(bool has_will_change) {
- layer_->SetHasWillChangeTransformHint(has_will_change);
-}
-
-void WebLayerImpl::ShowScrollbars() {
- layer_->ShowScrollbars();
-}
-
-void WebLayerImpl::SetOverscrollBehavior(
- const blink::WebOverscrollBehavior& behavior) {
- layer_->SetOverscrollBehavior(static_cast<cc::OverscrollBehavior>(behavior));
-}
-
-void WebLayerImpl::SetSnapContainerData(
- base::Optional<cc::SnapContainerData> data) {
- layer_->SetSnapContainerData(std::move(data));
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_layer_impl.h b/chromium/cc/blink/web_layer_impl.h
deleted file mode 100644
index 9be421d303f..00000000000
--- a/chromium/cc/blink/web_layer_impl.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_LAYER_IMPL_H_
-#define CC_BLINK_WEB_LAYER_IMPL_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "cc/blink/cc_blink_export.h"
-#include "cc/layers/layer_client.h"
-#include "third_party/blink/public/platform/web_color.h"
-#include "third_party/blink/public/platform/web_double_point.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_size.h"
-#include "third_party/blink/public/platform/web_layer.h"
-#include "third_party/blink/public/platform/web_point.h"
-#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-
-namespace cc {
-class FilterOperations;
-class Layer;
-}
-
-namespace cc_blink {
-
-class CC_BLINK_EXPORT WebLayerImpl : public blink::WebLayer {
- public:
- WebLayerImpl();
- explicit WebLayerImpl(scoped_refptr<cc::Layer>);
- ~WebLayerImpl() override;
-
- cc::Layer* layer() const;
-
- // WebLayer implementation.
- int Id() const override;
- void InvalidateRect(const blink::WebRect&) override;
- void Invalidate() override;
- void AddChild(blink::WebLayer* child) override;
- void InsertChild(blink::WebLayer* child, size_t index) override;
- void ReplaceChild(blink::WebLayer* reference,
- blink::WebLayer* new_layer) override;
- void RemoveFromParent() override;
- void RemoveAllChildren() override;
- void SetBounds(const blink::WebSize& bounds) override;
- blink::WebSize Bounds() const override;
- void SetMasksToBounds(bool masks_to_bounds) override;
- bool MasksToBounds() const override;
- void SetMaskLayer(blink::WebLayer* mask) override;
- void SetOpacity(float opacity) override;
- float Opacity() const override;
- void SetContentsOpaqueIsFixed(bool fixed) override;
-
- void SetBlendMode(blink::WebBlendMode blend_mode) override;
- blink::WebBlendMode BlendMode() const override;
- void SetIsRootForIsolatedGroup(bool root) override;
- bool IsRootForIsolatedGroup() override;
- void SetHitTestableWithoutDrawsContent(bool should_hit_test) override;
- void SetOpaque(bool opaque) override;
- bool Opaque() const override;
- void SetPosition(const blink::WebFloatPoint& position) override;
- blink::WebFloatPoint GetPosition() const override;
- void SetTransform(const SkMatrix44& transform) override;
- void SetTransformOrigin(const blink::WebFloatPoint3D& point) override;
- blink::WebFloatPoint3D TransformOrigin() const override;
- SkMatrix44 Transform() const override;
- void SetDrawsContent(bool draws_content) override;
- bool DrawsContent() const override;
- void SetDoubleSided(bool double_sided) override;
- void SetShouldFlattenTransform(bool flatten) override;
- void SetRenderingContext(int context) override;
- void SetUseParentBackfaceVisibility(bool visible) override;
- void SetBackgroundColor(blink::WebColor color) override;
- blink::WebColor BackgroundColor() const override;
- void SetFilters(const cc::FilterOperations& filters) override;
- void SetFiltersOrigin(const blink::WebFloatPoint& origin) override;
- void SetBackgroundFilters(const cc::FilterOperations& filters) override;
- bool HasTickingAnimationForTesting() override;
- void SetScrollable(const blink::WebSize&) override;
- blink::WebSize ScrollContainerBoundsForTesting() const override;
- void SetScrollPosition(blink::WebFloatPoint position) override;
- blink::WebFloatPoint ScrollPosition() const override;
- bool Scrollable() const override;
- void SetUserScrollable(bool horizontal, bool vertical) override;
- bool UserScrollableHorizontal() const override;
- bool UserScrollableVertical() const override;
- void AddMainThreadScrollingReasons(
- uint32_t main_thread_scrolling_reasons) override;
- void ClearMainThreadScrollingReasons(
- uint32_t main_thread_scrolling_reasons_to_clear) override;
- uint32_t MainThreadScrollingReasons() override;
- bool ShouldScrollOnMainThread() const override;
- void SetNonFastScrollableRegion(
- const blink::WebVector<blink::WebRect>& region) override;
- blink::WebVector<blink::WebRect> NonFastScrollableRegion() const override;
- void SetTouchEventHandlerRegion(
- const blink::WebVector<blink::WebTouchInfo>& touch_info) override;
- blink::WebVector<blink::WebRect> TouchEventHandlerRegion() const override;
- blink::WebVector<blink::WebRect>
- TouchEventHandlerRegionForTouchActionForTesting(
- cc::TouchAction) const override;
- void SetIsContainerForFixedPositionLayers(bool is_container) override;
- bool IsContainerForFixedPositionLayers() const override;
- void SetIsResizedByBrowserControls(bool) override;
- void SetPositionConstraint(
- const blink::WebLayerPositionConstraint& constraint) override;
- blink::WebLayerPositionConstraint PositionConstraint() const override;
- void SetStickyPositionConstraint(
- const blink::WebLayerStickyPositionConstraint& constraint) override;
- blink::WebLayerStickyPositionConstraint StickyPositionConstraint()
- const override;
- void SetScrollClient(blink::WebLayerScrollClient* client) override;
- void SetScrollOffsetFromImplSideForTesting(const gfx::ScrollOffset&) override;
- void SetLayerClient(base::WeakPtr<cc::LayerClient> client) override;
- const cc::Layer* CcLayer() const override;
- cc::Layer* CcLayer() override;
- void SetElementId(const cc::ElementId&) override;
- cc::ElementId GetElementId() const override;
- void SetHasWillChangeTransformHint(bool has_will_change) override;
- void ShowScrollbars() override;
- void SetOverscrollBehavior(const blink::WebOverscrollBehavior&) override;
- void SetSnapContainerData(base::Optional<cc::SnapContainerData>) override;
-
- void SetScrollParent(blink::WebLayer* parent) override;
- void SetClipParent(blink::WebLayer* parent) override;
-
- protected:
- scoped_refptr<cc::Layer> layer_;
-
- bool contents_opaque_is_fixed_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WebLayerImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_LAYER_IMPL_H_
diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds.cc b/chromium/cc/blink/web_layer_impl_fixed_bounds.cc
deleted file mode 100644
index dc6b90993c4..00000000000
--- a/chromium/cc/blink/web_layer_impl_fixed_bounds.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_layer_impl_fixed_bounds.h"
-
-#include "cc/layers/layer.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-
-using cc::Layer;
-
-namespace cc_blink {
-
-WebLayerImplFixedBounds::WebLayerImplFixedBounds() = default;
-
-WebLayerImplFixedBounds::WebLayerImplFixedBounds(scoped_refptr<Layer> layer)
- : WebLayerImpl(layer) {
-}
-
-WebLayerImplFixedBounds::~WebLayerImplFixedBounds() = default;
-
-void WebLayerImplFixedBounds::InvalidateRect(const blink::WebRect& rect) {
- // Partial invalidations seldom occur for such layers.
- // Simply invalidate the whole layer to avoid transformation of coordinates.
- Invalidate();
-}
-
-void WebLayerImplFixedBounds::SetTransformOrigin(
- const blink::WebFloatPoint3D& transform_origin) {
- if (transform_origin != this->TransformOrigin()) {
- layer_->SetTransformOrigin(transform_origin);
- UpdateLayerBoundsAndTransform();
- }
-}
-
-void WebLayerImplFixedBounds::SetBounds(const blink::WebSize& bounds) {
- if (original_bounds_ != gfx::Size(bounds)) {
- original_bounds_ = bounds;
- UpdateLayerBoundsAndTransform();
- }
-}
-
-blink::WebSize WebLayerImplFixedBounds::Bounds() const {
- return original_bounds_;
-}
-
-void WebLayerImplFixedBounds::SetTransform(const SkMatrix44& matrix) {
- gfx::Transform transform;
- transform.matrix() = matrix;
- SetTransformInternal(transform);
-}
-
-SkMatrix44 WebLayerImplFixedBounds::Transform() const {
- return original_transform_.matrix();
-}
-
-void WebLayerImplFixedBounds::SetFixedBounds(gfx::Size fixed_bounds) {
- if (fixed_bounds_ != fixed_bounds) {
- fixed_bounds_ = fixed_bounds;
- UpdateLayerBoundsAndTransform();
- }
-}
-
-void WebLayerImplFixedBounds::SetTransformInternal(
- const gfx::Transform& transform) {
- if (original_transform_ != transform) {
- original_transform_ = transform;
- UpdateLayerBoundsAndTransform();
- }
-}
-
-void WebLayerImplFixedBounds::UpdateLayerBoundsAndTransform() {
- if (fixed_bounds_.IsEmpty() || original_bounds_.IsEmpty() ||
- fixed_bounds_ == original_bounds_ ||
- // For now fall back to non-fixed bounds for non-zero transform origin.
- // TODO(wangxianzhu): Support non-zero anchor point for fixed bounds.
- TransformOrigin().x || TransformOrigin().y) {
- layer_->SetBounds(original_bounds_);
- layer_->SetTransform(original_transform_);
- return;
- }
-
- layer_->SetBounds(fixed_bounds_);
-
- // Apply bounds scale (bounds/fixed_bounds) over original transform.
- gfx::Transform transform_with_bounds_scale(original_transform_);
- float bounds_scale_x =
- static_cast<float>(original_bounds_.width()) / fixed_bounds_.width();
- float bounds_scale_y =
- static_cast<float>(original_bounds_.height()) / fixed_bounds_.height();
- transform_with_bounds_scale.Scale(bounds_scale_x, bounds_scale_y);
- layer_->SetTransform(transform_with_bounds_scale);
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds.h b/chromium/cc/blink/web_layer_impl_fixed_bounds.h
deleted file mode 100644
index 949e47d5434..00000000000
--- a/chromium/cc/blink/web_layer_impl_fixed_bounds.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_LAYER_IMPL_FIXED_BOUNDS_H_
-#define CC_BLINK_WEB_LAYER_IMPL_FIXED_BOUNDS_H_
-
-#include "base/macros.h"
-#include "cc/blink/web_layer_impl.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/transform.h"
-
-namespace cc_blink {
-
-// A special implementation of WebLayerImpl for layers that its contents
-// need to be automatically scaled when the bounds changes. The compositor
-// can efficiently handle the bounds change of such layers if the bounds
-// is fixed to a given value and the change of bounds are converted to
-// transformation scales.
-class CC_BLINK_EXPORT WebLayerImplFixedBounds : public WebLayerImpl {
- public:
- WebLayerImplFixedBounds();
- explicit WebLayerImplFixedBounds(scoped_refptr<cc::Layer> layer);
- ~WebLayerImplFixedBounds() override;
-
- // WebLayerImpl overrides.
- void InvalidateRect(const blink::WebRect& rect) override;
- void SetTransformOrigin(
- const blink::WebFloatPoint3D& transform_origin) override;
- void SetBounds(const blink::WebSize& bounds) override;
- blink::WebSize Bounds() const override;
- void SetTransform(const SkMatrix44& transform) override;
- SkMatrix44 Transform() const override;
-
- void SetFixedBounds(gfx::Size bounds);
-
- protected:
- void SetTransformInternal(const gfx::Transform& transform);
- void UpdateLayerBoundsAndTransform();
-
- gfx::Transform original_transform_;
- gfx::Size original_bounds_;
- gfx::Size fixed_bounds_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WebLayerImplFixedBounds);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_LAYER_IMPL_FIXED_BOUNDS_H_
diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
deleted file mode 100644
index 354326e36aa..00000000000
--- a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_layer_impl_fixed_bounds.h"
-#include <vector>
-#include "cc/animation/animation_host.h"
-#include "cc/layers/picture_image_layer.h"
-#include "cc/test/fake_layer_tree_host.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/test_task_graph_runner.h"
-#include "cc/trees/layer_tree_host_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-#include "ui/gfx/geometry/point3_f.h"
-
-using blink::WebFloatPoint;
-using blink::WebSize;
-
-namespace cc_blink {
-namespace {
-
-TEST(WebLayerImplFixedBoundsTest, IdentityBounds) {
- WebLayerImplFixedBounds layer;
- layer.SetFixedBounds(gfx::Size(100, 100));
- layer.SetBounds(WebSize(100, 100));
- EXPECT_EQ(WebSize(100, 100), layer.Bounds());
- EXPECT_EQ(gfx::Size(100, 100), layer.layer()->bounds());
- EXPECT_EQ(gfx::Transform(), layer.layer()->transform());
-}
-
-gfx::Point3F TransformPoint(const gfx::Transform& transform,
- const gfx::Point3F& point) {
- gfx::Point3F result = point;
- transform.TransformPoint(&result);
- return result;
-}
-
-void CheckBoundsScaleSimple(WebLayerImplFixedBounds* layer,
- const WebSize& bounds,
- const gfx::Size& fixed_bounds) {
- layer->SetBounds(bounds);
- layer->SetFixedBounds(fixed_bounds);
-
- EXPECT_EQ(bounds, layer->Bounds());
- EXPECT_EQ(fixed_bounds, layer->layer()->bounds());
- EXPECT_TRUE(layer->Transform().isIdentity());
-
- // An arbitrary point to check the scale and transforms.
- gfx::Point3F original_point(10, 20, 1);
- gfx::Point3F scaled_point(
- original_point.x() * bounds.width / fixed_bounds.width(),
- original_point.y() * bounds.height / fixed_bounds.height(),
- original_point.z());
- // Test if the bounds scale is correctly applied in transform.
- EXPECT_POINT3F_EQ(scaled_point, TransformPoint(layer->layer()->transform(),
- original_point));
-}
-
-TEST(WebLayerImplFixedBoundsTest, BoundsScaleSimple) {
- WebLayerImplFixedBounds layer;
- CheckBoundsScaleSimple(&layer, WebSize(100, 200), gfx::Size(150, 250));
- // Change fixed_bounds.
- CheckBoundsScaleSimple(&layer, WebSize(100, 200), gfx::Size(75, 100));
- // Change bounds.
- CheckBoundsScaleSimple(&layer, WebSize(300, 100), gfx::Size(75, 100));
-}
-
-void ExpectEqualLayerRectsInTarget(cc::Layer* layer1, cc::Layer* layer2) {
- gfx::RectF layer1_rect_in_target(gfx::SizeF(layer1->bounds()));
- layer1->ScreenSpaceTransform().TransformRect(&layer1_rect_in_target);
-
- gfx::RectF layer2_rect_in_target(gfx::SizeF(layer2->bounds()));
- layer2->ScreenSpaceTransform().TransformRect(&layer2_rect_in_target);
-
- EXPECT_FLOAT_RECT_EQ(layer1_rect_in_target, layer2_rect_in_target);
-}
-
-void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point,
- const gfx::Transform& transform) {
- const gfx::Size kDeviceViewportSize(800, 600);
- const float kDeviceScaleFactor = 2.f;
- const float kPageScaleFactor = 1.5f;
-
- WebSize bounds(150, 200);
- WebFloatPoint position(20, 30);
- gfx::Size fixed_bounds(160, 70);
-
- WebLayerImplFixedBounds root_layer;
-
- WebLayerImplFixedBounds fixed_bounds_layer(cc::PictureImageLayer::Create());
- fixed_bounds_layer.SetBounds(bounds);
- fixed_bounds_layer.SetFixedBounds(fixed_bounds);
- fixed_bounds_layer.SetTransform(transform.matrix());
- fixed_bounds_layer.SetPosition(position);
- root_layer.AddChild(&fixed_bounds_layer);
-
- WebLayerImpl normal_layer(cc::PictureImageLayer::Create());
-
- normal_layer.SetBounds(bounds);
- normal_layer.SetTransform(transform.matrix());
- normal_layer.SetPosition(position);
- root_layer.AddChild(&normal_layer);
-
- auto animation_host =
- cc::AnimationHost::CreateForTesting(cc::ThreadInstance::MAIN);
-
- cc::FakeLayerTreeHostClient client;
- cc::TestTaskGraphRunner task_graph_runner;
- std::unique_ptr<cc::FakeLayerTreeHost> host = cc::FakeLayerTreeHost::Create(
- &client, &task_graph_runner, animation_host.get());
- host->SetRootLayer(root_layer.layer());
-
- {
- cc::LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root_layer.layer(), kDeviceViewportSize);
- inputs.device_scale_factor = kDeviceScaleFactor;
- inputs.page_scale_factor = kPageScaleFactor;
- inputs.page_scale_layer = root_layer.layer(),
- cc::LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
-
- ExpectEqualLayerRectsInTarget(normal_layer.layer(),
- fixed_bounds_layer.layer());
- }
-
- // Change of fixed bounds should not affect the target geometries.
- fixed_bounds_layer.SetFixedBounds(
- gfx::Size(fixed_bounds.width() / 2, fixed_bounds.height() * 2));
-
- {
- cc::LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root_layer.layer(), kDeviceViewportSize);
- inputs.device_scale_factor = kDeviceScaleFactor;
- inputs.page_scale_factor = kPageScaleFactor;
- inputs.page_scale_layer = root_layer.layer(),
- cc::LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
-
- ExpectEqualLayerRectsInTarget(normal_layer.layer(),
- fixed_bounds_layer.layer());
- }
-}
-
-// TODO(perkj): CompareToWebLayerImplSimple disabled on LSAN due to crbug/386080
-#if defined(LEAK_SANITIZER)
-#define MAYBE_CompareToWebLayerImplSimple DISABLED_CompareToWebLayerImplSimple
-#else
-#define MAYBE_CompareToWebLayerImplSimple CompareToWebLayerImplSimple
-#endif
-// A black box test that ensures WebLayerImplFixedBounds won't change target
-// geometries. Simple case: identity transforms and zero anchor point.
-TEST(WebLayerImplFixedBoundsTest, MAYBE_CompareToWebLayerImplSimple) {
- CompareFixedBoundsLayerAndNormalLayer(WebFloatPoint(0, 0), gfx::Transform());
-}
-
-// TODO(perkj): CompareToWebLayerImplComplex disabled on LSAN due to
-// crbug/386080
-#if defined(LEAK_SANITIZER)
-#define MAYBE_CompareToWebLayerImplComplex DISABLED_CompareToWebLayerImplComplex
-#else
-#define MAYBE_CompareToWebLayerImplComplex CompareToWebLayerImplComplex
-#endif
-// A black box test that ensures WebLayerImplFixedBounds won't change target
-// geometries. Complex case: complex transforms and non-zero anchor point.
-TEST(WebLayerImplFixedBoundsTest, MAYBE_CompareToWebLayerImplComplex) {
- gfx::Transform transform;
- // These are arbitrary values that should not affect the results.
- transform.Translate3d(50, 60, 70);
- transform.Scale3d(2, 3, 4);
- transform.RotateAbout(gfx::Vector3dF(33, 44, 55), 99);
-
- CompareFixedBoundsLayerAndNormalLayer(WebFloatPoint(0, 0), transform);
-
- // With non-zero anchor point, WebLayerImplFixedBounds will fall back to
- // WebLayerImpl.
- CompareFixedBoundsLayerAndNormalLayer(WebFloatPoint(0.4f, 0.6f), transform);
-}
-
-} // namespace
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.cc b/chromium/cc/blink/web_scrollbar_layer_impl.cc
deleted file mode 100644
index f501002d486..00000000000
--- a/chromium/cc/blink/web_scrollbar_layer_impl.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/blink/web_scrollbar_layer_impl.h"
-
-#include <utility>
-
-#include "cc/blink/scrollbar_impl.h"
-#include "cc/blink/web_layer_impl.h"
-#include "cc/layers/layer.h"
-#include "cc/layers/painted_overlay_scrollbar_layer.h"
-#include "cc/layers/painted_scrollbar_layer.h"
-#include "cc/layers/scrollbar_layer_interface.h"
-#include "cc/layers/solid_color_scrollbar_layer.h"
-#include "cc/trees/element_id.h"
-
-using cc::PaintedOverlayScrollbarLayer;
-using cc::PaintedScrollbarLayer;
-using cc::SolidColorScrollbarLayer;
-
-namespace {
-
-cc::ScrollbarOrientation ConvertOrientation(
- blink::WebScrollbar::Orientation orientation) {
- return orientation == blink::WebScrollbar::kHorizontal ? cc::HORIZONTAL
- : cc::VERTICAL;
-}
-
-} // namespace
-
-namespace cc_blink {
-
-WebScrollbarLayerImpl::WebScrollbarLayerImpl(
- std::unique_ptr<blink::WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry,
- bool is_overlay)
- : layer_(is_overlay
- ? new WebLayerImpl(PaintedOverlayScrollbarLayer::Create(
- std::make_unique<ScrollbarImpl>(std::move(scrollbar),
- painter,
- std::move(geometry)),
- cc::ElementId()))
- : new WebLayerImpl(PaintedScrollbarLayer::Create(
- std::make_unique<ScrollbarImpl>(std::move(scrollbar),
- painter,
- std::move(geometry)),
- cc::ElementId()))) {}
-
-WebScrollbarLayerImpl::WebScrollbarLayerImpl(
- blink::WebScrollbar::Orientation orientation,
- int thumb_thickness,
- int track_start,
- bool is_left_side_vertical_scrollbar)
- : layer_(new WebLayerImpl(
- SolidColorScrollbarLayer::Create(ConvertOrientation(orientation),
- thumb_thickness,
- track_start,
- is_left_side_vertical_scrollbar,
- cc::ElementId()))) {}
-
-WebScrollbarLayerImpl::~WebScrollbarLayerImpl() = default;
-
-blink::WebLayer* WebScrollbarLayerImpl::Layer() {
- return layer_.get();
-}
-
-void WebScrollbarLayerImpl::SetScrollLayer(blink::WebLayer* layer) {
- cc::Layer* scroll_layer =
- layer ? static_cast<WebLayerImpl*>(layer)->layer() : nullptr;
- layer_->layer()->ToScrollbarLayer()->SetScrollElementId(
- scroll_layer ? scroll_layer->element_id() : cc::ElementId());
-}
-
-void WebScrollbarLayerImpl::SetElementId(const cc::ElementId& element_id) {
- layer_->SetElementId(element_id);
-}
-
-} // namespace cc_blink
diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.h b/chromium/cc/blink/web_scrollbar_layer_impl.h
deleted file mode 100644
index c80c31df230..00000000000
--- a/chromium/cc/blink/web_scrollbar_layer_impl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BLINK_WEB_SCROLLBAR_LAYER_IMPL_H_
-#define CC_BLINK_WEB_SCROLLBAR_LAYER_IMPL_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "cc/blink/cc_blink_export.h"
-#include "third_party/blink/public/platform/web_scrollbar.h"
-#include "third_party/blink/public/platform/web_scrollbar_layer.h"
-
-namespace blink {
-class WebScrollbarThemeGeometry;
-class WebScrollbarThemePainter;
-}
-
-namespace cc_blink {
-
-class WebLayerImpl;
-
-class WebScrollbarLayerImpl : public blink::WebScrollbarLayer {
- public:
- CC_BLINK_EXPORT WebScrollbarLayerImpl(
- std::unique_ptr<blink::WebScrollbar> scrollbar,
- blink::WebScrollbarThemePainter painter,
- std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry,
- bool is_overlay);
- CC_BLINK_EXPORT WebScrollbarLayerImpl(
- blink::WebScrollbar::Orientation orientation,
- int thumb_thickness,
- int track_start,
- bool is_left_side_vertical_scrollbar);
- ~WebScrollbarLayerImpl() override;
-
- // blink::WebScrollbarLayer implementation.
- blink::WebLayer* Layer() override;
- void SetScrollLayer(blink::WebLayer* layer) override;
-
- void SetElementId(const cc::ElementId&) override;
-
- private:
- std::unique_ptr<WebLayerImpl> layer_;
-
- DISALLOW_COPY_AND_ASSIGN(WebScrollbarLayerImpl);
-};
-
-} // namespace cc_blink
-
-#endif // CC_BLINK_WEB_SCROLLBAR_LAYER_IMPL_H_
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index 312f103e941..51bc8f74b94 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -50,8 +50,10 @@ struct CC_EXPORT InputHandlerScrollResult {
// property scroll-boundary-behavior.
OverscrollBehavior overscroll_behavior;
// The current offset of the currently scrolling node. It is in DIP or
- // physical pixels depending on the use-zoom-for-dsf flag.
- gfx::Vector2dF current_offset;
+ // physical pixels depending on the use-zoom-for-dsf flag. If the currently
+ // scrolling node is the viewport, this would be the sum of the scroll offsets
+ // of the inner and outer node, representing the visual scroll offset.
+ gfx::Vector2dF current_visual_offset;
};
class CC_EXPORT InputHandlerClient {
diff --git a/chromium/cc/input/main_thread_scrolling_reason.cc b/chromium/cc/input/main_thread_scrolling_reason.cc
new file mode 100644
index 00000000000..6653ac98fde
--- /dev/null
+++ b/chromium/cc/input/main_thread_scrolling_reason.cc
@@ -0,0 +1,78 @@
+// 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/main_thread_scrolling_reason.h"
+
+#include "base/stl_util.h"
+#include "base/trace_event/trace_event_argument.h"
+
+namespace cc {
+
+std::string MainThreadScrollingReason::AsText(uint32_t reasons) {
+ base::trace_event::TracedValue traced_value;
+ AddToTracedValue(reasons, traced_value);
+ std::string result = traced_value.ToString();
+ // Remove '{main_thread_scrolling_reasons:[', ']}', and any '"' chars.
+ size_t array_start_pos = result.find('[');
+ size_t array_end_pos = result.find(']');
+ result =
+ result.substr(array_start_pos + 1, array_end_pos - array_start_pos - 1);
+ base::Erase(result, '\"');
+ return result;
+}
+
+void MainThreadScrollingReason::AddToTracedValue(
+ uint32_t reasons,
+ base::trace_event::TracedValue& traced_value) {
+ traced_value.BeginArray("main_thread_scrolling_reasons");
+
+ if (reasons & kHasBackgroundAttachmentFixedObjects)
+ traced_value.AppendString("Has background-attachment:fixed");
+ if (reasons & kHasNonLayerViewportConstrainedObjects)
+ traced_value.AppendString("Has non-layer viewport-constrained objects");
+ if (reasons & kThreadedScrollingDisabled)
+ traced_value.AppendString("Threaded scrolling is disabled");
+ if (reasons & kScrollbarScrolling)
+ traced_value.AppendString("Scrollbar scrolling");
+ if (reasons & kPageOverlay)
+ traced_value.AppendString("Page overlay");
+ if (reasons & kHandlingScrollFromMainThread)
+ traced_value.AppendString("Handling scroll from main thread");
+ if (reasons & kCustomScrollbarScrolling)
+ traced_value.AppendString("Custom scrollbar scrolling");
+ if (reasons & kHasOpacityAndLCDText)
+ traced_value.AppendString("Has opacity and LCD text");
+ if (reasons & kHasTransformAndLCDText)
+ 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)
+ traced_value.AppendString("Has box shadow from non-root layer");
+ if (reasons & kIsNotStackingContextAndLCDText)
+ traced_value.AppendString("Is not stacking context and LCD text");
+
+ // Transient scrolling reasons.
+ if (reasons & kNonFastScrollableRegion)
+ traced_value.AppendString("Non fast scrollable region");
+ if (reasons & kFailedHitTest)
+ traced_value.AppendString("Failed hit test");
+ if (reasons & kNoScrollingLayer)
+ traced_value.AppendString("No scrolling layer");
+ if (reasons & kNotScrollable)
+ traced_value.AppendString("Not scrollable");
+ if (reasons & kContinuingMainThreadScroll)
+ traced_value.AppendString("Continuing main thread scroll");
+ if (reasons & kNonInvertibleTransform)
+ traced_value.AppendString("Non-invertible transform");
+ if (reasons & kPageBasedScrolling)
+ traced_value.AppendString("Page-based scrolling");
+
+ traced_value.EndArray();
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/main_thread_scrolling_reason.h b/chromium/cc/input/main_thread_scrolling_reason.h
index e7d88471aff..b926c75117d 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.h
+++ b/chromium/cc/input/main_thread_scrolling_reason.h
@@ -5,17 +5,22 @@
#ifndef CC_INPUT_MAIN_THREAD_SCROLLING_REASON_H_
#define CC_INPUT_MAIN_THREAD_SCROLLING_REASON_H_
+#include <memory>
#include <string>
+#include "cc/cc_export.h"
-#include "base/stl_util.h"
-#include "base/trace_event/trace_event_argument.h"
+namespace base {
+namespace trace_event {
+class TracedValue;
+}
+} // namespace base
namespace cc {
// Ensure this stays in sync with MainThreadScrollingReason in histograms.xml.
// When adding a new MainThreadScrollingReason, make sure the corresponding
// [MainThread/Compositor]CanSetScrollReasons function is also updated.
-struct MainThreadScrollingReason {
+struct CC_EXPORT MainThreadScrollingReason {
enum : uint32_t {
// Non-transient scrolling reasons.
kNotScrollingOnMain = 0,
@@ -96,72 +101,9 @@ struct MainThreadScrollingReason {
return (reasons & kNonCompositedReasons) != 0;
}
- static std::string mainThreadScrollingReasonsAsText(uint32_t reasons) {
- base::trace_event::TracedValue tracedValue;
- mainThreadScrollingReasonsAsTracedValue(reasons, &tracedValue);
- std::string result_in_array_foramt = tracedValue.ToString();
- // Remove '{main_thread_scrolling_reasons:[', ']}', and any '"' chars.
- std::string result =
- result_in_array_foramt.substr(34, result_in_array_foramt.length() - 36);
- base::Erase(result, '\"');
- return result;
- }
-
- static void mainThreadScrollingReasonsAsTracedValue(
- uint32_t reasons,
- base::trace_event::TracedValue* tracedValue) {
- tracedValue->BeginArray("main_thread_scrolling_reasons");
- if (reasons &
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)
- tracedValue->AppendString("Has background-attachment:fixed");
- if (reasons &
- MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects)
- tracedValue->AppendString("Has non-layer viewport-constrained objects");
- if (reasons & MainThreadScrollingReason::kThreadedScrollingDisabled)
- tracedValue->AppendString("Threaded scrolling is disabled");
- if (reasons & MainThreadScrollingReason::kScrollbarScrolling)
- tracedValue->AppendString("Scrollbar scrolling");
- if (reasons & MainThreadScrollingReason::kPageOverlay)
- tracedValue->AppendString("Page overlay");
- if (reasons & MainThreadScrollingReason::kHandlingScrollFromMainThread)
- tracedValue->AppendString("Handling scroll from main thread");
- if (reasons & MainThreadScrollingReason::kCustomScrollbarScrolling)
- tracedValue->AppendString("Custom scrollbar scrolling");
- if (reasons & MainThreadScrollingReason::kHasOpacityAndLCDText)
- tracedValue->AppendString("Has opacity and LCD text");
- if (reasons & MainThreadScrollingReason::kHasTransformAndLCDText)
- tracedValue->AppendString("Has transform and LCD text");
- if (reasons &
- MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText) {
- tracedValue->AppendString(
- "Background is not opaque in rect and LCD text");
- }
- if (reasons & MainThreadScrollingReason::kHasBorderRadius)
- tracedValue->AppendString("Has border radius");
- if (reasons & MainThreadScrollingReason::kHasClipRelatedProperty)
- tracedValue->AppendString("Has clip related property");
- if (reasons & MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer)
- tracedValue->AppendString("Has box shadow from non-root layer");
- if (reasons & MainThreadScrollingReason::kIsNotStackingContextAndLCDText)
- tracedValue->AppendString("Is not stacking context and LCD text");
-
- // Transient scrolling reasons.
- if (reasons & MainThreadScrollingReason::kNonFastScrollableRegion)
- tracedValue->AppendString("Non fast scrollable region");
- if (reasons & MainThreadScrollingReason::kFailedHitTest)
- tracedValue->AppendString("Failed hit test");
- if (reasons & MainThreadScrollingReason::kNoScrollingLayer)
- tracedValue->AppendString("No scrolling layer");
- if (reasons & MainThreadScrollingReason::kNotScrollable)
- tracedValue->AppendString("Not scrollable");
- if (reasons & MainThreadScrollingReason::kContinuingMainThreadScroll)
- tracedValue->AppendString("Continuing main thread scroll");
- if (reasons & MainThreadScrollingReason::kNonInvertibleTransform)
- tracedValue->AppendString("Non-invertible transform");
- if (reasons & MainThreadScrollingReason::kPageBasedScrolling)
- tracedValue->AppendString("Page-based scrolling");
- tracedValue->EndArray();
- }
+ static std::string AsText(uint32_t reasons);
+ static void AddToTracedValue(uint32_t reasons,
+ base::trace_event::TracedValue&);
};
} // namespace cc
diff --git a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
new file mode 100644
index 00000000000..ec49ff98001
--- /dev/null
+++ b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
@@ -0,0 +1,38 @@
+// 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/main_thread_scrolling_reason.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+using MainThreadScrollingReasonTest = testing::Test;
+
+TEST_F(MainThreadScrollingReasonTest, AsText) {
+ EXPECT_EQ("", MainThreadScrollingReason::AsText(0));
+ EXPECT_EQ(
+ "Has background-attachment:fixed,"
+ "Has non-layer viewport-constrained objects,"
+ "Threaded scrolling is disabled,"
+ "Scrollbar scrolling,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 box shadow from non-root layer,"
+ "Is not stacking context and LCD text,"
+ "Non fast scrollable region,"
+ "Failed hit test,"
+ "No scrolling layer,"
+ "Not scrollable,"
+ "Continuing main thread scroll,"
+ "Non-invertible transform,"
+ "Page-based scrolling",
+ MainThreadScrollingReason::AsText(0xffffffffu));
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/scrollbar_animation_controller_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
index 9749fc77148..e9f336ff695 100644
--- a/chromium/cc/input/scrollbar_animation_controller_unittest.cc
+++ b/chromium/cc/input/scrollbar_animation_controller_unittest.cc
@@ -35,7 +35,7 @@ class MockScrollbarAnimationControllerClient
public:
explicit MockScrollbarAnimationControllerClient(LayerTreeHostImpl* host_impl)
: host_impl_(host_impl) {}
- virtual ~MockScrollbarAnimationControllerClient() = default;
+ ~MockScrollbarAnimationControllerClient() override = default;
void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
base::TimeDelta delay) override {
diff --git a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
index b883b1d0c17..08ba96d79b5 100644
--- a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
+++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
@@ -35,7 +35,7 @@ class MockSingleScrollbarAnimationControllerClient
explicit MockSingleScrollbarAnimationControllerClient(
LayerTreeHostImpl* host_impl)
: host_impl_(host_impl) {}
- virtual ~MockSingleScrollbarAnimationControllerClient() = default;
+ ~MockSingleScrollbarAnimationControllerClient() override = default;
ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override {
return host_impl_->ScrollbarsFor(scroll_element_id);
diff --git a/chromium/cc/input/snap_fling_controller.cc b/chromium/cc/input/snap_fling_controller.cc
new file mode 100644
index 00000000000..4c8e485bcff
--- /dev/null
+++ b/chromium/cc/input/snap_fling_controller.cc
@@ -0,0 +1,92 @@
+// 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_fling_controller.h"
+
+#include "cc/input/snap_fling_curve.h"
+
+namespace cc {
+
+SnapFlingController::SnapFlingController(SnapFlingClient* client)
+ : client_(client), state_(State::kIdle) {}
+
+SnapFlingController::~SnapFlingController() = default;
+
+bool SnapFlingController::FilterEventForSnap(
+ SnapFlingController::GestureScrollType gesture_scroll_type) {
+ switch (gesture_scroll_type) {
+ case GestureScrollType::kBegin: {
+ ClearSnapFling();
+ return false;
+ }
+ // TODO(sunyunjia): Need to update the existing snap curve if the GSU is
+ // from a fling boosting event.
+ case GestureScrollType::kUpdate:
+ case GestureScrollType::kEnd: {
+ return state_ == State::kActive || state_ == State::kFinished;
+ }
+ }
+}
+
+void SnapFlingController::ClearSnapFling() {
+ if (state_ == State::kActive)
+ client_->ScrollEndForSnapFling();
+
+ curve_.reset();
+ state_ = State::kIdle;
+}
+
+bool SnapFlingController::HandleGestureScrollUpdate(
+ const SnapFlingController::GestureScrollUpdateInfo& info) {
+ DCHECK(state_ != State::kActive && state_ != State::kFinished);
+ if (state_ != State::kIdle)
+ return false;
+
+ if (!info.is_in_inertial_phase)
+ return false;
+
+ gfx::Vector2dF ending_displacement =
+ SnapFlingCurve::EstimateDisplacement(info.delta);
+
+ gfx::Vector2dF target_offset, start_offset;
+ if (!client_->GetSnapFlingInfo(ending_displacement, &start_offset,
+ &target_offset)) {
+ state_ = State::kIgnored;
+ return false;
+ }
+
+ if (start_offset == target_offset) {
+ state_ = State::kFinished;
+ return true;
+ }
+
+ curve_ = std::make_unique<SnapFlingCurve>(start_offset, target_offset,
+ info.event_time);
+ state_ = State::kActive;
+ Animate(info.event_time);
+ return true;
+}
+
+void SnapFlingController::Animate(base::TimeTicks time) {
+ if (state_ != State::kActive)
+ return;
+
+ if (curve_->IsFinished()) {
+ client_->ScrollEndForSnapFling();
+ state_ = State::kFinished;
+ return;
+ }
+ gfx::Vector2dF snapped_delta = curve_->GetScrollDelta(time);
+ gfx::Vector2dF current_offset = client_->ScrollByForSnapFling(snapped_delta);
+ curve_->UpdateCurrentOffset(current_offset);
+ client_->RequestAnimationForSnapFling();
+}
+
+void SnapFlingController::SetCurveForTest(
+ std::unique_ptr<SnapFlingCurve> curve) {
+ curve_ = std::move(curve);
+ state_ = State::kActive;
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/snap_fling_controller.h b/chromium/cc/input/snap_fling_controller.h
new file mode 100644
index 00000000000..5199b23faa6
--- /dev/null
+++ b/chromium/cc/input/snap_fling_controller.h
@@ -0,0 +1,106 @@
+// 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_FLING_CONTROLLER_H_
+#define CC_INPUT_SNAP_FLING_CONTROLLER_H_
+
+#include <memory>
+
+#include "base/time/time.h"
+#include "cc/cc_export.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+
+namespace cc {
+namespace test {
+class SnapFlingControllerTest;
+}
+
+class SnapFlingCurve;
+
+// A client that provides information to the controller. It also executes the
+// scroll operations and requests animation frames. All the inputs and outputs
+// are in the same coordinate space.
+class SnapFlingClient {
+ public:
+ virtual bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement,
+ gfx::Vector2dF* initial_offset,
+ gfx::Vector2dF* target_offset) const = 0;
+ virtual gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) = 0;
+ virtual void ScrollEndForSnapFling() = 0;
+ virtual void RequestAnimationForSnapFling() = 0;
+};
+
+// SnapFlingController ensures that an incoming fling event (or inertial-phase
+// scroll event) would land on a snap position if there is a valid one nearby.
+// It takes an input event, filters it if it conflicts with the current fling,
+// or generates a curve if the SnapFlingClient finds a valid snap position.
+// It also animates the curve by notifying the client to scroll when clock
+// ticks.
+class CC_EXPORT SnapFlingController {
+ public:
+ enum class GestureScrollType { kBegin, kUpdate, kEnd };
+
+ struct GestureScrollUpdateInfo {
+ gfx::Vector2dF delta;
+ bool is_in_inertial_phase;
+ base::TimeTicks event_time;
+ };
+
+ explicit SnapFlingController(SnapFlingClient* client);
+
+ static std::unique_ptr<SnapFlingController> CreateForTests(
+ SnapFlingClient* client,
+ std::unique_ptr<SnapFlingCurve> curve);
+
+ ~SnapFlingController();
+
+ // Returns true if the event should be consumed for snapping and should not be
+ // processed further.
+ bool FilterEventForSnap(GestureScrollType gesture_scroll_type);
+
+ // Creates the snap fling curve from the first inertial GSU. Returns true if
+ // the event if a snap fling curve has been created and the event should not
+ // be processed further.
+ bool HandleGestureScrollUpdate(const GestureScrollUpdateInfo& info);
+
+ // Notifies the snap fling controller to update or end the scroll animation.
+ void Animate(base::TimeTicks time);
+
+ private:
+ friend class test::SnapFlingControllerTest;
+
+ enum class State {
+ // We haven't received an inertial GSU in this scroll sequence.
+ kIdle,
+ // We have received an inertial GSU but decided not to snap for this scroll
+ // sequence.
+ kIgnored,
+ // We have received an inertial GSU and decided to snap and animate it for
+ // this scroll sequence. So subsequent GSUs and GSE in the scroll sequence
+ // are consumed for snapping.
+ kActive,
+ // The animation of the snap fling has finished for this scroll sequence.
+ // Subsequent GSUs and GSE in the scroll sequence are ignored.
+ kFinished,
+ };
+
+ SnapFlingController(SnapFlingClient* client,
+ std::unique_ptr<SnapFlingCurve> curve);
+ void ClearSnapFling();
+
+ // Sets the |curve_| to |curve| and the |state| to |kActive|.
+ void SetCurveForTest(std::unique_ptr<SnapFlingCurve> curve);
+
+ void SetActiveStateForTest() { state_ = State::kActive; }
+
+ SnapFlingClient* client_;
+ State state_ = State::kIdle;
+ std::unique_ptr<SnapFlingCurve> curve_;
+
+ DISALLOW_COPY_AND_ASSIGN(SnapFlingController);
+};
+
+} // namespace cc
+
+#endif // CC_INPUT_SNAP_FLING_CONTROLLER_H_
diff --git a/chromium/cc/input/snap_fling_controller_unittest.cc b/chromium/cc/input/snap_fling_controller_unittest.cc
new file mode 100644
index 00000000000..5deb03cb565
--- /dev/null
+++ b/chromium/cc/input/snap_fling_controller_unittest.cc
@@ -0,0 +1,157 @@
+// 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_fling_controller.h"
+
+#include "cc/input/snap_fling_curve.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace test {
+namespace {
+
+class MockSnapFlingClient : public SnapFlingClient {
+ public:
+ MOCK_CONST_METHOD3(GetSnapFlingInfo,
+ bool(const gfx::Vector2dF& natural_displacement,
+ gfx::Vector2dF* initial_offset,
+ gfx::Vector2dF* target_offset));
+ MOCK_METHOD0(ScrollEndForSnapFling, void());
+ MOCK_METHOD0(RequestAnimationForSnapFling, void());
+ MOCK_METHOD1(ScrollByForSnapFling, gfx::Vector2dF(const gfx::Vector2dF&));
+};
+
+class MockSnapFlingCurve : public SnapFlingCurve {
+ public:
+ MockSnapFlingCurve()
+ : SnapFlingCurve(gfx::Vector2dF(),
+ gfx::Vector2dF(0, 100),
+ base::TimeTicks()) {}
+ MOCK_CONST_METHOD0(IsFinished, bool());
+ MOCK_METHOD1(GetScrollDelta, gfx::Vector2dF(base::TimeTicks));
+};
+
+} // namespace
+
+class SnapFlingControllerTest : public testing::Test {
+ public:
+ SnapFlingControllerTest() {
+ controller_ = std::make_unique<SnapFlingController>(&mock_client_);
+ }
+ void SetCurve(std::unique_ptr<SnapFlingCurve> curve) {
+ controller_->SetCurveForTest(std::move(curve));
+ }
+ void SetActiveState() { controller_->SetActiveStateForTest(); }
+
+ protected:
+ testing::StrictMock<MockSnapFlingClient> mock_client_;
+ std::unique_ptr<SnapFlingController> controller_;
+};
+
+TEST_F(SnapFlingControllerTest, DoesNotFilterGSBWhenIdle) {
+ EXPECT_FALSE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kBegin));
+}
+
+TEST_F(SnapFlingControllerTest, FiltersGSUAndGSEDependingOnState) {
+ // Should not filter GSU and GSE if the fling is not active.
+ EXPECT_FALSE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kUpdate));
+ EXPECT_FALSE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kEnd));
+
+ // Should filter GSU and GSE if the fling is active.
+ SetActiveState();
+ EXPECT_TRUE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kUpdate));
+ EXPECT_TRUE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kEnd));
+}
+
+TEST_F(SnapFlingControllerTest, CreatesAndAnimatesCurveOnFirstInertialGSU) {
+ SnapFlingController::GestureScrollUpdateInfo gsu;
+ gsu.delta = gfx::Vector2dF(0, -10);
+ gsu.is_in_inertial_phase = true;
+
+ EXPECT_CALL(mock_client_,
+ GetSnapFlingInfo(testing::_, testing::_, testing::_))
+ .WillOnce(DoAll(testing::SetArgPointee<1>(gfx::Vector2dF(0, 0)),
+ testing::SetArgPointee<2>(gfx::Vector2dF(0, 100)),
+ testing::Return(true)));
+ EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(1);
+ EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(1);
+ EXPECT_TRUE(controller_->HandleGestureScrollUpdate(gsu));
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+}
+
+TEST_F(SnapFlingControllerTest, DoesNotHandleNonInertialGSU) {
+ SnapFlingController::GestureScrollUpdateInfo gsu;
+ gsu.delta = gfx::Vector2dF(0, -10);
+ gsu.is_in_inertial_phase = false;
+
+ EXPECT_CALL(mock_client_,
+ GetSnapFlingInfo(testing::_, testing::_, testing::_))
+ .Times(0);
+ EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
+ EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
+ EXPECT_FALSE(controller_->HandleGestureScrollUpdate(gsu));
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+}
+
+TEST_F(SnapFlingControllerTest, AnimatesTheCurve) {
+ std::unique_ptr<MockSnapFlingCurve> mock_curve =
+ std::make_unique<MockSnapFlingCurve>();
+ MockSnapFlingCurve* curve = mock_curve.get();
+ SetCurve(std::move(mock_curve));
+
+ EXPECT_CALL(*curve, IsFinished()).WillOnce(testing::Return(false));
+ EXPECT_CALL(*curve, GetScrollDelta(testing::_))
+ .WillOnce(testing::Return(gfx::Vector2dF(100, 100)));
+ EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(1);
+ EXPECT_CALL(mock_client_, ScrollByForSnapFling(gfx::Vector2dF(100, 100)));
+ controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(1));
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+ testing::Mock::VerifyAndClearExpectations(curve);
+}
+
+TEST_F(SnapFlingControllerTest, FinishesTheCurve) {
+ std::unique_ptr<MockSnapFlingCurve> mock_curve =
+ std::make_unique<MockSnapFlingCurve>();
+ MockSnapFlingCurve* curve = mock_curve.get();
+ SetCurve(std::move(mock_curve));
+ EXPECT_CALL(*curve, IsFinished()).WillOnce(testing::Return(true));
+ EXPECT_CALL(*curve, GetScrollDelta(testing::_)).Times(0);
+ EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
+ EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
+ EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(1);
+ controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(1));
+ testing::Mock::VerifyAndClearExpectations(curve);
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+
+ EXPECT_CALL(*curve, IsFinished()).Times(0);
+ EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
+ EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
+ EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(0);
+ controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(2));
+ testing::Mock::VerifyAndClearExpectations(curve);
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+}
+
+TEST_F(SnapFlingControllerTest, GSBNotFilteredAndResetsStateWhenActive) {
+ SetActiveState();
+ EXPECT_TRUE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kUpdate));
+
+ EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(1);
+ EXPECT_FALSE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kBegin));
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+
+ EXPECT_FALSE(controller_->FilterEventForSnap(
+ SnapFlingController::GestureScrollType::kUpdate));
+}
+
+} // namespace test
+} // namespace cc
diff --git a/chromium/cc/input/snap_fling_curve.cc b/chromium/cc/input/snap_fling_curve.cc
new file mode 100644
index 00000000000..645c9c5440a
--- /dev/null
+++ b/chromium/cc/input/snap_fling_curve.cc
@@ -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.
+
+#include "cc/input/snap_fling_curve.h"
+
+#include <cmath>
+#include "build/build_config.h"
+
+namespace cc {
+namespace {
+
+#if defined(OS_ANDROID)
+constexpr double kDistanceEstimatorScalar = 40;
+// The delta to be scrolled in next frame is 0.9 of the delta in last frame.
+constexpr double kRatio = 0.9;
+#else
+constexpr double kDistanceEstimatorScalar = 25;
+// The delta to be scrolled in next frame is 0.92 of the delta in last frame.
+constexpr double kRatio = 0.92;
+#endif
+constexpr double kMsPerFrame = 16;
+constexpr base::TimeDelta kMaximumSnapDuration =
+ base::TimeDelta::FromSecondsD(5);
+
+double GetDistanceFromDisplacement(gfx::Vector2dF displacement) {
+ return std::hypot(displacement.x(), displacement.y());
+}
+
+double EstimateFramesFromDistance(double distance) {
+ // We approximate scroll deltas as a geometric sequence with the ratio kRatio,
+ // and the last scrolled delta should be less or equal than 1, yielding the
+ // total distance as (1 - kRatio^(-n)) / (1 - (1 / kRatio)). Solving this
+ // could get n as below, which is the total number of deltas in the sequence,
+ // and is also the total frames needed to finish the curve.
+ return std::ceil(-std::log(1 - distance * (1 - 1 / kRatio)) /
+ std::log(kRatio));
+}
+
+double CalculateFirstDelta(double distance, double frames) {
+ // distance = first_delta (1 - kRatio^(frames) / (1 - kRatio)).
+ // We can get the |first_delta| by solving the equation above.
+ return distance * (1 - kRatio) / (1 - std::pow(kRatio, frames));
+}
+
+} // namespace
+
+gfx::Vector2dF SnapFlingCurve::EstimateDisplacement(
+ const gfx::Vector2dF& first_delta) {
+ gfx::Vector2dF destination = first_delta;
+ destination.Scale(kDistanceEstimatorScalar);
+ return destination;
+}
+
+SnapFlingCurve::SnapFlingCurve(const gfx::Vector2dF& start_offset,
+ const gfx::Vector2dF& target_offset,
+ base::TimeTicks first_gsu_time)
+ : start_offset_(start_offset),
+ total_displacement_(target_offset - start_offset),
+ total_distance_(GetDistanceFromDisplacement(total_displacement_)),
+ start_time_(first_gsu_time),
+ total_frames_(EstimateFramesFromDistance(total_distance_)),
+ first_delta_(CalculateFirstDelta(total_distance_, total_frames_)),
+ duration_(base::TimeDelta::FromMilliseconds(total_frames_ * kMsPerFrame)),
+ is_finished_(total_distance_ == 0) {
+ if (is_finished_)
+ return;
+ ratio_x_ = total_displacement_.x() / total_distance_;
+ ratio_y_ = total_displacement_.y() / total_distance_;
+}
+
+SnapFlingCurve::~SnapFlingCurve() = default;
+
+double SnapFlingCurve::GetCurrentCurveDistance(base::TimeTicks time_stamp) {
+ double current_distance = GetDistanceFromDisplacement(current_displacement_);
+ base::TimeDelta current_time = time_stamp - start_time_;
+
+ // Finishes the curve if the time elapsed is longer than |duration_|, or the
+ // remaining distance is less than 1.
+ if (current_time >= duration_ || current_distance >= total_distance_ - 1) {
+ return total_distance_;
+ }
+
+ double current_frame = current_time.InMillisecondsF() / kMsPerFrame + 1;
+ double sum =
+ first_delta_ * (1 - std::pow(kRatio, current_frame)) / (1 - kRatio);
+ return sum <= total_distance_ ? sum : total_distance_;
+}
+
+gfx::Vector2dF SnapFlingCurve::GetScrollDelta(base::TimeTicks time_stamp) {
+ if (is_finished_)
+ return gfx::Vector2dF();
+
+ // The the snap offset may never be reached due to clamping or other factors.
+ // To avoid a never ending snap curve, we force the curve to end if the time
+ // has passed a maximum Duration.
+ if (time_stamp - start_time_ > kMaximumSnapDuration) {
+ is_finished_ = true;
+ return total_displacement_ - current_displacement_;
+ }
+
+ double new_distance = GetCurrentCurveDistance(time_stamp);
+ gfx::Vector2dF new_displacement(new_distance * ratio_x_,
+ new_distance * ratio_y_);
+
+ return new_displacement - current_displacement_;
+}
+
+void SnapFlingCurve::UpdateCurrentOffset(const gfx::Vector2dF& current_offset) {
+ current_displacement_ = current_offset - start_offset_;
+ if (current_displacement_ == total_displacement_)
+ is_finished_ = true;
+}
+
+bool SnapFlingCurve::IsFinished() const {
+ return is_finished_;
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/snap_fling_curve.h b/chromium/cc/input/snap_fling_curve.h
new file mode 100644
index 00000000000..b5eaf62fa3d
--- /dev/null
+++ b/chromium/cc/input/snap_fling_curve.h
@@ -0,0 +1,78 @@
+// 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_FLING_CURVE_H_
+#define CC_INPUT_SNAP_FLING_CURVE_H_
+
+#include "base/time/time.h"
+#include "cc/cc_export.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+
+namespace cc {
+
+// The curve for the snap fling animation. The curve would generate a geometric
+// sequence of deltas to be scrolled at each frame.
+class CC_EXPORT SnapFlingCurve {
+ public:
+ // Creates the curve based on the start offset, target offset, and the first
+ // inertial GSU's time_stamp.
+ SnapFlingCurve(const gfx::Vector2dF& start_offset,
+ const gfx::Vector2dF& target_offset,
+ base::TimeTicks first_gsu_time);
+
+ virtual ~SnapFlingCurve();
+
+ // Estimate the total distance that will be scrolled given the first GSU's
+ // delta
+ static gfx::Vector2dF EstimateDisplacement(const gfx::Vector2dF& first_delta);
+
+ // Returns the delta that should be scrolled at |time|.
+ virtual gfx::Vector2dF GetScrollDelta(base::TimeTicks time);
+
+ // Updates |current_displacement_|. This sync is necessary because the node
+ // might be scrolled by other calls and the scrolls might be clamped.
+ void UpdateCurrentOffset(const gfx::Vector2dF& current_offset);
+
+ // Returns true if the scroll has arrived at the snap destination.
+ virtual bool IsFinished() const;
+
+ base::TimeDelta duration() const { return duration_; }
+
+ private:
+ // Returns the curve's current distance at |time_stamp|.
+ double GetCurrentCurveDistance(base::TimeTicks time_stamp);
+
+ // The initial scroll offset of the scroller.
+ const gfx::Vector2dF start_offset_;
+
+ // The total displacement to the snap position.
+ const gfx::Vector2dF total_displacement_;
+ // 1D representation of |total_displacement_|.
+ const double total_distance_;
+
+ // The current displacement that has been scrolled.
+ gfx::Vector2dF current_displacement_;
+
+ // The timestamp of the first GSU.
+ const base::TimeTicks start_time_;
+
+ // The number of deltas in the curve's geometric sequence.
+ const double total_frames_;
+ // The first delta that defines the curve's geometric sequence.
+ const double first_delta_;
+ // The total milliseconds needed to finish the curve.
+ const base::TimeDelta duration_;
+
+ bool is_finished_ = false;
+
+ // |total_displacement_.x| / |total_distance_|
+ double ratio_x_;
+ // |total_displacement_.y| / |total_distance_|
+ double ratio_y_;
+};
+
+} // namespace cc
+
+#endif // CC_INPUT_SNAP_FLING_CURVE_H_
diff --git a/chromium/cc/input/snap_fling_curve_unittest.cc b/chromium/cc/input/snap_fling_curve_unittest.cc
new file mode 100644
index 00000000000..028006f7670
--- /dev/null
+++ b/chromium/cc/input/snap_fling_curve_unittest.cc
@@ -0,0 +1,71 @@
+// 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_fling_curve.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace test {
+
+TEST(SnapFlingCurveTest, CurveInitialization) {
+ SnapFlingCurve active_curve(gfx::Vector2dF(100, 100),
+ gfx::Vector2dF(500, 500), base::TimeTicks());
+ EXPECT_FALSE(active_curve.IsFinished());
+
+ SnapFlingCurve finished_curve(gfx::Vector2dF(100, 100),
+ gfx::Vector2dF(100, 100), base::TimeTicks());
+ EXPECT_TRUE(finished_curve.IsFinished());
+}
+
+TEST(SnapFlingCurveTest, AdvanceHalfwayThrough) {
+ SnapFlingCurve curve(gfx::Vector2dF(100, 100), gfx::Vector2dF(500, 500),
+ base::TimeTicks());
+ base::TimeDelta duration = curve.duration();
+ gfx::Vector2dF delta1 =
+ curve.GetScrollDelta(base::TimeTicks() + duration / 2);
+ EXPECT_LT(0, delta1.x());
+ EXPECT_LT(0, delta1.y());
+ EXPECT_FALSE(curve.IsFinished());
+
+ // Repeated offset computations at the same timestamp before applying the
+ // scrolled delta should yield identical results.
+ gfx::Vector2dF delta2 =
+ curve.GetScrollDelta(base::TimeTicks() + duration / 2);
+ EXPECT_EQ(delta1, delta2);
+ EXPECT_FALSE(curve.IsFinished());
+
+ curve.UpdateCurrentOffset(gfx::Vector2dF(100, 100) + delta1);
+ EXPECT_FALSE(curve.IsFinished());
+}
+
+TEST(SnapFlingCurveTest, AdvanceFullyThroughOnlyFinishesAfterUpdate) {
+ SnapFlingCurve curve(gfx::Vector2dF(100, 100), gfx::Vector2dF(500, 500),
+ base::TimeTicks());
+ gfx::Vector2dF delta =
+ curve.GetScrollDelta(base::TimeTicks() + curve.duration());
+ EXPECT_EQ(gfx::Vector2dF(400, 400), delta);
+ EXPECT_FALSE(curve.IsFinished());
+
+ curve.UpdateCurrentOffset(gfx::Vector2dF(500, 500));
+ EXPECT_TRUE(curve.IsFinished());
+}
+
+TEST(SnapFlingCurveTest, ReturnsZeroAfterFinished) {
+ SnapFlingCurve curve(gfx::Vector2dF(100, 100), gfx::Vector2dF(500, 500),
+ base::TimeTicks());
+ curve.UpdateCurrentOffset(gfx::Vector2dF(500, 500));
+ EXPECT_TRUE(curve.IsFinished());
+
+ gfx::Vector2dF delta = curve.GetScrollDelta(base::TimeTicks());
+ EXPECT_EQ(gfx::Vector2dF(), delta);
+ EXPECT_TRUE(curve.IsFinished());
+
+ delta = curve.GetScrollDelta(base::TimeTicks() + curve.duration());
+ EXPECT_EQ(gfx::Vector2dF(), delta);
+ EXPECT_TRUE(curve.IsFinished());
+}
+
+} // namespace test
+} // namespace cc
diff --git a/chromium/cc/ipc/BUILD.gn b/chromium/cc/ipc/BUILD.gn
deleted file mode 100644
index 8692a3c6ac5..00000000000
--- a/chromium/cc/ipc/BUILD.gn
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ui.gni")
-import("//cc/cc.gni")
-import("//mojo/public/tools/bindings/mojom.gni")
-
-cc_component("ipc") {
- output_name = "cc_ipc"
-
- defines = [ "CC_IPC_IMPLEMENTATION" ]
-
- sources = [
- "cc_ipc_export.h",
- "cc_param_traits.cc",
- "cc_param_traits.h",
- "cc_param_traits_macros.h",
- ]
-
- public_deps = [
- "//cc",
- "//cc/paint",
- "//components/viz/common",
- "//skia",
- ]
-
- deps = [
- "//base",
- "//gpu/ipc/common",
- "//ipc",
- "//ui/gfx",
- "//ui/gfx/ipc",
- "//ui/gfx/ipc/buffer_types",
- "//ui/gfx/ipc/color",
- "//ui/gfx/ipc/geometry",
- "//ui/gfx/ipc/skia",
- "//ui/latency/ipc",
- ]
-}
diff --git a/chromium/cc/ipc/DEPS b/chromium/cc/ipc/DEPS
deleted file mode 100644
index a21ff764e82..00000000000
--- a/chromium/cc/ipc/DEPS
+++ /dev/null
@@ -1,10 +0,0 @@
-include_rules = [
- "+gpu/ipc/common",
- "+mojo/common",
- "+mojo/public",
- "+skia/public",
- "+ui/gfx/geometry/mojo",
- "+ui/latency/ipc",
- "+ui/latency/mojo",
- "+services/viz/public",
-]
diff --git a/chromium/cc/ipc/OWNERS b/chromium/cc/ipc/OWNERS
deleted file mode 100644
index 8b2d44fbeff..00000000000
--- a/chromium/cc/ipc/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-per-file *_param_traits*.*=set noparent
-per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
-
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
-
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/cc/ipc/cc_ipc_export.h b/chromium/cc/ipc/cc_ipc_export.h
deleted file mode 100644
index 4a3623e03d5..00000000000
--- a/chromium/cc/ipc/cc_ipc_export.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_IPC_CC_IPC_EXPORT_H_
-#define CC_IPC_CC_IPC_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(CC_IPC_IMPLEMENTATION)
-#define CC_IPC_EXPORT __declspec(dllexport)
-#else
-#define CC_IPC_EXPORT __declspec(dllimport)
-#endif // defined(CC_IPC_IMPLEMENTATION)
-
-#else // defined(WIN32)
-#if defined(CC_IPC_IMPLEMENTATION)
-#define CC_IPC_EXPORT __attribute__((visibility("default")))
-#else
-#define CC_IPC_EXPORT
-#endif
-#endif
-
-#else // defined(COMPONENT_BUILD)
-#define CC_IPC_EXPORT
-#endif
-
-#endif // CC_IPC_CC_IPC_EXPORT_H_
diff --git a/chromium/cc/ipc/cc_param_traits.cc b/chromium/cc/ipc/cc_param_traits.cc
deleted file mode 100644
index c66518e291d..00000000000
--- a/chromium/cc/ipc/cc_param_traits.cc
+++ /dev/null
@@ -1,1006 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/ipc/cc_param_traits.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/numerics/safe_conversions.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "base/unguessable_token.h"
-#include "cc/paint/filter_operations.h"
-#include "cc/paint/paint_filter.h"
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/paint/paint_op_reader.h"
-#include "cc/paint/paint_op_writer.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/debug_border_draw_quad.h"
-#include "components/viz/common/quads/draw_quad.h"
-#include "components/viz/common/quads/largest_draw_quad.h"
-#include "components/viz/common/quads/render_pass_draw_quad.h"
-#include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/quads/tile_draw_quad.h"
-#include "components/viz/common/quads/yuv_video_draw_quad.h"
-#include "components/viz/common/surfaces/surface_id.h"
-#include "ui/gfx/ipc/geometry/gfx_param_traits.h"
-#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-
-namespace IPC {
-
-void ParamTraits<cc::FilterOperation>::Write(base::Pickle* m,
- const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::FilterOperation::Write");
- WriteParam(m, p.type());
- switch (p.type()) {
- case cc::FilterOperation::GRAYSCALE:
- case cc::FilterOperation::SEPIA:
- case cc::FilterOperation::SATURATE:
- case cc::FilterOperation::HUE_ROTATE:
- case cc::FilterOperation::INVERT:
- case cc::FilterOperation::BRIGHTNESS:
- case cc::FilterOperation::SATURATING_BRIGHTNESS:
- case cc::FilterOperation::CONTRAST:
- case cc::FilterOperation::OPACITY:
- WriteParam(m, p.amount());
- break;
- case cc::FilterOperation::BLUR:
- WriteParam(m, p.amount());
- WriteParam(m, p.blur_tile_mode());
- break;
- case cc::FilterOperation::DROP_SHADOW:
- WriteParam(m, p.drop_shadow_offset());
- WriteParam(m, p.amount());
- WriteParam(m, p.drop_shadow_color());
- break;
- case cc::FilterOperation::COLOR_MATRIX:
- for (int i = 0; i < 20; ++i)
- WriteParam(m, p.matrix()[i]);
- break;
- case cc::FilterOperation::ZOOM:
- WriteParam(m, p.amount());
- WriteParam(m, p.zoom_inset());
- break;
- case cc::FilterOperation::REFERENCE:
- WriteParam(m, p.image_filter());
- break;
- case cc::FilterOperation::ALPHA_THRESHOLD:
- WriteParam(m, p.amount());
- WriteParam(m, p.outer_threshold());
- WriteParam(m, p.shape());
- break;
- }
-}
-
-bool ParamTraits<cc::FilterOperation>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::FilterOperation::Read");
- cc::FilterOperation::FilterType type;
- float amount;
- float outer_threshold;
- gfx::Point drop_shadow_offset;
- SkColor drop_shadow_color;
- SkScalar matrix[20];
- cc::FilterOperation::ShapeRects shape;
- int zoom_inset;
- SkBlurImageFilter::TileMode tile_mode;
-
- if (!ReadParam(m, iter, &type))
- return false;
- r->set_type(type);
-
- bool success = false;
- switch (type) {
- case cc::FilterOperation::GRAYSCALE:
- case cc::FilterOperation::SEPIA:
- case cc::FilterOperation::SATURATE:
- case cc::FilterOperation::HUE_ROTATE:
- case cc::FilterOperation::INVERT:
- case cc::FilterOperation::BRIGHTNESS:
- case cc::FilterOperation::SATURATING_BRIGHTNESS:
- case cc::FilterOperation::CONTRAST:
- case cc::FilterOperation::OPACITY:
- if (ReadParam(m, iter, &amount)) {
- r->set_amount(amount);
- success = true;
- }
- break;
- case cc::FilterOperation::BLUR:
- if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &tile_mode)) {
- r->set_amount(amount);
- r->set_blur_tile_mode(tile_mode);
- success = true;
- }
- break;
- case cc::FilterOperation::DROP_SHADOW:
- if (ReadParam(m, iter, &drop_shadow_offset) &&
- ReadParam(m, iter, &amount) &&
- ReadParam(m, iter, &drop_shadow_color)) {
- r->set_drop_shadow_offset(drop_shadow_offset);
- r->set_amount(amount);
- r->set_drop_shadow_color(drop_shadow_color);
- success = true;
- }
- break;
- case cc::FilterOperation::COLOR_MATRIX: {
- int i;
- for (i = 0; i < 20; ++i) {
- if (!ReadParam(m, iter, &matrix[i]))
- break;
- }
- if (i == 20) {
- r->set_matrix(matrix);
- success = true;
- }
- break;
- }
- case cc::FilterOperation::ZOOM:
- if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &zoom_inset) &&
- amount >= 0.f && zoom_inset >= 0) {
- r->set_amount(amount);
- r->set_zoom_inset(zoom_inset);
- success = true;
- }
- break;
- case cc::FilterOperation::REFERENCE: {
- sk_sp<cc::PaintFilter> filter;
- if (!ReadParam(m, iter, &filter)) {
- success = false;
- break;
- }
- r->set_image_filter(std::move(filter));
- success = true;
- break;
- }
- case cc::FilterOperation::ALPHA_THRESHOLD:
- if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &outer_threshold) &&
- ReadParam(m, iter, &shape) && amount >= 0.f &&
- outer_threshold >= 0.f) {
- r->set_amount(amount);
- r->set_outer_threshold(amount);
- r->set_shape(shape);
- success = true;
- }
- break;
- }
- return success;
-}
-
-void ParamTraits<cc::FilterOperation>::Log(const param_type& p,
- std::string* l) {
- l->append("(");
- LogParam(static_cast<unsigned>(p.type()), l);
- l->append(", ");
-
- switch (p.type()) {
- case cc::FilterOperation::GRAYSCALE:
- case cc::FilterOperation::SEPIA:
- case cc::FilterOperation::SATURATE:
- case cc::FilterOperation::HUE_ROTATE:
- case cc::FilterOperation::INVERT:
- case cc::FilterOperation::BRIGHTNESS:
- case cc::FilterOperation::SATURATING_BRIGHTNESS:
- case cc::FilterOperation::CONTRAST:
- case cc::FilterOperation::OPACITY:
- LogParam(p.amount(), l);
- break;
- case cc::FilterOperation::BLUR:
- LogParam(p.amount(), l);
- l->append(", ");
- LogParam(static_cast<int>(p.blur_tile_mode()), l);
- break;
- case cc::FilterOperation::DROP_SHADOW:
- LogParam(p.drop_shadow_offset(), l);
- l->append(", ");
- LogParam(p.amount(), l);
- l->append(", ");
- LogParam(p.drop_shadow_color(), l);
- break;
- case cc::FilterOperation::COLOR_MATRIX:
- for (int i = 0; i < 20; ++i) {
- if (i)
- l->append(", ");
- LogParam(p.matrix()[i], l);
- }
- break;
- case cc::FilterOperation::ZOOM:
- LogParam(p.amount(), l);
- l->append(", ");
- LogParam(p.zoom_inset(), l);
- break;
- case cc::FilterOperation::REFERENCE:
- LogParam(p.image_filter(), l);
- break;
- case cc::FilterOperation::ALPHA_THRESHOLD:
- LogParam(p.amount(), l);
- l->append(", ");
- LogParam(p.outer_threshold(), l);
- l->append(", ");
- LogParam(p.shape(), l);
- break;
- }
- l->append(")");
-}
-
-void ParamTraits<cc::FilterOperations>::Write(base::Pickle* m,
- const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::FilterOperations::Write");
- WriteParam(m, base::checked_cast<uint32_t>(p.size()));
- for (std::size_t i = 0; i < p.size(); ++i) {
- WriteParam(m, p.at(i));
- }
-}
-
-bool ParamTraits<cc::FilterOperations>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::FilterOperations::Read");
- uint32_t count;
- if (!ReadParam(m, iter, &count))
- return false;
-
- for (std::size_t i = 0; i < count; ++i) {
- cc::FilterOperation op = cc::FilterOperation::CreateEmptyFilter();
- if (!ReadParam(m, iter, &op))
- return false;
- r->Append(op);
- }
- return true;
-}
-
-void ParamTraits<cc::FilterOperations>::Log(const param_type& p,
- std::string* l) {
- l->append("(");
- for (std::size_t i = 0; i < p.size(); ++i) {
- if (i)
- l->append(", ");
- LogParam(p.at(i), l);
- }
- l->append(")");
-}
-
-void ParamTraits<sk_sp<cc::PaintFilter>>::Write(base::Pickle* m,
- const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::PaintFilter::Write");
- std::vector<uint8_t> memory;
- memory.resize(cc::PaintOpWriter::HeaderBytes() +
- cc::PaintFilter::GetFilterSize(p.get()));
- cc::PaintOpWriter writer(memory.data(), memory.size(), nullptr, nullptr,
- true /* enable_security_constraints */);
- writer.Write(p.get());
- if (writer.size() == 0u)
- m->WriteData(nullptr, 0);
- else
- m->WriteData(reinterpret_cast<const char*>(memory.data()), writer.size());
-}
-
-bool ParamTraits<sk_sp<cc::PaintFilter>>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::PaintFilter::Read");
- const char* data = nullptr;
- int length = 0;
- if (!iter->ReadData(&data, &length))
- return false;
-
- if (length <= 0) {
- r->reset();
- return true;
- }
-
- cc::PaintOpReader reader(data, length, nullptr,
- true /* enable_security_constraints */);
- sk_sp<cc::PaintFilter> filter;
- reader.Read(&filter);
- if (!filter)
- return false;
-
- *r = std::move(filter);
- return true;
-}
-
-void ParamTraits<sk_sp<cc::PaintFilter>>::Log(const param_type& p,
- std::string* l) {
- l->append("(");
- auto type = p ? p->type() : cc::PaintFilter::Type::kNullFilter;
- LogParam(cc::PaintFilter::TypeToString(type), l);
- l->append(")");
-}
-
-void ParamTraits<viz::RenderPass>::Write(base::Pickle* m, const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::RenderPass::Write");
- WriteParam(m, p.id);
- WriteParam(m, p.output_rect);
- WriteParam(m, p.damage_rect);
- WriteParam(m, p.transform_to_root_target);
- WriteParam(m, p.filters);
- WriteParam(m, p.background_filters);
- WriteParam(m, p.color_space);
- WriteParam(m, p.has_transparent_background);
- WriteParam(m, p.cache_render_pass);
- WriteParam(m, p.has_damage_from_contributing_content);
- WriteParam(m, p.generate_mipmap);
- WriteParam(m, base::checked_cast<uint32_t>(p.quad_list.size()));
-
- auto shared_quad_state_iter = p.shared_quad_state_list.cbegin();
- auto last_shared_quad_state_iter = p.shared_quad_state_list.cend();
- for (auto* quad : p.quad_list) {
- DCHECK(quad->rect.Contains(quad->visible_rect))
- << quad->material << " rect: " << quad->rect.ToString()
- << " visible_rect: " << quad->visible_rect.ToString();
-
- switch (quad->material) {
- case viz::DrawQuad::DEBUG_BORDER:
- WriteParam(m, *viz::DebugBorderDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::PICTURE_CONTENT:
- NOTREACHED();
- break;
- case viz::DrawQuad::TEXTURE_CONTENT:
- WriteParam(m, *viz::TextureDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::RENDER_PASS:
- WriteParam(m, *viz::RenderPassDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::SOLID_COLOR:
- WriteParam(m, *viz::SolidColorDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::SURFACE_CONTENT:
- WriteParam(m, *viz::SurfaceDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::TILED_CONTENT:
- WriteParam(m, *viz::TileDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::STREAM_VIDEO_CONTENT:
- WriteParam(m, *viz::StreamVideoDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::YUV_VIDEO_CONTENT:
- WriteParam(m, *viz::YUVVideoDrawQuad::MaterialCast(quad));
- break;
- case viz::DrawQuad::INVALID:
- break;
- }
-
- // Null shared quad states should not occur.
- DCHECK(quad->shared_quad_state);
-
- // SharedQuadStates should appear in the order they are used by DrawQuads.
- // Find the SharedQuadState for this DrawQuad.
- while (shared_quad_state_iter != p.shared_quad_state_list.end() &&
- quad->shared_quad_state != *shared_quad_state_iter) {
- ++shared_quad_state_iter;
- }
-
- DCHECK(shared_quad_state_iter != p.shared_quad_state_list.end());
-
- if (shared_quad_state_iter != last_shared_quad_state_iter) {
- WriteParam(m, true);
- WriteParam(m, **shared_quad_state_iter);
- last_shared_quad_state_iter = shared_quad_state_iter;
- } else {
- WriteParam(m, false);
- }
- }
-}
-
-static size_t ReserveSizeForRenderPassWrite(const viz::RenderPass& p) {
- size_t to_reserve = sizeof(viz::RenderPass);
-
- // Whether the quad points to a new shared quad state for each quad.
- to_reserve += p.quad_list.size() * sizeof(bool);
-
- // Shared quad state is only written when a quad contains a shared quad state
- // that has not been written.
- to_reserve += p.shared_quad_state_list.size() * sizeof(viz::SharedQuadState);
-
- // The largest quad type, verified by a unit test.
- to_reserve += p.quad_list.size() * viz::LargestDrawQuadSize();
-
- to_reserve +=
- sizeof(uint32_t) + p.filters.size() * sizeof(cc::FilterOperation);
- to_reserve += sizeof(uint32_t) +
- p.background_filters.size() * sizeof(cc::FilterOperation);
-
- return to_reserve;
-}
-
-template <typename QuadType>
-static viz::DrawQuad* ReadDrawQuad(const base::Pickle* m,
- base::PickleIterator* iter,
- viz::RenderPass* render_pass) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::ReadDrawQuad");
- QuadType* quad = render_pass->CreateAndAppendDrawQuad<QuadType>();
- if (!ReadParam(m, iter, quad))
- return nullptr;
- return quad;
-}
-
-bool ParamTraits<viz::RenderPass>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::RenderPass::Read");
- uint64_t id;
- gfx::Rect output_rect;
- gfx::Rect damage_rect;
- gfx::Transform transform_to_root_target;
- cc::FilterOperations filters;
- cc::FilterOperations background_filters;
- gfx::ColorSpace color_space;
- bool has_transparent_background;
- bool cache_render_pass;
- bool has_damage_from_contributing_content;
- bool generate_mipmap;
-
- uint32_t quad_list_size;
-
- if (!ReadParam(m, iter, &id) || !ReadParam(m, iter, &output_rect) ||
- !ReadParam(m, iter, &damage_rect) ||
- !ReadParam(m, iter, &transform_to_root_target) ||
- !ReadParam(m, iter, &filters) ||
- !ReadParam(m, iter, &background_filters) ||
- !ReadParam(m, iter, &color_space) ||
- !ReadParam(m, iter, &has_transparent_background) ||
- !ReadParam(m, iter, &cache_render_pass) ||
- !ReadParam(m, iter, &has_damage_from_contributing_content) ||
- !ReadParam(m, iter, &generate_mipmap) ||
- !ReadParam(m, iter, &quad_list_size))
- return false;
-
- p->SetAll(id, output_rect, damage_rect, transform_to_root_target, filters,
- background_filters, color_space, has_transparent_background,
- cache_render_pass, has_damage_from_contributing_content,
- generate_mipmap);
-
- for (uint32_t i = 0; i < quad_list_size; ++i) {
- viz::DrawQuad::Material material;
- base::PickleIterator temp_iter = *iter;
- if (!ReadParam(m, &temp_iter, &material))
- return false;
-
- viz::DrawQuad* draw_quad = nullptr;
- switch (material) {
- case viz::DrawQuad::DEBUG_BORDER:
- draw_quad = ReadDrawQuad<viz::DebugBorderDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::PICTURE_CONTENT:
- NOTREACHED();
- return false;
- case viz::DrawQuad::SURFACE_CONTENT:
- draw_quad = ReadDrawQuad<viz::SurfaceDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::TEXTURE_CONTENT:
- draw_quad = ReadDrawQuad<viz::TextureDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::RENDER_PASS:
- draw_quad = ReadDrawQuad<viz::RenderPassDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::SOLID_COLOR:
- draw_quad = ReadDrawQuad<viz::SolidColorDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::TILED_CONTENT:
- draw_quad = ReadDrawQuad<viz::TileDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::STREAM_VIDEO_CONTENT:
- draw_quad = ReadDrawQuad<viz::StreamVideoDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::YUV_VIDEO_CONTENT:
- draw_quad = ReadDrawQuad<viz::YUVVideoDrawQuad>(m, iter, p);
- break;
- case viz::DrawQuad::INVALID:
- break;
- }
- if (!draw_quad)
- return false;
- if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
- LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
- << " rect: " << draw_quad->rect.ToString()
- << " visible_rect: " << draw_quad->visible_rect.ToString();
- return false;
- }
-
- bool has_new_shared_quad_state;
- if (!ReadParam(m, iter, &has_new_shared_quad_state))
- return false;
-
- // If the quad has a new shared quad state, read it in.
- if (has_new_shared_quad_state) {
- viz::SharedQuadState* state = p->CreateAndAppendSharedQuadState();
- if (!ReadParam(m, iter, state))
- return false;
- }
-
- draw_quad->shared_quad_state = p->shared_quad_state_list.back();
- }
-
- return true;
-}
-
-void ParamTraits<viz::RenderPass>::Log(const param_type& p, std::string* l) {
- l->append("RenderPass((");
- LogParam(p.id, l);
- l->append("), ");
- LogParam(p.output_rect, l);
- l->append(", ");
- LogParam(p.damage_rect, l);
- l->append(", ");
- LogParam(p.transform_to_root_target, l);
- l->append(", ");
- LogParam(p.filters, l);
- l->append(", ");
- LogParam(p.background_filters, l);
- l->append(", ");
- LogParam(p.color_space, l);
- l->append(", ");
- LogParam(p.has_transparent_background, l);
- l->append(", ");
- LogParam(p.cache_render_pass, l);
- l->append(", ");
- LogParam(p.has_damage_from_contributing_content, l);
- l->append(", ");
-
- l->append("[");
- for (auto* shared_quad_state : p.shared_quad_state_list) {
- if (shared_quad_state != p.shared_quad_state_list.front())
- l->append(", ");
- LogParam(*shared_quad_state, l);
- }
- l->append("], [");
- for (auto* quad : p.quad_list) {
- if (quad != p.quad_list.front())
- l->append(", ");
- switch (quad->material) {
- case viz::DrawQuad::DEBUG_BORDER:
- LogParam(*viz::DebugBorderDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::PICTURE_CONTENT:
- NOTREACHED();
- break;
- case viz::DrawQuad::TEXTURE_CONTENT:
- LogParam(*viz::TextureDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::RENDER_PASS:
- LogParam(*viz::RenderPassDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::SOLID_COLOR:
- LogParam(*viz::SolidColorDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::SURFACE_CONTENT:
- LogParam(*viz::SurfaceDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::TILED_CONTENT:
- LogParam(*viz::TileDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::STREAM_VIDEO_CONTENT:
- LogParam(*viz::StreamVideoDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::YUV_VIDEO_CONTENT:
- LogParam(*viz::YUVVideoDrawQuad::MaterialCast(quad), l);
- break;
- case viz::DrawQuad::INVALID:
- break;
- }
- }
- l->append("])");
-}
-
-void ParamTraits<viz::FrameDeadline>::Write(base::Pickle* m,
- const param_type& p) {
- WriteParam(m, p.frame_start_time());
- WriteParam(m, p.deadline_in_frames());
- WriteParam(m, p.frame_interval());
- WriteParam(m, p.use_default_lower_bound_deadline());
-}
-
-bool ParamTraits<viz::FrameDeadline>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- base::TimeTicks frame_start_time;
- if (!ReadParam(m, iter, &frame_start_time))
- return false;
-
- uint32_t deadline_in_frames;
- if (!ReadParam(m, iter, &deadline_in_frames))
- return false;
-
- base::TimeDelta frame_interval;
- if (!ReadParam(m, iter, &frame_interval))
- return false;
-
- bool use_default_lower_bound_deadline;
- if (!ReadParam(m, iter, &use_default_lower_bound_deadline))
- return false;
-
- *p = viz::FrameDeadline(frame_start_time, deadline_in_frames, frame_interval,
- use_default_lower_bound_deadline);
- return true;
-}
-
-void ParamTraits<viz::FrameDeadline>::Log(const param_type& p, std::string* l) {
- l->append("viz::FrameDeadline(");
- LogParam(p.frame_start_time(), l);
- l->append(", ");
- LogParam(p.deadline_in_frames(), l);
- l->append(", ");
- LogParam(p.frame_interval(), l);
- l->append(", ");
- LogParam(p.use_default_lower_bound_deadline(), l);
- l->append(")");
-}
-
-void ParamTraits<viz::FrameSinkId>::Write(base::Pickle* m,
- const param_type& p) {
- DCHECK(p.is_valid());
- WriteParam(m, p.client_id());
- WriteParam(m, p.sink_id());
-}
-
-bool ParamTraits<viz::FrameSinkId>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- uint32_t client_id;
- if (!ReadParam(m, iter, &client_id))
- return false;
-
- uint32_t sink_id;
- if (!ReadParam(m, iter, &sink_id))
- return false;
-
- *p = viz::FrameSinkId(client_id, sink_id);
- return p->is_valid();
-}
-
-void ParamTraits<viz::FrameSinkId>::Log(const param_type& p, std::string* l) {
- l->append("viz::FrameSinkId(");
- LogParam(p.client_id(), l);
- l->append(", ");
- LogParam(p.sink_id(), l);
- l->append(")");
-}
-
-void ParamTraits<viz::LocalSurfaceId>::Write(base::Pickle* m,
- const param_type& p) {
- DCHECK(p.is_valid());
- WriteParam(m, p.parent_sequence_number());
- WriteParam(m, p.child_sequence_number());
- WriteParam(m, p.embed_token());
-}
-
-bool ParamTraits<viz::LocalSurfaceId>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- uint32_t parent_sequence_number;
- if (!ReadParam(m, iter, &parent_sequence_number))
- return false;
-
- uint32_t child_sequence_number;
- if (!ReadParam(m, iter, &child_sequence_number))
- return false;
-
- base::UnguessableToken embed_token;
- if (!ReadParam(m, iter, &embed_token))
- return false;
-
- *p = viz::LocalSurfaceId(parent_sequence_number, child_sequence_number,
- embed_token);
- return p->is_valid();
-}
-
-void ParamTraits<viz::LocalSurfaceId>::Log(const param_type& p,
- std::string* l) {
- l->append("viz::LocalSurfaceId(");
- LogParam(p.parent_sequence_number(), l);
- l->append(", ");
- LogParam(p.child_sequence_number(), l);
- l->append(", ");
- LogParam(p.embed_token(), l);
- l->append(")");
-}
-
-void ParamTraits<viz::SurfaceId>::Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, p.frame_sink_id());
- WriteParam(m, p.local_surface_id());
-}
-
-bool ParamTraits<viz::SurfaceId>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- viz::FrameSinkId frame_sink_id;
- if (!ReadParam(m, iter, &frame_sink_id))
- return false;
-
- viz::LocalSurfaceId local_surface_id;
- if (!ReadParam(m, iter, &local_surface_id))
- return false;
-
- *p = viz::SurfaceId(frame_sink_id, local_surface_id);
- return true;
-}
-
-void ParamTraits<viz::SurfaceId>::Log(const param_type& p, std::string* l) {
- l->append("viz::SurfaceId(");
- LogParam(p.frame_sink_id(), l);
- l->append(", ");
- LogParam(p.local_surface_id(), l);
- l->append(")");
-}
-
-void ParamTraits<viz::SurfaceInfo>::Write(base::Pickle* m,
- const param_type& p) {
- WriteParam(m, p.id());
- WriteParam(m, p.device_scale_factor());
- WriteParam(m, p.size_in_pixels());
-}
-
-bool ParamTraits<viz::SurfaceInfo>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- viz::SurfaceId surface_id;
- if (!ReadParam(m, iter, &surface_id))
- return false;
-
- float device_scale_factor;
- if (!ReadParam(m, iter, &device_scale_factor))
- return false;
-
- gfx::Size size_in_pixels;
- if (!ReadParam(m, iter, &size_in_pixels))
- return false;
-
- *p = viz::SurfaceInfo(surface_id, device_scale_factor, size_in_pixels);
- return p->is_valid();
-}
-
-void ParamTraits<viz::SurfaceInfo>::Log(const param_type& p, std::string* l) {
- l->append("viz::SurfaceInfo(");
- LogParam(p.id(), l);
- l->append(", ");
- LogParam(p.device_scale_factor(), l);
- l->append(", ");
- LogParam(p.size_in_pixels(), l);
- l->append(")");
-}
-
-void ParamTraits<viz::CompositorFrame>::Write(base::Pickle* m,
- const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::CompositorFrame::Write");
- WriteParam(m, p.metadata);
- size_t to_reserve = 0u;
- to_reserve += p.resource_list.size() * sizeof(viz::TransferableResource);
- for (const auto& pass : p.render_pass_list) {
- to_reserve += sizeof(size_t) * 2;
- to_reserve += ReserveSizeForRenderPassWrite(*pass);
- }
- m->Reserve(to_reserve);
-
- WriteParam(m, p.resource_list);
- WriteParam(m, base::checked_cast<uint32_t>(p.render_pass_list.size()));
- for (const auto& pass : p.render_pass_list) {
- WriteParam(m, base::checked_cast<uint32_t>(pass->quad_list.size()));
- WriteParam(
- m, base::checked_cast<uint32_t>(pass->shared_quad_state_list.size()));
- WriteParam(m, *pass);
- }
-}
-
-bool ParamTraits<viz::CompositorFrame>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::CompositorFrame::Read");
- if (!ReadParam(m, iter, &p->metadata))
- return false;
-
- const size_t kMaxRenderPasses = 10000;
- const size_t kMaxSharedQuadStateListSize = 100000;
- const size_t kMaxQuadListSize = 1000000;
-
- std::set<viz::RenderPassId> pass_id_set;
-
- uint32_t num_render_passes;
- if (!ReadParam(m, iter, &p->resource_list) ||
- !ReadParam(m, iter, &num_render_passes) || num_render_passes == 0 ||
- num_render_passes > kMaxRenderPasses)
- return false;
- for (uint32_t i = 0; i < num_render_passes; ++i) {
- uint32_t quad_list_size;
- uint32_t shared_quad_state_list_size;
- if (!ReadParam(m, iter, &quad_list_size) ||
- !ReadParam(m, iter, &shared_quad_state_list_size) ||
- quad_list_size > kMaxQuadListSize ||
- shared_quad_state_list_size > kMaxSharedQuadStateListSize)
- return false;
- std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(
- static_cast<size_t>(shared_quad_state_list_size),
- static_cast<size_t>(quad_list_size));
- if (!ReadParam(m, iter, render_pass.get()))
- return false;
- // Validate that each viz::RenderPassDrawQuad points at a valid RenderPass
- // earlier in the frame.
- for (const auto* quad : render_pass->quad_list) {
- if (quad->material != viz::DrawQuad::RENDER_PASS)
- continue;
- const viz::RenderPassDrawQuad* rpdq =
- viz::RenderPassDrawQuad::MaterialCast(quad);
- if (!pass_id_set.count(rpdq->render_pass_id))
- return false;
- }
- pass_id_set.insert(render_pass->id);
- p->render_pass_list.push_back(std::move(render_pass));
- }
-
- if (p->render_pass_list.back()->output_rect.size().IsEmpty())
- return false;
-
- return true;
-}
-
-void ParamTraits<viz::CompositorFrame>::Log(const param_type& p,
- std::string* l) {
- l->append("CompositorFrame(");
- LogParam(p.metadata, l);
- l->append(", ");
- LogParam(p.resource_list, l);
- l->append(", [");
- for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
- if (i)
- l->append(", ");
- LogParam(*p.render_pass_list[i], l);
- }
- l->append("])");
-}
-
-void ParamTraits<viz::DrawQuad::Resources>::Write(base::Pickle* m,
- const param_type& p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::DrawQuad::Resources::Write");
- DCHECK_LE(p.count, viz::DrawQuad::Resources::kMaxResourceIdCount);
- WriteParam(m, p.count);
- for (size_t i = 0; i < p.count; ++i)
- WriteParam(m, p.ids[i]);
-}
-
-bool ParamTraits<viz::DrawQuad::Resources>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "ParamTraits::DrawQuad::Resources::Read");
- if (!ReadParam(m, iter, &p->count))
- return false;
- if (p->count > viz::DrawQuad::Resources::kMaxResourceIdCount)
- return false;
- for (size_t i = 0; i < p->count; ++i) {
- if (!ReadParam(m, iter, &p->ids[i]))
- return false;
- }
- return true;
-}
-
-void ParamTraits<viz::DrawQuad::Resources>::Log(const param_type& p,
- std::string* l) {
- l->append("DrawQuad::Resources(");
- LogParam(p.count, l);
- l->append(", [");
- if (p.count > viz::DrawQuad::Resources::kMaxResourceIdCount) {
- l->append("])");
- return;
- }
-
- for (size_t i = 0; i < p.count; ++i) {
- LogParam(p.ids[i], l);
- if (i < (p.count - 1))
- l->append(", ");
- }
- l->append("])");
-}
-
-void ParamTraits<viz::YUVVideoDrawQuad>::Write(base::Pickle* m,
- const param_type& p) {
- ParamTraits<viz::DrawQuad>::Write(m, p);
- WriteParam(m, p.ya_tex_coord_rect);
- WriteParam(m, p.uv_tex_coord_rect);
- WriteParam(m, p.ya_tex_size);
- WriteParam(m, p.uv_tex_size);
- WriteParam(m, p.video_color_space);
- WriteParam(m, p.resource_offset);
- WriteParam(m, p.resource_multiplier);
- WriteParam(m, p.bits_per_channel);
-}
-
-bool ParamTraits<viz::YUVVideoDrawQuad>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- return ParamTraits<viz::DrawQuad>::Read(m, iter, p) &&
- ReadParam(m, iter, &p->ya_tex_coord_rect) &&
- ReadParam(m, iter, &p->uv_tex_coord_rect) &&
- ReadParam(m, iter, &p->ya_tex_size) &&
- ReadParam(m, iter, &p->uv_tex_size) &&
- ReadParam(m, iter, &p->video_color_space) &&
- ReadParam(m, iter, &p->resource_offset) &&
- ReadParam(m, iter, &p->resource_multiplier) &&
- ReadParam(m, iter, &p->bits_per_channel) &&
- p->bits_per_channel >= viz::YUVVideoDrawQuad::kMinBitsPerChannel &&
- p->bits_per_channel <= viz::YUVVideoDrawQuad::kMaxBitsPerChannel;
-}
-
-void ParamTraits<viz::YUVVideoDrawQuad>::Log(const param_type& p,
- std::string* l) {
- l->append("(");
- ParamTraits<viz::DrawQuad>::Log(p, l);
- l->append(", ");
- LogParam(p.ya_tex_coord_rect, l);
- l->append(", ");
- LogParam(p.uv_tex_coord_rect, l);
- l->append(", ");
- LogParam(p.ya_tex_size, l);
- l->append(", ");
- LogParam(p.uv_tex_size, l);
- l->append(", ");
- LogParam(p.video_color_space, l);
- l->append(", ");
- LogParam(p.resource_offset, l);
- l->append(", ");
- LogParam(p.resource_multiplier, l);
- l->append(", ");
- LogParam(p.bits_per_channel, l);
- l->append("])");
-}
-
-void ParamTraits<viz::BeginFrameAck>::Write(base::Pickle* m,
- const param_type& p) {
- m->WriteUInt64(p.sequence_number);
- m->WriteUInt64(p.source_id);
- // |has_damage| is implicit through IPC message name, so not transmitted.
-}
-
-bool ParamTraits<viz::BeginFrameAck>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- return iter->ReadUInt64(&p->sequence_number) &&
- p->sequence_number >= viz::BeginFrameArgs::kStartingFrameNumber &&
- iter->ReadUInt64(&p->source_id);
-}
-
-void ParamTraits<viz::BeginFrameAck>::Log(const param_type& p, std::string* l) {
- l->append("(");
- LogParam(p.sequence_number, l);
- l->append(", ");
- LogParam(p.source_id, l);
- l->append(")");
-}
-
-} // namespace IPC
-
-// Generate param traits write methods.
-#include "ipc/param_traits_write_macros.h"
-namespace IPC {
-#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
-#include "cc/ipc/cc_param_traits_macros.h"
-} // namespace IPC
-
-// Generate param traits read methods.
-#include "ipc/param_traits_read_macros.h"
-namespace IPC {
-#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
-#include "cc/ipc/cc_param_traits_macros.h"
-} // namespace IPC
-
-// Generate param traits log methods.
-#include "ipc/param_traits_log_macros.h"
-namespace IPC {
-#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
-#include "cc/ipc/cc_param_traits_macros.h"
-} // namespace IPC
diff --git a/chromium/cc/ipc/cc_param_traits.h b/chromium/cc/ipc/cc_param_traits.h
deleted file mode 100644
index bb575eb87f6..00000000000
--- a/chromium/cc/ipc/cc_param_traits.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// IPC Messages sent between compositor instances.
-
-#ifndef CC_IPC_CC_PARAM_TRAITS_H_
-#define CC_IPC_CC_PARAM_TRAITS_H_
-
-#include "cc/ipc/cc_ipc_export.h"
-#include "cc/ipc/cc_param_traits_macros.h"
-#include "cc/paint/filter_operation.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/draw_quad.h"
-#include "components/viz/common/quads/frame_deadline.h"
-#include "components/viz/common/quads/stream_video_draw_quad.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
-#include "gpu/ipc/common/gpu_command_buffer_traits.h"
-#include "ipc/ipc_message_macros.h"
-
-namespace cc {
-class FilterOperations;
-class PaintFilter;
-}
-
-namespace IPC {
-
-template <>
-struct ParamTraits<cc::FilterOperation> {
- typedef cc::FilterOperation param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct ParamTraits<cc::FilterOperations> {
- typedef cc::FilterOperations param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<sk_sp<cc::PaintFilter>> {
- typedef sk_sp<cc::PaintFilter> param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::RenderPass> {
- typedef viz::RenderPass param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::FrameDeadline> {
- typedef viz::FrameDeadline param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::FrameSinkId> {
- typedef viz::FrameSinkId param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::LocalSurfaceId> {
- typedef viz::LocalSurfaceId param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::SurfaceId> {
- typedef viz::SurfaceId param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::SurfaceInfo> {
- typedef viz::SurfaceInfo param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::CompositorFrame> {
- typedef viz::CompositorFrame param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::DrawQuad::Resources> {
- typedef viz::DrawQuad::Resources param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::YUVVideoDrawQuad> {
- typedef viz::YUVVideoDrawQuad param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct CC_IPC_EXPORT ParamTraits<viz::BeginFrameAck> {
- typedef viz::BeginFrameAck param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p);
- static void Log(const param_type& p, std::string* l);
-};
-
-} // namespace IPC
-
-#endif // CC_IPC_CC_PARAM_TRAITS_H_
diff --git a/chromium/cc/ipc/cc_param_traits_macros.h b/chromium/cc/ipc/cc_param_traits_macros.h
deleted file mode 100644
index 1141b237a82..00000000000
--- a/chromium/cc/ipc/cc_param_traits_macros.h
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
-#define CC_IPC_CC_PARAM_TRAITS_MACROS_H_
-
-#include "cc/paint/filter_operation.h"
-#include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/debug_border_draw_quad.h"
-#include "components/viz/common/quads/draw_quad.h"
-#include "components/viz/common/quads/render_pass.h"
-#include "components/viz/common/quads/render_pass_draw_quad.h"
-#include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/common/quads/stream_video_draw_quad.h"
-#include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/quads/tile_draw_quad.h"
-#include "components/viz/common/quads/yuv_video_draw_quad.h"
-#include "components/viz/common/resources/resource_format.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "components/viz/common/surfaces/surface_id.h"
-#include "components/viz/common/surfaces/surface_info.h"
-#include "ui/gfx/ipc/buffer_types/gfx_param_traits.h"
-#include "ui/gfx/ipc/color/gfx_param_traits.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-#include "ui/latency/ipc/latency_info_param_traits.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CC_IPC_EXPORT
-
-IPC_ENUM_TRAITS_MAX_VALUE(viz::DrawQuad::Material, viz::DrawQuad::MATERIAL_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(cc::FilterOperation::FilterType,
- cc::FilterOperation::FILTER_TYPE_LAST)
-// TODO(wutao): This trait belongs with skia code.
-IPC_ENUM_TRAITS_MAX_VALUE(SkBlurImageFilter::TileMode,
- SkBlurImageFilter::kMax_TileMode)
-IPC_ENUM_TRAITS_MAX_VALUE(viz::ResourceFormat, viz::RESOURCE_FORMAT_MAX)
-
-// TODO(fsamuel): This trait belongs with skia code.
-IPC_ENUM_TRAITS_MAX_VALUE(SkBlendMode, SkBlendMode::kLastMode)
-
-IPC_STRUCT_TRAITS_BEGIN(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(material)
- IPC_STRUCT_TRAITS_MEMBER(rect)
- IPC_STRUCT_TRAITS_MEMBER(visible_rect)
- IPC_STRUCT_TRAITS_MEMBER(needs_blending)
- IPC_STRUCT_TRAITS_MEMBER(resources)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::DebugBorderDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(color)
- IPC_STRUCT_TRAITS_MEMBER(width)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::RenderPassDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(render_pass_id)
- IPC_STRUCT_TRAITS_MEMBER(mask_uv_rect)
- IPC_STRUCT_TRAITS_MEMBER(mask_texture_size)
- IPC_STRUCT_TRAITS_MEMBER(filters_scale)
- IPC_STRUCT_TRAITS_MEMBER(filters_origin)
- IPC_STRUCT_TRAITS_MEMBER(tex_coord_rect)
- IPC_STRUCT_TRAITS_MEMBER(force_anti_aliasing_off)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::SolidColorDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(color)
- IPC_STRUCT_TRAITS_MEMBER(force_anti_aliasing_off)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::StreamVideoDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(overlay_resources)
- IPC_STRUCT_TRAITS_MEMBER(matrix)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::StreamVideoDrawQuad::OverlayResources)
- IPC_STRUCT_TRAITS_MEMBER(size_in_pixels)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::SurfaceDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(primary_surface_id)
- IPC_STRUCT_TRAITS_MEMBER(fallback_surface_id)
- IPC_STRUCT_TRAITS_MEMBER(default_background_color)
- IPC_STRUCT_TRAITS_MEMBER(stretch_content_to_fill_bounds)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::TextureDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(overlay_resources)
- IPC_STRUCT_TRAITS_MEMBER(premultiplied_alpha)
- IPC_STRUCT_TRAITS_MEMBER(uv_top_left)
- IPC_STRUCT_TRAITS_MEMBER(uv_bottom_right)
- IPC_STRUCT_TRAITS_MEMBER(background_color)
- IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[0])
- IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[1])
- IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[2])
- IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[3])
- IPC_STRUCT_TRAITS_MEMBER(y_flipped)
- IPC_STRUCT_TRAITS_MEMBER(nearest_neighbor)
- IPC_STRUCT_TRAITS_MEMBER(secure_output_only)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::TextureDrawQuad::OverlayResources)
- IPC_STRUCT_TRAITS_MEMBER(size_in_pixels)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::TileDrawQuad)
- IPC_STRUCT_TRAITS_PARENT(viz::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(tex_coord_rect)
- IPC_STRUCT_TRAITS_MEMBER(texture_size)
- IPC_STRUCT_TRAITS_MEMBER(swizzle_contents)
- IPC_STRUCT_TRAITS_MEMBER(is_premultiplied)
- IPC_STRUCT_TRAITS_MEMBER(nearest_neighbor)
- IPC_STRUCT_TRAITS_MEMBER(force_anti_aliasing_off)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::SharedQuadState)
- IPC_STRUCT_TRAITS_MEMBER(quad_to_target_transform)
- IPC_STRUCT_TRAITS_MEMBER(quad_layer_rect)
- IPC_STRUCT_TRAITS_MEMBER(visible_quad_layer_rect)
- IPC_STRUCT_TRAITS_MEMBER(clip_rect)
- IPC_STRUCT_TRAITS_MEMBER(is_clipped)
- IPC_STRUCT_TRAITS_MEMBER(opacity)
- IPC_STRUCT_TRAITS_MEMBER(blend_mode)
- IPC_STRUCT_TRAITS_MEMBER(sorting_context_id)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::TransferableResource)
- IPC_STRUCT_TRAITS_MEMBER(id)
- IPC_STRUCT_TRAITS_MEMBER(format)
- IPC_STRUCT_TRAITS_MEMBER(buffer_format)
- IPC_STRUCT_TRAITS_MEMBER(filter)
- IPC_STRUCT_TRAITS_MEMBER(size)
- IPC_STRUCT_TRAITS_MEMBER(mailbox_holder)
- IPC_STRUCT_TRAITS_MEMBER(read_lock_fences_enabled)
- IPC_STRUCT_TRAITS_MEMBER(is_software)
- IPC_STRUCT_TRAITS_MEMBER(shared_bitmap_sequence_number)
- IPC_STRUCT_TRAITS_MEMBER(is_overlay_candidate)
- IPC_STRUCT_TRAITS_MEMBER(color_space)
-#if defined(OS_ANDROID)
- IPC_STRUCT_TRAITS_MEMBER(is_backed_by_surface_texture)
- IPC_STRUCT_TRAITS_MEMBER(wants_promotion_hint)
-#endif
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::ReturnedResource)
- IPC_STRUCT_TRAITS_MEMBER(id)
- IPC_STRUCT_TRAITS_MEMBER(sync_token)
- IPC_STRUCT_TRAITS_MEMBER(count)
- IPC_STRUCT_TRAITS_MEMBER(lost)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::Selection<gfx::SelectionBound>)
- IPC_STRUCT_TRAITS_MEMBER(start)
- IPC_STRUCT_TRAITS_MEMBER(end)
-IPC_STRUCT_TRAITS_END()
-
-IPC_ENUM_TRAITS_MAX_VALUE(viz::BeginFrameArgs::BeginFrameArgsType,
- viz::BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX - 1)
-
-IPC_STRUCT_TRAITS_BEGIN(viz::BeginFrameArgs)
- IPC_STRUCT_TRAITS_MEMBER(frame_time)
- IPC_STRUCT_TRAITS_MEMBER(deadline)
- IPC_STRUCT_TRAITS_MEMBER(interval)
- IPC_STRUCT_TRAITS_MEMBER(sequence_number)
- IPC_STRUCT_TRAITS_MEMBER(source_id)
- IPC_STRUCT_TRAITS_MEMBER(type)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(viz::CompositorFrameMetadata)
- IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset)
- IPC_STRUCT_TRAITS_MEMBER(page_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(scrollable_viewport_size)
- IPC_STRUCT_TRAITS_MEMBER(root_layer_size)
- IPC_STRUCT_TRAITS_MEMBER(min_page_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(root_overflow_y_hidden)
- IPC_STRUCT_TRAITS_MEMBER(may_contain_video)
- IPC_STRUCT_TRAITS_MEMBER(
- is_resourceless_software_draw_with_scroll_or_animation)
- IPC_STRUCT_TRAITS_MEMBER(top_controls_height)
- IPC_STRUCT_TRAITS_MEMBER(top_controls_shown_ratio)
- IPC_STRUCT_TRAITS_MEMBER(bottom_controls_height)
- IPC_STRUCT_TRAITS_MEMBER(bottom_controls_shown_ratio)
- IPC_STRUCT_TRAITS_MEMBER(root_background_color)
- IPC_STRUCT_TRAITS_MEMBER(selection)
- IPC_STRUCT_TRAITS_MEMBER(latency_info)
- IPC_STRUCT_TRAITS_MEMBER(referenced_surfaces)
- IPC_STRUCT_TRAITS_MEMBER(deadline)
- IPC_STRUCT_TRAITS_MEMBER(activation_dependencies)
- IPC_STRUCT_TRAITS_MEMBER(content_source_id)
- IPC_STRUCT_TRAITS_MEMBER(begin_frame_ack)
- IPC_STRUCT_TRAITS_MEMBER(frame_token)
-IPC_STRUCT_TRAITS_END()
-
-#endif // CC_IPC_CC_PARAM_TRAITS_MACROS_H_
diff --git a/chromium/cc/ipc/cc_param_traits_unittest.cc b/chromium/cc/ipc/cc_param_traits_unittest.cc
deleted file mode 100644
index 867bb9c39b0..00000000000
--- a/chromium/cc/ipc/cc_param_traits_unittest.cc
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright (c) 2012 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 <string.h>
-#include <algorithm>
-#include <utility>
-
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "cc/ipc/cc_param_traits.h"
-#include "cc/resources/resource_provider.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/frame_deadline.h"
-#include "components/viz/common/quads/picture_draw_quad.h"
-#include "components/viz/common/quads/render_pass_draw_quad.h"
-#include "ipc/ipc_message.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(OS_POSIX)
-#include "base/file_descriptor_posix.h"
-#endif
-
-using viz::CompositorFrame;
-using cc::BlurPaintFilter;
-using cc::FilterOperation;
-using cc::FilterOperations;
-using cc::ResourceProvider;
-using gfx::Transform;
-using viz::DebugBorderDrawQuad;
-using viz::DrawQuad;
-using viz::FrameDeadline;
-using viz::PictureDrawQuad;
-using viz::RenderPass;
-using viz::RenderPassDrawQuad;
-using viz::ResourceId;
-using viz::SharedQuadState;
-using viz::SolidColorDrawQuad;
-using viz::StreamVideoDrawQuad;
-using viz::SurfaceDrawQuad;
-using viz::TextureDrawQuad;
-using viz::TileDrawQuad;
-using viz::TransferableResource;
-using viz::YUVVideoDrawQuad;
-
-namespace content {
-namespace {
-
-static constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);
-
-class CCParamTraitsTest : public testing::Test {
- protected:
- void Compare(const RenderPass* a, const RenderPass* b) {
- EXPECT_EQ(a->id, b->id);
- EXPECT_EQ(a->output_rect.ToString(), b->output_rect.ToString());
- EXPECT_EQ(a->damage_rect.ToString(), b->damage_rect.ToString());
- EXPECT_EQ(a->transform_to_root_target, b->transform_to_root_target);
- EXPECT_EQ(a->filters.size(), b->filters.size());
- for (size_t i = 0; i < a->filters.size(); ++i) {
- if (a->filters.at(i).type() != cc::FilterOperation::REFERENCE) {
- EXPECT_EQ(a->filters.at(i), b->filters.at(i));
- } else {
- EXPECT_EQ(b->filters.at(i).type(), cc::FilterOperation::REFERENCE);
- EXPECT_EQ(a->filters.at(i).image_filter()->count_inputs(),
- b->filters.at(i).image_filter()->count_inputs());
- }
- }
- EXPECT_EQ(a->background_filters.size(), b->background_filters.size());
- for (size_t i = 0; i < a->background_filters.size(); ++i) {
- if (a->background_filters.at(i).type() !=
- cc::FilterOperation::REFERENCE) {
- EXPECT_EQ(a->background_filters.at(i), b->background_filters.at(i));
- } else {
- EXPECT_EQ(b->background_filters.at(i).type(),
- cc::FilterOperation::REFERENCE);
- EXPECT_EQ(a->background_filters.at(i).image_filter()->count_inputs(),
- b->background_filters.at(i).image_filter()->count_inputs());
- }
- }
- EXPECT_EQ(a->color_space, b->color_space);
- EXPECT_EQ(a->has_transparent_background, b->has_transparent_background);
- }
-
- void Compare(const SharedQuadState* a, const SharedQuadState* b) {
- EXPECT_EQ(a->quad_to_target_transform, b->quad_to_target_transform);
- EXPECT_EQ(a->quad_layer_rect, b->quad_layer_rect);
- EXPECT_EQ(a->visible_quad_layer_rect, b->visible_quad_layer_rect);
- EXPECT_EQ(a->clip_rect, b->clip_rect);
- EXPECT_EQ(a->is_clipped, b->is_clipped);
- EXPECT_EQ(a->opacity, b->opacity);
- EXPECT_EQ(a->blend_mode, b->blend_mode);
- EXPECT_EQ(a->sorting_context_id, b->sorting_context_id);
- }
-
- void Compare(const DrawQuad* a, const DrawQuad* b) {
- ASSERT_NE(DrawQuad::INVALID, a->material);
- ASSERT_EQ(a->material, b->material);
- EXPECT_EQ(a->rect.ToString(), b->rect.ToString());
- EXPECT_EQ(a->visible_rect.ToString(), b->visible_rect.ToString());
- EXPECT_EQ(a->needs_blending, b->needs_blending);
-
- Compare(a->shared_quad_state, b->shared_quad_state);
-
- switch (a->material) {
- case DrawQuad::DEBUG_BORDER:
- Compare(DebugBorderDrawQuad::MaterialCast(a),
- DebugBorderDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::PICTURE_CONTENT:
- Compare(PictureDrawQuad::MaterialCast(a),
- PictureDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::RENDER_PASS:
- Compare(RenderPassDrawQuad::MaterialCast(a),
- RenderPassDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::TEXTURE_CONTENT:
- Compare(TextureDrawQuad::MaterialCast(a),
- TextureDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::TILED_CONTENT:
- Compare(TileDrawQuad::MaterialCast(a), TileDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::SOLID_COLOR:
- Compare(SolidColorDrawQuad::MaterialCast(a),
- SolidColorDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::STREAM_VIDEO_CONTENT:
- Compare(StreamVideoDrawQuad::MaterialCast(a),
- StreamVideoDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::SURFACE_CONTENT:
- Compare(SurfaceDrawQuad::MaterialCast(a),
- SurfaceDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::YUV_VIDEO_CONTENT:
- Compare(YUVVideoDrawQuad::MaterialCast(a),
- YUVVideoDrawQuad::MaterialCast(b));
- break;
- case DrawQuad::INVALID:
- break;
- }
- }
-
- void Compare(const DebugBorderDrawQuad* a, const DebugBorderDrawQuad* b) {
- EXPECT_EQ(a->color, b->color);
- EXPECT_EQ(a->width, b->width);
- }
-
- void Compare(const RenderPassDrawQuad* a, const RenderPassDrawQuad* b) {
- EXPECT_EQ(a->render_pass_id, b->render_pass_id);
- EXPECT_EQ(a->mask_resource_id(), b->mask_resource_id());
- EXPECT_EQ(a->mask_uv_rect.ToString(), b->mask_uv_rect.ToString());
- EXPECT_EQ(a->mask_texture_size.ToString(), b->mask_texture_size.ToString());
- EXPECT_EQ(a->filters_scale, b->filters_scale);
- EXPECT_EQ(a->filters_origin, b->filters_origin);
- EXPECT_EQ(a->tex_coord_rect, b->tex_coord_rect);
- EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off);
- }
-
- void Compare(const SolidColorDrawQuad* a, const SolidColorDrawQuad* b) {
- EXPECT_EQ(a->color, b->color);
- EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off);
- }
-
- void Compare(const StreamVideoDrawQuad* a, const StreamVideoDrawQuad* b) {
- EXPECT_EQ(a->resource_id(), b->resource_id());
- EXPECT_EQ(a->resource_size_in_pixels(), b->resource_size_in_pixels());
- EXPECT_EQ(a->matrix, b->matrix);
- }
-
- void Compare(const SurfaceDrawQuad* a, const SurfaceDrawQuad* b) {
- EXPECT_EQ(a->primary_surface_id, b->primary_surface_id);
- EXPECT_EQ(a->fallback_surface_id, b->fallback_surface_id);
- EXPECT_EQ(a->default_background_color, b->default_background_color);
- EXPECT_EQ(a->stretch_content_to_fill_bounds,
- b->stretch_content_to_fill_bounds);
- }
-
- void Compare(const TextureDrawQuad* a, const TextureDrawQuad* b) {
- EXPECT_EQ(a->resource_id(), b->resource_id());
- EXPECT_EQ(a->resource_size_in_pixels(), b->resource_size_in_pixels());
- EXPECT_EQ(a->premultiplied_alpha, b->premultiplied_alpha);
- EXPECT_EQ(a->uv_top_left, b->uv_top_left);
- EXPECT_EQ(a->uv_bottom_right, b->uv_bottom_right);
- EXPECT_EQ(a->background_color, b->background_color);
- EXPECT_EQ(a->vertex_opacity[0], b->vertex_opacity[0]);
- EXPECT_EQ(a->vertex_opacity[1], b->vertex_opacity[1]);
- EXPECT_EQ(a->vertex_opacity[2], b->vertex_opacity[2]);
- EXPECT_EQ(a->vertex_opacity[3], b->vertex_opacity[3]);
- EXPECT_EQ(a->y_flipped, b->y_flipped);
- EXPECT_EQ(a->nearest_neighbor, b->nearest_neighbor);
- EXPECT_EQ(a->secure_output_only, b->secure_output_only);
- }
-
- void Compare(const TileDrawQuad* a, const TileDrawQuad* b) {
- EXPECT_EQ(a->resource_id(), b->resource_id());
- EXPECT_EQ(a->tex_coord_rect, b->tex_coord_rect);
- EXPECT_EQ(a->texture_size, b->texture_size);
- EXPECT_EQ(a->swizzle_contents, b->swizzle_contents);
- EXPECT_EQ(a->nearest_neighbor, b->nearest_neighbor);
- EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off);
- }
-
- void Compare(const YUVVideoDrawQuad* a, const YUVVideoDrawQuad* b) {
- EXPECT_EQ(a->ya_tex_coord_rect, b->ya_tex_coord_rect);
- EXPECT_EQ(a->uv_tex_coord_rect, b->uv_tex_coord_rect);
- EXPECT_EQ(a->ya_tex_size, b->ya_tex_size);
- EXPECT_EQ(a->uv_tex_size, b->uv_tex_size);
- EXPECT_EQ(a->y_plane_resource_id(), b->y_plane_resource_id());
- EXPECT_EQ(a->u_plane_resource_id(), b->u_plane_resource_id());
- EXPECT_EQ(a->v_plane_resource_id(), b->v_plane_resource_id());
- EXPECT_EQ(a->a_plane_resource_id(), b->a_plane_resource_id());
- EXPECT_EQ(a->video_color_space, b->video_color_space);
- EXPECT_EQ(a->bits_per_channel, b->bits_per_channel);
- EXPECT_EQ(a->require_overlay, b->require_overlay);
- }
-
- void Compare(const TransferableResource& a, const TransferableResource& b) {
- EXPECT_EQ(a.id, b.id);
- EXPECT_EQ(a.format, b.format);
- EXPECT_EQ(a.filter, b.filter);
- EXPECT_EQ(a.size.ToString(), b.size.ToString());
- for (size_t i = 0; i < arraysize(a.mailbox_holder.mailbox.name); ++i) {
- EXPECT_EQ(a.mailbox_holder.mailbox.name[i],
- b.mailbox_holder.mailbox.name[i]);
- }
- EXPECT_EQ(a.mailbox_holder.texture_target, b.mailbox_holder.texture_target);
- EXPECT_EQ(a.mailbox_holder.sync_token, b.mailbox_holder.sync_token);
- EXPECT_EQ(a.is_overlay_candidate, b.is_overlay_candidate);
-#if defined(OS_ANDROID)
- EXPECT_EQ(a.is_backed_by_surface_texture, b.is_backed_by_surface_texture);
- EXPECT_EQ(a.wants_promotion_hint, b.wants_promotion_hint);
-#endif
- }
-};
-
-TEST_F(CCParamTraitsTest, AllQuads) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
-
- Transform arbitrary_matrix1;
- arbitrary_matrix1.Scale(3, 3);
- arbitrary_matrix1.Translate(-5, 20);
- arbitrary_matrix1.Rotate(15);
- Transform arbitrary_matrix2;
- arbitrary_matrix2.Scale(10, -1);
- arbitrary_matrix2.Translate(20, 3);
- arbitrary_matrix2.Rotate(24);
- gfx::Rect arbitrary_rect1(-5, 9, 3, 15);
- gfx::Rect arbitrary_rect1_inside_rect1(-4, 12, 2, 8);
- gfx::Rect arbitrary_rect2(40, 23, 11, 7);
- gfx::Rect arbitrary_rect1_inside_rect2(44, 23, 4, 2);
- gfx::Rect arbitrary_rect3(7, -53, 22, 19);
- gfx::Rect arbitrary_rect2_inside_rect3(12, -51, 5, 12);
- gfx::Size arbitrary_size1(15, 19);
- gfx::Size arbitrary_size2(3, 99);
- gfx::RectF arbitrary_rectf1(4.2f, -922.1f, 15.6f, 29.5f);
- gfx::RectF arbitrary_rectf2(2.1f, -411.05f, 7.8f, 14.75f);
- gfx::PointF arbitrary_pointf1(31.4f, 15.9f);
- gfx::PointF arbitrary_pointf2(26.5f, -35.8f);
- gfx::Vector2dF arbitrary_vector2df2(-8.3f, 0.47f);
- float arbitrary_float1 = 0.7f;
- float arbitrary_float2 = 0.3f;
- float arbitrary_float3 = 0.9f;
- float arbitrary_float_array[4] = {3.5f, 6.2f, 9.3f, 12.3f};
- bool arbitrary_bool1 = true;
- bool arbitrary_bool2 = false;
- bool arbitrary_bool3 = true;
- bool arbitrary_bool4 = true;
- bool arbitrary_bool5 = false;
- bool arbitrary_bool6 = true;
- int arbitrary_context_id1 = 12;
- int arbitrary_context_id2 = 57;
- int arbitrary_context_id3 = -503;
- int arbitrary_int = 13;
- SkColor arbitrary_color = SkColorSetARGB(25, 36, 47, 58);
- SkBlendMode arbitrary_blend_mode1 = SkBlendMode::kScreen;
- SkBlendMode arbitrary_blend_mode2 = SkBlendMode::kLighten;
- SkBlendMode arbitrary_blend_mode3 = SkBlendMode::kOverlay;
- ResourceId arbitrary_resourceid1 = 55;
- ResourceId arbitrary_resourceid2 = 47;
- ResourceId arbitrary_resourceid3 = 23;
- ResourceId arbitrary_resourceid4 = 16;
- SkScalar arbitrary_sigma = SkFloatToScalar(2.0f);
- gfx::ColorSpace arbitrary_color_space = gfx::ColorSpace::CreateREC601();
-
- int child_id = 30;
- int root_id = 14;
-
- FilterOperations arbitrary_filters1;
- arbitrary_filters1.Append(
- FilterOperation::CreateGrayscaleFilter(arbitrary_float1));
- arbitrary_filters1.Append(
- FilterOperation::CreateBlurFilter(arbitrary_float2));
- arbitrary_filters1.Append(
- cc::FilterOperation::CreateReferenceFilter(sk_make_sp<BlurPaintFilter>(
- arbitrary_sigma, arbitrary_sigma,
- BlurPaintFilter::TileMode::kClampToBlack_TileMode, nullptr)));
-
- FilterOperations arbitrary_filters2;
- arbitrary_filters2.Append(
- FilterOperation::CreateBrightnessFilter(arbitrary_float2));
-
- std::unique_ptr<RenderPass> child_pass_in = RenderPass::Create();
- child_pass_in->SetAll(
- child_id, arbitrary_rect2, arbitrary_rect3, arbitrary_matrix2,
- arbitrary_filters1, arbitrary_filters2, arbitrary_color_space,
- arbitrary_bool2, arbitrary_bool3, arbitrary_bool4, arbitrary_bool5);
-
- std::unique_ptr<RenderPass> child_pass_cmp = RenderPass::Create();
- child_pass_cmp->SetAll(
- child_id, arbitrary_rect2, arbitrary_rect3, arbitrary_matrix2,
- arbitrary_filters1, arbitrary_filters2, arbitrary_color_space,
- arbitrary_bool2, arbitrary_bool3, arbitrary_bool4, arbitrary_bool5);
-
- std::unique_ptr<RenderPass> pass_in = RenderPass::Create();
- pass_in->SetAll(root_id, arbitrary_rect1, arbitrary_rect2, arbitrary_matrix1,
- arbitrary_filters2, arbitrary_filters1, arbitrary_color_space,
- arbitrary_bool1, arbitrary_bool2, arbitrary_bool3,
- arbitrary_bool4);
-
- SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state1_in->SetAll(arbitrary_matrix1, arbitrary_rect1, arbitrary_rect1,
- arbitrary_rect2, arbitrary_bool1, arbitrary_bool2,
- arbitrary_float1, arbitrary_blend_mode1,
- arbitrary_context_id1);
-
- std::unique_ptr<RenderPass> pass_cmp = RenderPass::Create();
- pass_cmp->SetAll(root_id, arbitrary_rect1, arbitrary_rect2, arbitrary_matrix1,
- arbitrary_filters2, arbitrary_filters1,
- arbitrary_color_space, arbitrary_bool1, arbitrary_bool2,
- arbitrary_bool3, arbitrary_bool4);
-
- SharedQuadState* shared_state1_cmp =
- pass_cmp->CreateAndAppendSharedQuadState();
- *shared_state1_cmp = *shared_state1_in;
-
- DebugBorderDrawQuad* debugborder_in =
- pass_in->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
- debugborder_in->SetAll(shared_state1_in, arbitrary_rect3,
- arbitrary_rect2_inside_rect3, arbitrary_bool1,
- arbitrary_color, arbitrary_int);
- pass_cmp->CopyFromAndAppendDrawQuad(debugborder_in);
-
- SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state2_in->SetAll(arbitrary_matrix2, arbitrary_rect2, arbitrary_rect2,
- arbitrary_rect3, arbitrary_bool1, arbitrary_bool1,
- arbitrary_float2, arbitrary_blend_mode2,
- arbitrary_context_id2);
- SharedQuadState* shared_state2_cmp =
- pass_cmp->CreateAndAppendSharedQuadState();
- *shared_state2_cmp = *shared_state2_in;
-
- RenderPassDrawQuad* renderpass_in =
- pass_in->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
- renderpass_in->SetAll(shared_state2_in, arbitrary_rect1,
- arbitrary_rect1_inside_rect1, arbitrary_bool1, child_id,
- arbitrary_resourceid2, arbitrary_rectf1,
- arbitrary_size1, arbitrary_vector2df2,
- arbitrary_pointf2, arbitrary_rectf1, arbitrary_bool2);
- pass_cmp->CopyFromAndAppendRenderPassDrawQuad(renderpass_in,
- renderpass_in->render_pass_id);
-
- SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state3_in->SetAll(arbitrary_matrix1, arbitrary_rect3, arbitrary_rect3,
- arbitrary_rect1, arbitrary_bool1, arbitrary_bool2,
- arbitrary_float3, arbitrary_blend_mode3,
- arbitrary_context_id3);
- SharedQuadState* shared_state3_cmp =
- pass_cmp->CreateAndAppendSharedQuadState();
- *shared_state3_cmp = *shared_state3_in;
-
- auto* solidcolor_in = pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- solidcolor_in->SetAll(shared_state3_in, arbitrary_rect3,
- arbitrary_rect2_inside_rect3, arbitrary_bool1,
- arbitrary_color, arbitrary_bool2);
- pass_cmp->CopyFromAndAppendDrawQuad(solidcolor_in);
-
- StreamVideoDrawQuad* streamvideo_in =
- pass_in->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
- streamvideo_in->SetAll(shared_state3_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid2, arbitrary_size1,
- arbitrary_matrix1);
- pass_cmp->CopyFromAndAppendDrawQuad(streamvideo_in);
-
- viz::SurfaceId arbitrary_surface_id(
- kArbitraryFrameSinkId,
- viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
- SurfaceDrawQuad* surface_in =
- pass_in->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
- surface_in->SetAll(shared_state3_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_surface_id, base::nullopt, SK_ColorWHITE, true);
- pass_cmp->CopyFromAndAppendDrawQuad(surface_in);
-
- TextureDrawQuad* texture_in =
- pass_in->CreateAndAppendDrawQuad<TextureDrawQuad>();
- texture_in->SetAll(
- shared_state3_in, arbitrary_rect2, arbitrary_rect1_inside_rect2,
- arbitrary_bool1, arbitrary_resourceid1, arbitrary_size1, arbitrary_bool2,
- arbitrary_pointf1, arbitrary_pointf2, arbitrary_color,
- arbitrary_float_array, arbitrary_bool4, arbitrary_bool5, arbitrary_bool6);
- pass_cmp->CopyFromAndAppendDrawQuad(texture_in);
-
- TileDrawQuad* tile_in = pass_in->CreateAndAppendDrawQuad<TileDrawQuad>();
- tile_in->SetAll(
- shared_state3_in, arbitrary_rect2, arbitrary_rect1_inside_rect2,
- arbitrary_bool1, arbitrary_resourceid3, arbitrary_rectf1, arbitrary_size1,
- arbitrary_bool2, arbitrary_bool3, arbitrary_bool4, arbitrary_bool5);
- pass_cmp->CopyFromAndAppendDrawQuad(tile_in);
-
- YUVVideoDrawQuad* yuvvideo_in =
- pass_in->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
- yuvvideo_in->SetAll(
- shared_state3_in, arbitrary_rect1, arbitrary_rect1_inside_rect1,
- arbitrary_bool1, arbitrary_rectf1, arbitrary_rectf2, arbitrary_size1,
- arbitrary_size2, arbitrary_resourceid1, arbitrary_resourceid2,
- arbitrary_resourceid3, arbitrary_resourceid4, arbitrary_color_space,
- arbitrary_float1, arbitrary_float2, arbitrary_int, arbitrary_bool2);
- pass_cmp->CopyFromAndAppendDrawQuad(yuvvideo_in);
-
- // Make sure the in and cmp RenderPasses match.
- Compare(child_pass_cmp.get(), child_pass_in.get());
- ASSERT_EQ(0u, child_pass_in->shared_quad_state_list.size());
- ASSERT_EQ(0u, child_pass_in->quad_list.size());
- Compare(pass_cmp.get(), pass_in.get());
- ASSERT_EQ(3u, pass_in->shared_quad_state_list.size());
- ASSERT_EQ(8u, pass_in->quad_list.size());
- for (auto cmp_iterator = pass_cmp->shared_quad_state_list.cbegin(),
- in_iterator = pass_in->shared_quad_state_list.cbegin();
- in_iterator != pass_in->shared_quad_state_list.cend();
- ++cmp_iterator, ++in_iterator) {
- Compare(*cmp_iterator, *in_iterator);
- }
- for (auto in_iter = pass_in->quad_list.cbegin(),
- cmp_iter = pass_cmp->quad_list.cbegin();
- in_iter != pass_in->quad_list.cend(); ++in_iter, ++cmp_iter)
- Compare(*cmp_iter, *in_iter);
-
- for (size_t i = 1; i < pass_in->quad_list.size(); ++i) {
- bool same_shared_quad_state_cmp =
- pass_cmp->quad_list.ElementAt(i)->shared_quad_state ==
- pass_cmp->quad_list.ElementAt(i - 1)->shared_quad_state;
- bool same_shared_quad_state_in =
- pass_in->quad_list.ElementAt(i)->shared_quad_state ==
- pass_in->quad_list.ElementAt(i - 1)->shared_quad_state;
- EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_in);
- }
-
- CompositorFrame frame_in;
- frame_in.render_pass_list.push_back(std::move(child_pass_in));
- frame_in.render_pass_list.push_back(std::move(pass_in));
- frame_in.metadata.begin_frame_ack.sequence_number =
- viz::BeginFrameArgs::kStartingFrameNumber;
- const base::TimeTicks now = base::TimeTicks::Now();
- frame_in.metadata.deadline =
- FrameDeadline(now, 4u, base::TimeDelta::FromMilliseconds(16), true);
-
- IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in);
-
- CompositorFrame frame_out;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(IPC::ParamTraits<CompositorFrame>::Read(&msg, &iter, &frame_out));
-
- EXPECT_EQ(FrameDeadline(now, 4u, base::TimeDelta::FromMilliseconds(16), true),
- frame_out.metadata.deadline);
-
- // Make sure the out and cmp RenderPasses match.
- std::unique_ptr<RenderPass> child_pass_out =
- std::move(frame_out.render_pass_list[0]);
- Compare(child_pass_cmp.get(), child_pass_out.get());
- ASSERT_EQ(0u, child_pass_out->shared_quad_state_list.size());
- ASSERT_EQ(0u, child_pass_out->quad_list.size());
- std::unique_ptr<RenderPass> pass_out =
- std::move(frame_out.render_pass_list[1]);
- Compare(pass_cmp.get(), pass_out.get());
- ASSERT_EQ(3u, pass_out->shared_quad_state_list.size());
- ASSERT_EQ(8u, pass_out->quad_list.size());
- for (auto cmp_iterator = pass_cmp->shared_quad_state_list.cbegin(),
- out_iterator = pass_out->shared_quad_state_list.cbegin();
- out_iterator != pass_out->shared_quad_state_list.cend();
- ++cmp_iterator, ++out_iterator) {
- Compare(*cmp_iterator, *out_iterator);
- }
- for (auto out_iter = pass_out->quad_list.cbegin(),
- cmp_iter = pass_cmp->quad_list.cbegin();
- out_iter != pass_out->quad_list.cend(); ++out_iter, ++cmp_iter)
- Compare(*cmp_iter, *out_iter);
-
- for (size_t i = 1; i < pass_out->quad_list.size(); ++i) {
- bool same_shared_quad_state_cmp =
- pass_cmp->quad_list.ElementAt(i)->shared_quad_state ==
- pass_cmp->quad_list.ElementAt(i - 1)->shared_quad_state;
- bool same_shared_quad_state_out =
- pass_out->quad_list.ElementAt(i)->shared_quad_state ==
- pass_out->quad_list.ElementAt(i - 1)->shared_quad_state;
- EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_out);
- }
-}
-
-TEST_F(CCParamTraitsTest, UnusedSharedQuadStates) {
- std::unique_ptr<RenderPass> pass_in = RenderPass::Create();
- pass_in->SetAll(1, gfx::Rect(100, 100), gfx::Rect(), gfx::Transform(),
- FilterOperations(), FilterOperations(),
- gfx::ColorSpace::CreateSRGB(), false, false, false, false);
-
- // The first SharedQuadState is used.
- SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state1_in->SetAll(gfx::Transform(), gfx::Rect(1, 1), gfx::Rect(),
- gfx::Rect(), false, true, 1.f, SkBlendMode::kSrcOver,
- 0);
-
- auto* quad1 = pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- quad1->SetAll(shared_state1_in, gfx::Rect(10, 10), gfx::Rect(10, 10), false,
- SK_ColorRED, false);
-
- // The second and third SharedQuadStates are not used.
- SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state2_in->SetAll(gfx::Transform(), gfx::Rect(2, 2), gfx::Rect(),
- gfx::Rect(), false, true, 1.f, SkBlendMode::kSrcOver,
- 0);
-
- SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state3_in->SetAll(gfx::Transform(), gfx::Rect(3, 3), gfx::Rect(),
- gfx::Rect(), false, true, 1.f, SkBlendMode::kSrcOver,
- 0);
-
- // The fourth SharedQuadState is used.
- SharedQuadState* shared_state4_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state4_in->SetAll(gfx::Transform(), gfx::Rect(4, 4), gfx::Rect(),
- gfx::Rect(), false, true, 1.f, SkBlendMode::kSrcOver,
- 0);
-
- auto* quad2 = pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- quad2->SetAll(shared_state4_in, gfx::Rect(10, 10), gfx::Rect(10, 10), false,
- SK_ColorRED, false);
-
- // The fifth is not used again.
- SharedQuadState* shared_state5_in = pass_in->CreateAndAppendSharedQuadState();
- shared_state5_in->SetAll(gfx::Transform(), gfx::Rect(5, 5), gfx::Rect(),
- gfx::Rect(), false, true, 1.f, SkBlendMode::kSrcOver,
- 0);
-
- // 5 SharedQuadStates go in.
- ASSERT_EQ(5u, pass_in->shared_quad_state_list.size());
- ASSERT_EQ(2u, pass_in->quad_list.size());
-
- CompositorFrame frame_in;
- frame_in.render_pass_list.push_back(std::move(pass_in));
- frame_in.metadata.begin_frame_ack.sequence_number =
- viz::BeginFrameArgs::kStartingFrameNumber;
-
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in);
-
- CompositorFrame frame_out;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(IPC::ParamTraits<CompositorFrame>::Read(&msg, &iter, &frame_out));
-
- std::unique_ptr<RenderPass> pass_out =
- std::move(frame_out.render_pass_list[0]);
-
- // 2 SharedQuadStates come out. The first and fourth SharedQuadStates were
- // used by quads, and so serialized. Others were not.
- ASSERT_EQ(2u, pass_out->shared_quad_state_list.size());
- ASSERT_EQ(2u, pass_out->quad_list.size());
-
- EXPECT_EQ(gfx::Rect(1, 1).ToString(),
- pass_out->shared_quad_state_list.ElementAt(0)
- ->quad_layer_rect.ToString());
- EXPECT_EQ(gfx::Rect(4, 4).ToString(),
- pass_out->shared_quad_state_list.ElementAt(1)
- ->quad_layer_rect.ToString());
-}
-
-TEST_F(CCParamTraitsTest, Resources) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- gpu::SyncToken arbitrary_token1(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x123),
- 71234838);
- arbitrary_token1.SetVerifyFlush();
- gpu::SyncToken arbitrary_token2(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x123),
- 53589793);
- arbitrary_token2.SetVerifyFlush();
-
- GLbyte arbitrary_mailbox1[GL_MAILBOX_SIZE_CHROMIUM] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6};
-
- GLbyte arbitrary_mailbox2[GL_MAILBOX_SIZE_CHROMIUM] = {
- 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2};
-
- TransferableResource arbitrary_resource1;
- arbitrary_resource1.id = 2178312;
- arbitrary_resource1.format = viz::RGBA_8888;
- arbitrary_resource1.filter = 53;
- arbitrary_resource1.size = gfx::Size(37189, 123123);
- arbitrary_resource1.mailbox_holder.mailbox.SetName(arbitrary_mailbox1);
- arbitrary_resource1.mailbox_holder.texture_target = GL_TEXTURE_2D;
- arbitrary_resource1.mailbox_holder.sync_token = arbitrary_token1;
- arbitrary_resource1.is_overlay_candidate = true;
-#if defined(OS_ANDROID)
- arbitrary_resource1.is_backed_by_surface_texture = true;
- arbitrary_resource1.wants_promotion_hint = true;
-#endif
-
- TransferableResource arbitrary_resource2;
- arbitrary_resource2.id = 789132;
- arbitrary_resource2.format = viz::RGBA_4444;
- arbitrary_resource2.filter = 47;
- arbitrary_resource2.size = gfx::Size(89123, 23789);
- arbitrary_resource2.mailbox_holder.mailbox.SetName(arbitrary_mailbox2);
- arbitrary_resource2.mailbox_holder.texture_target = GL_TEXTURE_EXTERNAL_OES;
- arbitrary_resource2.mailbox_holder.sync_token = arbitrary_token2;
- arbitrary_resource2.is_overlay_candidate = false;
-#if defined(OS_ANDROID)
- arbitrary_resource2.is_backed_by_surface_texture = false;
- arbitrary_resource2.wants_promotion_hint = false;
-#endif
-
- std::unique_ptr<RenderPass> renderpass_in = RenderPass::Create();
- renderpass_in->SetNew(1u, gfx::Rect(0, 0, 5, 5), gfx::Rect(),
- gfx::Transform());
-
- CompositorFrame frame_in;
- frame_in.resource_list.push_back(arbitrary_resource1);
- frame_in.resource_list.push_back(arbitrary_resource2);
- frame_in.render_pass_list.push_back(std::move(renderpass_in));
- frame_in.metadata.begin_frame_ack.sequence_number =
- viz::BeginFrameArgs::kStartingFrameNumber;
-
- IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in);
-
- CompositorFrame frame_out;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(IPC::ParamTraits<CompositorFrame>::Read(&msg, &iter, &frame_out));
-
- ASSERT_EQ(2u, frame_out.resource_list.size());
- Compare(arbitrary_resource1, frame_out.resource_list[0]);
- Compare(arbitrary_resource2, frame_out.resource_list[1]);
-}
-
-TEST_F(CCParamTraitsTest, SurfaceInfo) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- const viz::SurfaceId kArbitrarySurfaceId(
- kArbitraryFrameSinkId,
- viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
- constexpr float kArbitraryDeviceScaleFactor = 0.9f;
- const gfx::Size kArbitrarySize(65, 321);
- const viz::SurfaceInfo surface_info_in(
- kArbitrarySurfaceId, kArbitraryDeviceScaleFactor, kArbitrarySize);
- IPC::ParamTraits<viz::SurfaceInfo>::Write(&msg, surface_info_in);
-
- viz::SurfaceInfo surface_info_out;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(
- IPC::ParamTraits<viz::SurfaceInfo>::Read(&msg, &iter, &surface_info_out));
-
- ASSERT_EQ(surface_info_in, surface_info_out);
-}
-
-} // namespace
-} // namespace content
diff --git a/chromium/cc/ipc/cc_serialization_perftest.cc b/chromium/cc/ipc/cc_serialization_perftest.cc
deleted file mode 100644
index 7dc52dcff3f..00000000000
--- a/chromium/cc/ipc/cc_serialization_perftest.cc
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "cc/ipc/cc_param_traits.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/picture_draw_quad.h"
-#include "components/viz/test/compositor_frame_helpers.h"
-#include "gpu/ipc/common/mailbox_holder_struct_traits.h"
-#include "gpu/ipc/common/mailbox_struct_traits.h"
-#include "gpu/ipc/common/sync_token_struct_traits.h"
-#include "ipc/ipc_message.h"
-#include "mojo/public/cpp/base/time_mojom_traits.h"
-#include "mojo/public/cpp/bindings/message.h"
-#include "services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h"
-#include "services/viz/public/cpp/compositing/compositor_frame_struct_traits.h"
-#include "services/viz/public/cpp/compositing/render_pass_struct_traits.h"
-#include "services/viz/public/cpp/compositing/selection_struct_traits.h"
-#include "services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h"
-#include "services/viz/public/cpp/compositing/surface_id_struct_traits.h"
-#include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-#include "ui/gfx/geometry/mojo/geometry.mojom.h"
-#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
-#include "ui/gfx/mojo/selection_bound_struct_traits.h"
-#include "ui/latency/mojo/latency_info_struct_traits.h"
-
-namespace cc {
-namespace {
-
-static const int kTimeLimitMillis = 2000;
-static const int kNumWarmupRuns = 20;
-static const int kTimeCheckInterval = 10;
-
-enum class UseSingleSharedQuadState { YES, NO };
-
-class CCSerializationPerfTest : public testing::Test {
- protected:
- static void ReadMessage(const IPC::Message* msg,
- viz::CompositorFrame* frame) {
- base::PickleIterator iter(*msg);
- bool success =
- IPC::ParamTraits<viz::CompositorFrame>::Read(msg, &iter, frame);
- CHECK(success);
- }
-
- static void RunDeserializationTestParamTraits(
- const std::string& test_name,
- const viz::CompositorFrame& frame,
- UseSingleSharedQuadState single_sqs) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<viz::CompositorFrame>::Write(&msg, frame);
- for (int i = 0; i < kNumWarmupRuns; ++i) {
- viz::CompositorFrame compositor_frame;
- ReadMessage(&msg, &compositor_frame);
- }
-
- base::TimeTicks start = base::TimeTicks::Now();
- base::TimeTicks end =
- start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis);
- base::TimeTicks now = start;
- base::TimeDelta min_time;
- size_t count = 0;
- while (start < end) {
- for (int i = 0; i < kTimeCheckInterval; ++i) {
- viz::CompositorFrame compositor_frame;
- ReadMessage(&msg, &compositor_frame);
- now = base::TimeTicks::Now();
- // We don't count iterations after the end time.
- if (now < end)
- ++count;
- }
-
- if (now - start < min_time || min_time.is_zero())
- min_time = now - start;
- start = now;
- }
-
- perf_test::PrintResult(
- "ParamTraits deserialization: min_frame_deserialization_time",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, min_time.InMillisecondsF() / kTimeCheckInterval * 1000, "us",
- true);
- perf_test::PrintResult("ParamTraits deserialization: num runs in 2 seconds",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, count, "runs/s", true);
- }
-
- static void RunSerializationTestParamTraits(
- const std::string& test_name,
- const viz::CompositorFrame& frame,
- UseSingleSharedQuadState single_sqs) {
- for (int i = 0; i < kNumWarmupRuns; ++i) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<viz::CompositorFrame>::Write(&msg, frame);
- }
-
- base::TimeTicks start = base::TimeTicks::Now();
- base::TimeTicks end =
- start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis);
- base::TimeTicks now = start;
- base::TimeDelta min_time;
- size_t count = 0;
- while (start < end) {
- for (int i = 0; i < kTimeCheckInterval; ++i) {
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<viz::CompositorFrame>::Write(&msg, frame);
- now = base::TimeTicks::Now();
- // We don't count iterations after the end time.
- if (now < end)
- ++count;
- }
-
- if (now - start < min_time || min_time.is_zero())
- min_time = now - start;
- start = now;
- }
-
- perf_test::PrintResult(
- "ParamTraits serialization: min_frame_serialization_time",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, min_time.InMillisecondsF() / kTimeCheckInterval * 1000, "us",
- true);
- perf_test::PrintResult("ParamTraits serialization: num runs in 2 seconds",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, count, "runs/s", true);
- }
-
- static void RunDeserializationTestStructTraits(
- const std::string& test_name,
- const viz::CompositorFrame& frame,
- UseSingleSharedQuadState single_sqs) {
- mojo::Message message =
- viz::mojom::CompositorFrame::SerializeAsMessage(&frame);
- for (int i = 0; i < kNumWarmupRuns; ++i) {
- viz::CompositorFrame compositor_frame;
- viz::mojom::CompositorFrame::Deserialize(
- message.payload(), message.payload_num_bytes(), &compositor_frame);
- }
-
- base::TimeTicks start = base::TimeTicks::Now();
- base::TimeTicks end =
- start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis);
- base::TimeTicks now = start;
- base::TimeDelta min_time;
- size_t count = 0;
- while (start < end) {
- for (int i = 0; i < kTimeCheckInterval; ++i) {
- viz::CompositorFrame compositor_frame;
- viz::mojom::CompositorFrame::Deserialize(
- message.payload(), message.payload_num_bytes(), &compositor_frame);
- now = base::TimeTicks::Now();
- // We don't count iterations after the end time.
- if (now < end)
- ++count;
- }
-
- if (now - start < min_time || min_time.is_zero())
- min_time = now - start;
- start = now;
- }
-
- perf_test::PrintResult(
- "StructTraits deserialization min_frame_deserialization_time",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, min_time.InMillisecondsF() / kTimeCheckInterval * 1000, "us",
- true);
- perf_test::PrintResult(
- "StructTraits deserialization: num runs in 2 seconds",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, count, "runs/s", true);
- }
-
- static void RunSerializationTestStructTraits(
- const std::string& test_name,
- const viz::CompositorFrame& frame,
- UseSingleSharedQuadState single_sqs) {
- for (int i = 0; i < kNumWarmupRuns; ++i) {
- mojo::Message message =
- viz::mojom::CompositorFrame::SerializeAsMessage(&frame);
- }
-
- base::TimeTicks start = base::TimeTicks::Now();
- base::TimeTicks end =
- start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis);
- base::TimeTicks now = start;
- base::TimeDelta min_time;
- size_t count = 0;
- while (start < end) {
- for (int i = 0; i < kTimeCheckInterval; ++i) {
- mojo::Message message =
- viz::mojom::CompositorFrame::SerializeAsMessage(&frame);
- now = base::TimeTicks::Now();
- // We don't count iterations after the end time.
- if (now < end)
- ++count;
- }
-
- if (now - start < min_time || min_time.is_zero())
- min_time = now - start;
- start = now;
- }
-
- perf_test::PrintResult(
- "StructTraits serialization min_frame_serialization_time",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, min_time.InMillisecondsF() / kTimeCheckInterval * 1000, "us",
- true);
- perf_test::PrintResult("StructTraits serialization: num runs in 2 seconds",
- single_sqs == UseSingleSharedQuadState::YES
- ? "_per_render_pass_shared_quad_state"
- : "_per_quad_shared_quad_state",
- test_name, count, "runs/s", true);
- }
-
- static void RunComplexCompositorFrameTest(const std::string& test_name) {
- viz::CompositorFrame frame;
- frame.metadata.begin_frame_ack = viz::BeginFrameAck(0, 1, true);
-
- std::vector<viz::TransferableResource>& resource_list = frame.resource_list;
- for (uint32_t i = 0; i < 80; ++i) {
- viz::TransferableResource arbitrary_resource;
- resource_list.push_back(arbitrary_resource);
- }
-
- auto& render_pass_list = frame.render_pass_list;
-
- gfx::Transform arbitrary_matrix1;
- arbitrary_matrix1.Scale(3, 3);
- arbitrary_matrix1.Translate(-5, 20);
- arbitrary_matrix1.Rotate(15);
- gfx::Transform arbitrary_matrix2;
- arbitrary_matrix2.Scale(10, -1);
- arbitrary_matrix2.Translate(20, 3);
- arbitrary_matrix2.Rotate(24);
- gfx::Rect arbitrary_rect1(-5, 9, 3, 15);
- gfx::Rect arbitrary_rect2(40, 23, 11, 7);
- gfx::Rect arbitrary_rect1_inside_rect2(44, 23, 4, 2);
- gfx::Rect arbitrary_rect3(7, -53, 22, 19);
- gfx::Rect arbitrary_rect2_inside_rect3(12, -51, 5, 12);
- gfx::Size arbitrary_size1(15, 19);
- gfx::Size arbitrary_size2(3, 99);
- gfx::RectF arbitrary_rectf1(4.2f, -922.1f, 15.6f, 29.5f);
- gfx::PointF arbitrary_pointf1(31.4f, 15.9f);
- gfx::PointF arbitrary_pointf2(26.5f, -35.8f);
- float arbitrary_float1 = 0.7f;
- float arbitrary_float2 = 0.3f;
- float arbitrary_float3 = 0.9f;
- float arbitrary_float_array[4] = {3.5f, 6.2f, 9.3f, 12.3f};
- bool arbitrary_bool1 = true;
- bool arbitrary_bool2 = false;
- bool arbitrary_bool3 = true;
- bool arbitrary_bool4 = true;
- bool arbitrary_bool5 = false;
- bool arbitrary_bool6 = true;
- int arbitrary_context_id1 = 12;
- int arbitrary_context_id2 = 57;
- int arbitrary_context_id3 = -503;
- SkColor arbitrary_color = SkColorSetARGB(25, 36, 47, 58);
- SkBlendMode arbitrary_blend_mode1 = SkBlendMode::kScreen;
- SkBlendMode arbitrary_blend_mode2 = SkBlendMode::kLighten;
- SkBlendMode arbitrary_blend_mode3 = SkBlendMode::kOverlay;
- viz::ResourceId arbitrary_resourceid1 = 55;
- viz::ResourceId arbitrary_resourceid2 = 47;
- viz::ResourceId arbitrary_resourceid3 = 23;
- viz::ResourceId arbitrary_resourceid4 = 16;
- SkScalar arbitrary_sigma = SkFloatToScalar(2.0f);
- gfx::ColorSpace arbitrary_color_space = gfx::ColorSpace::CreateXYZD50();
- int root_id = 14;
-
- FilterOperations arbitrary_filters1;
- arbitrary_filters1.Append(
- FilterOperation::CreateGrayscaleFilter(arbitrary_float1));
- arbitrary_filters1.Append(
- FilterOperation::CreateReferenceFilter(sk_make_sp<BlurPaintFilter>(
- arbitrary_sigma, arbitrary_sigma,
- BlurPaintFilter::TileMode::kClampToBlack_TileMode, nullptr)));
-
- FilterOperations arbitrary_filters2;
- arbitrary_filters2.Append(
- FilterOperation::CreateBrightnessFilter(arbitrary_float2));
-
- std::unique_ptr<viz::RenderPass> pass_in = viz::RenderPass::Create();
- pass_in->SetAll(root_id, arbitrary_rect1, arbitrary_rect2,
- arbitrary_matrix1, arbitrary_filters2, arbitrary_filters1,
- arbitrary_color_space, arbitrary_bool1, arbitrary_bool1,
- arbitrary_bool1, arbitrary_bool1);
-
- // Texture quads
- for (uint32_t i = 0; i < 10; ++i) {
- viz::SharedQuadState* shared_state1_in =
- pass_in->CreateAndAppendSharedQuadState();
- shared_state1_in->SetAll(
- arbitrary_matrix1, arbitrary_rect1, arbitrary_rect1, arbitrary_rect2,
- arbitrary_bool1, arbitrary_bool1, arbitrary_float1,
- arbitrary_blend_mode1, arbitrary_context_id1);
-
- auto* texture_in =
- pass_in->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- texture_in->SetAll(shared_state1_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid1, arbitrary_size1,
- arbitrary_bool1, arbitrary_pointf1, arbitrary_pointf2,
- arbitrary_color, arbitrary_float_array,
- arbitrary_bool4, arbitrary_bool5, arbitrary_bool6);
-
- auto* texture_in2 =
- pass_in->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- texture_in2->SetAll(shared_state1_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid2, arbitrary_size1,
- arbitrary_bool3, arbitrary_pointf1, arbitrary_pointf2,
- arbitrary_color, arbitrary_float_array,
- arbitrary_bool4, arbitrary_bool5, arbitrary_bool6);
-
- auto* texture_in3 =
- pass_in->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- texture_in3->SetAll(shared_state1_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid3, arbitrary_size1,
- arbitrary_bool2, arbitrary_pointf1, arbitrary_pointf2,
- arbitrary_color, arbitrary_float_array,
- arbitrary_bool4, arbitrary_bool6, arbitrary_bool6);
-
- auto* texture_in4 =
- pass_in->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- texture_in4->SetAll(shared_state1_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid4, arbitrary_size2,
- arbitrary_bool4, arbitrary_pointf1, arbitrary_pointf2,
- arbitrary_color, arbitrary_float_array,
- arbitrary_bool4, arbitrary_bool5, arbitrary_bool6);
- }
-
- // Tiled quads
- for (uint32_t i = 0; i < 10; ++i) {
- viz::SharedQuadState* shared_state2_in =
- pass_in->CreateAndAppendSharedQuadState();
- shared_state2_in->SetAll(
- arbitrary_matrix2, arbitrary_rect2, arbitrary_rect2, arbitrary_rect3,
- arbitrary_bool1, arbitrary_bool1, arbitrary_float2,
- arbitrary_blend_mode2, arbitrary_context_id2);
- for (uint32_t j = 0; j < 6; ++j) {
- auto* tile_in = pass_in->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
- tile_in->SetAll(shared_state2_in, arbitrary_rect2,
- arbitrary_rect1_inside_rect2, arbitrary_bool1,
- arbitrary_resourceid3, arbitrary_rectf1,
- arbitrary_size1, arbitrary_bool2, arbitrary_bool3,
- arbitrary_bool4, arbitrary_bool5);
- }
- }
-
- // Solid color quads
- for (uint32_t i = 0; i < 5; ++i) {
- viz::SharedQuadState* shared_state3_in =
- pass_in->CreateAndAppendSharedQuadState();
- shared_state3_in->SetAll(
- arbitrary_matrix1, arbitrary_rect3, arbitrary_rect3, arbitrary_rect1,
- arbitrary_bool1, arbitrary_bool1, arbitrary_float3,
- arbitrary_blend_mode3, arbitrary_context_id3);
- for (uint32_t j = 0; j < 5; ++j) {
- auto* solidcolor_in =
- pass_in->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- solidcolor_in->SetAll(shared_state3_in, arbitrary_rect3,
- arbitrary_rect2_inside_rect3, arbitrary_bool1,
- arbitrary_color, arbitrary_bool2);
- }
- }
-
- render_pass_list.push_back(std::move(pass_in));
- RunTest(test_name, std::move(frame), UseSingleSharedQuadState::NO);
- }
-
- static void RunCompositorFrameTest(const std::string& test_name,
- uint32_t num_quads,
- uint32_t num_passes,
- UseSingleSharedQuadState single_sqs) {
- viz::CompositorFrame frame = viz::MakeEmptyCompositorFrame();
-
- for (uint32_t i = 0; i < num_passes; ++i) {
- std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
- render_pass->SetNew(1, gfx::Rect(20, 20), gfx::Rect(), gfx::Transform());
- for (uint32_t j = 0; j < num_quads; ++j) {
- if (j == 0 || single_sqs == UseSingleSharedQuadState::NO)
- render_pass->CreateAndAppendSharedQuadState();
- const gfx::Rect bounds(100, 100, 100, 100);
- const bool kForceAntiAliasingOff = true;
- auto* quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- quad->SetNew(render_pass->shared_quad_state_list.back(), bounds, bounds,
- SK_ColorRED, kForceAntiAliasingOff);
- }
- frame.render_pass_list.push_back(std::move(render_pass));
- }
- RunTest(test_name, std::move(frame), single_sqs);
- }
-
- static void RunTest(const std::string& test_name,
- viz::CompositorFrame frame,
- UseSingleSharedQuadState single_sqs) {
- RunSerializationTestStructTraits(test_name, frame, single_sqs);
- RunDeserializationTestStructTraits(test_name, frame, single_sqs);
- RunSerializationTestParamTraits(test_name, frame, single_sqs);
- RunDeserializationTestParamTraits(test_name, frame, single_sqs);
- }
-};
-
-// Test for compositor frames with one render pass, 80 resources in resource
-// list, 10 shared quad states with 4 texture quads each, 10 shared quad states
-// with 6 tiled quads each, and 5 shared quad states with 5 solid color quads
-// each.
-TEST_F(CCSerializationPerfTest, DelegatedFrame_Complex) {
- RunComplexCompositorFrameTest("DelegatedFrame_Complex");
-}
-
-// Test for compositor frames with one render pass and 4000 quads.
-TEST_F(CCSerializationPerfTest, DelegatedFrame_ManyQuads_1_4000) {
- // Case 1: One shared quad state for all quads in one render pass.
- RunCompositorFrameTest("DelegatedFrame_ManyQuads_1_4000", 4000, 1,
- UseSingleSharedQuadState::YES);
- // Case 2: One shared quad state for each quad.
- RunCompositorFrameTest("DelegatedFrame_ManyQuads_1_4000", 4000, 1,
- UseSingleSharedQuadState::NO);
-}
-
-// Test for compositor frames with 5 render pass and each with 100 quads.
-TEST_F(CCSerializationPerfTest, DelegatedFrame_ManyRenderPasses_5_100) {
- // Case 1: One shared quad state for all quads in one render pass.
- RunCompositorFrameTest("DelegatedFrame_ManyRenderPasses_5_100", 100, 5,
- UseSingleSharedQuadState::YES);
- // Case 2: One shared quad state for each quad.
- RunCompositorFrameTest("DelegatedFrame_ManyRenderPasses_5_100", 100, 5,
- UseSingleSharedQuadState::NO);
-}
-
-// Test for compositor frames with 10 render pass and each with 500 quads.
-TEST_F(CCSerializationPerfTest, DelegatedFrame_ManyRenderPasses_10_500) {
- // Case 1: One shared quad state for all quads in one render pass.
- RunCompositorFrameTest("DelegatedFrame_ManyRenderPasses_10_500", 500, 10,
- UseSingleSharedQuadState::YES);
- // Case 2: One shared quad state for each quad.
- RunCompositorFrameTest("DelegatedFrame_ManyRenderPasses_10_500", 500, 10,
- UseSingleSharedQuadState::NO);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/layers/content_layer_client.h b/chromium/cc/layers/content_layer_client.h
index c5d005f85a2..7f61a99ccef 100644
--- a/chromium/cc/layers/content_layer_client.h
+++ b/chromium/cc/layers/content_layer_client.h
@@ -34,8 +34,12 @@ class CC_EXPORT ContentLayerClient {
// that is guaranteed valid only within this region.
virtual gfx::Rect PaintableRegion() = 0;
+ // Paints the content area for the layer, typically dirty rects submitted
+ // to the layer itself, into a DisplayItemList that it returns. The
+ // PaintingControlSetting enum controls painting to isolate different
+ // components in performance tests.
virtual scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting painting_status) = 0;
+ PaintingControlSetting painting_control) = 0;
// If true the layer may skip clearing the background before rasterizing,
// because it will cover any uncleared data with content.
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index 8f2a21ea3fd..890f7ec426c 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -11,6 +11,7 @@
#include <vector>
#include "base/numerics/safe_conversions.h"
+#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
@@ -28,6 +29,7 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
+#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 "skia/ext/platform_canvas.h"
@@ -138,12 +140,12 @@ bool HeadsUpDisplayLayerImpl::WillDraw(
if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
return false;
+ int max_texture_size = layer_tree_impl()->max_texture_size();
internal_contents_scale_ = GetIdealContentsScale();
internal_content_bounds_ =
gfx::ScaleToCeiledSize(bounds(), internal_contents_scale_);
internal_content_bounds_.SetToMin(
- gfx::Size(resource_provider->max_texture_size(),
- resource_provider->max_texture_size()));
+ gfx::Size(max_texture_size, max_texture_size));
return LayerImpl::WillDraw(draw_mode, resource_provider);
}
@@ -185,17 +187,10 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
layer_tree_impl()->task_runner_provider()->HasImplThread()
? layer_tree_impl()->task_runner_provider()->ImplThreadTaskRunner()
: layer_tree_impl()->task_runner_provider()->MainThreadTaskRunner();
- if (draw_mode == DRAW_MODE_HARDWARE) {
- pool_ = std::make_unique<ResourcePool>(
- resource_provider, std::move(task_runner),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- layer_tree_impl()->settings().disallow_non_exact_resource_reuse);
- } else {
- pool_ = std::make_unique<ResourcePool>(
- resource_provider, std::move(task_runner),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kSoftware,
- layer_tree_impl()->settings().disallow_non_exact_resource_reuse);
- }
+ pool_ = std::make_unique<ResourcePool>(
+ resource_provider, layer_tree_frame_sink->context_provider(),
+ std::move(task_runner), ResourcePool::kDefaultExpirationDelay,
+ layer_tree_impl()->settings().disallow_non_exact_resource_reuse);
}
// Return ownership of the previous frame's resource to the pool, so we
@@ -205,17 +200,20 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
if (in_flight_resource_)
pool_->ReleaseResource(std::move(in_flight_resource_));
- ResourcePool::InUsePoolResource pool_resource = pool_->AcquireResource(
- internal_content_bounds_, resource_provider->best_render_buffer_format(),
- gfx::ColorSpace());
-
// Allocate a backing for the resource if needed, either for gpu or software
// compositing.
+ ResourcePool::InUsePoolResource pool_resource;
if (draw_mode == DRAW_MODE_HARDWARE) {
viz::ContextProvider* context_provider =
layer_tree_impl()->context_provider();
DCHECK(context_provider);
+ viz::ResourceFormat format =
+ viz::PlatformColor::BestSupportedRenderBufferFormat(
+ context_provider->ContextCapabilities());
+ 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;
@@ -245,6 +243,9 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
} else {
DCHECK_EQ(draw_mode, DRAW_MODE_SOFTWARE);
+ pool_resource = pool_->AcquireResource(internal_content_bounds_,
+ viz::RGBA_8888, gfx::ColorSpace());
+
if (!pool_resource.software_backing()) {
auto backing = std::make_unique<HudSoftwareBacking>();
backing->layer_tree_frame_sink = layer_tree_frame_sink;
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index f8f478a6486..c5fb253d85e 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -65,7 +65,6 @@ Layer::Inputs::Inputs(int layer_id)
has_will_change_transform_hint(false),
trilinear_filtering(false),
hide_layer_and_subtree(false),
- client_rawptr(nullptr),
overscroll_behavior(OverscrollBehavior::kOverscrollBehaviorTypeAuto) {}
Layer::Inputs::~Inputs() = default;
@@ -887,12 +886,15 @@ void Layer::AddMainThreadScrollingReasons(
uint32_t main_thread_scrolling_reasons) {
DCHECK(IsPropertyChangeAllowed());
DCHECK(main_thread_scrolling_reasons);
+ // Layer should only see non-transient scrolling reasons. Transient scrolling
+ // reasons are computed per hit test.
+ DCHECK(MainThreadScrollingReason::MainThreadCanSetScrollReasons(
+ main_thread_scrolling_reasons));
uint32_t new_reasons =
inputs_.main_thread_scrolling_reasons | main_thread_scrolling_reasons;
if (inputs_.main_thread_scrolling_reasons == new_reasons)
return;
inputs_.main_thread_scrolling_reasons = new_reasons;
- didUpdateMainThreadScrollingReasons();
SetPropertyTreesNeedRebuild();
SetNeedsCommit();
}
@@ -906,7 +908,6 @@ void Layer::ClearMainThreadScrollingReasons(
if (new_reasons == inputs_.main_thread_scrolling_reasons)
return;
inputs_.main_thread_scrolling_reasons = new_reasons;
- didUpdateMainThreadScrollingReasons();
SetPropertyTreesNeedRebuild();
SetNeedsCommit();
}
@@ -1164,9 +1165,7 @@ void Layer::SetStickyPositionConstraint(
void Layer::SetLayerClient(base::WeakPtr<LayerClient> client) {
inputs_.client = std::move(client);
- // Both binds the weak_ptr to the main thread and stores a rawptr for access
- // during commit.
- inputs_.client_rawptr = client.get();
+ inputs_.debug_info = nullptr;
}
bool Layer::IsSnapped() {
@@ -1185,14 +1184,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->SetBackgroundColor(inputs_.background_color);
layer->SetSafeOpaqueBackgroundColor(safe_opaque_background_color_);
layer->SetBounds(inputs_.bounds);
-
-#if defined(NDEBUG)
- if (frame_viewer_instrumentation::IsTracingLayerTreeSnapshots())
- layer->SetDebugInfo(TakeDebugInfo());
-#else
- layer->SetDebugInfo(TakeDebugInfo());
-#endif
-
+ layer->SetDebugInfo(std::move(inputs_.debug_info));
layer->SetTransformTreeIndex(transform_tree_index());
layer->SetEffectTreeIndex(effect_tree_index());
layer->SetClipTreeIndex(clip_tree_index());
@@ -1321,24 +1313,10 @@ bool Layer::HasNonAAPaint() const {
return false;
}
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-Layer::TakeDebugInfo() {
- // TakeDebugInfo is called from the compositor thread while the main thread is
- // blocked so we use the raw client pointer as we can't check whether the
- // reference is safe on the weak pointer.
- // TODO(flackr): Remove client_rawptr and figure out if we can take the debug
- // info from the main thread and store it on inputs before doing the commit or
- // make a WeakPtr which understands the commit and allows checked access from
- // the compositor thread. https://crbug.com/826455
- if (inputs_.client_rawptr)
- return inputs_.client_rawptr->TakeDebugInfo(this);
- else
- return nullptr;
-}
-
-void Layer::didUpdateMainThreadScrollingReasons() {
+void Layer::UpdateDebugInfo() {
+ DCHECK(frame_viewer_instrumentation::IsTracingLayerTreeSnapshots());
if (inputs_.client)
- inputs_.client->didUpdateMainThreadScrollingReasons();
+ inputs_.debug_info = inputs_.client->TakeDebugInfo(this);
}
void Layer::SetSubtreePropertyChanged() {
@@ -1357,7 +1335,7 @@ void Layer::SetMayContainVideo(bool yes) {
void Layer::SetScrollbarsHiddenFromImplSide(bool hidden) {
if (inputs_.client)
- inputs_.client->didChangeScrollbarsHiddenIfOverlay(hidden);
+ inputs_.client->DidChangeScrollbarsHiddenIfOverlay(hidden);
}
// On<Property>Animated is called due to an ongoing accelerated animation.
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index eca81a044cf..32f87b182cd 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -41,7 +41,7 @@
namespace base {
namespace trace_event {
-class ConvertableToTraceFormat;
+class TracedValue;
}
}
@@ -117,7 +117,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// A layer's bounds are in logical, non-page-scaled pixels (however, the
// root layer's bounds are in physical pixels).
void SetBounds(const gfx::Size& bounds);
- gfx::Size bounds() const { return inputs_.bounds; }
+ const gfx::Size& bounds() const { return inputs_.bounds; }
void SetOverscrollBehavior(const OverscrollBehavior& behavior);
OverscrollBehavior overscroll_behavior() const {
@@ -136,7 +136,13 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
Layer* mask_layer() { return inputs_.mask_layer.get(); }
const Layer* mask_layer() const { return inputs_.mask_layer.get(); }
+ // Marks the |dirty_rect| as being changed, which will cause a commit and
+ // the compositor to submit a new frame with a damage rect that includes the
+ // layer's dirty area.
virtual void SetNeedsDisplayRect(const gfx::Rect& dirty_rect);
+ // Marks the entire layer's bounds as being changed, which will cause a commit
+ // and the compositor to submit a new frame with a damage rect that includes
+ // the entire layer.
void SetNeedsDisplay() { SetNeedsDisplayRect(gfx::Rect(bounds())); }
virtual void SetOpacity(float opacity);
@@ -166,8 +172,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
const FilterOperations& filters() const { return inputs_.filters; }
// Background filters are filters applied to what is behind this layer, when
- // they are viewed through non-opaque regions in this layer. They are used
- // through the WebLayer interface, and are not exposed to HTML.
+ // they are viewed through non-opaque regions in this layer.
void SetBackgroundFilters(const FilterOperations& filters);
const FilterOperations& background_filters() const {
return inputs_.background_filters;
@@ -177,7 +182,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
bool contents_opaque() const { return inputs_.contents_opaque; }
void SetPosition(const gfx::PointF& position);
- gfx::PointF position() const { return inputs_.position; }
+ const gfx::PointF& position() const { return inputs_.position; }
// A layer that is a container for fixed position layers cannot be both
// scrollable and have a non-identity transform.
@@ -204,7 +209,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
const gfx::Transform& transform() const { return inputs_.transform; }
void SetTransformOrigin(const gfx::Point3F&);
- gfx::Point3F transform_origin() const { return inputs_.transform_origin; }
+ const gfx::Point3F& transform_origin() const {
+ return inputs_.transform_origin;
+ }
void SetScrollParent(Layer* parent);
@@ -230,14 +237,18 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
void SetScrollOffset(const gfx::ScrollOffset& scroll_offset);
- gfx::ScrollOffset scroll_offset() const { return inputs_.scroll_offset; }
+ const gfx::ScrollOffset& scroll_offset() const {
+ return inputs_.scroll_offset;
+ }
+ // Called internally during commit to update the layer with state from the
+ // compositor thread. Not to be called externally by users of this class.
void SetScrollOffsetFromImplSide(const gfx::ScrollOffset& scroll_offset);
// Marks this layer as being scrollable and needing an associated scroll node.
// The scroll node's bounds and container_bounds will be kept in sync
// with this layer. Once scrollable, a Layer cannot become un-scrollable.
void SetScrollable(const gfx::Size& scroll_container_bounds);
- gfx::Size scroll_container_bounds() const {
+ const gfx::Size& scroll_container_bounds() const {
return inputs_.scroll_container_bounds;
}
bool scrollable() const { return inputs_.scrollable; }
@@ -284,7 +295,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
return force_render_surface_for_testing_;
}
- gfx::ScrollOffset CurrentScrollOffset() const {
+ const gfx::ScrollOffset& CurrentScrollOffset() const {
return inputs_.scroll_offset;
}
@@ -310,6 +321,11 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
virtual void SetLayerTreeHost(LayerTreeHost* host);
+ // When true the layer may contribute to the compositor's output. When false,
+ // it does not. This property does not apply to children of the layer, they
+ // may contribute while this layer does not. The layer itself will determine
+ // if it has content to contribute, but when false, this prevents it from
+ // doing so.
void SetIsDrawable(bool is_drawable);
void SetHideLayerAndSubtree(bool hide);
@@ -320,6 +336,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
int NumDescendantsThatDrawContent() const;
+ // Is true if the layer will contribute content to the compositor's output.
+ // Will be false if SetIsDrawable(false) is called. But will also be false if
+ // the layer itself has no content to contribute, even though the layer was
+ // given SetIsDrawable(true).
// This is only virtual for tests.
// TODO(awoloszyn): Remove this once we no longer need it for tests
virtual bool DrawsContent() const;
@@ -331,11 +351,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
virtual bool HasSlowPaths() const;
virtual bool HasNonAAPaint() const;
- virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
- TakeDebugInfo();
- virtual void didUpdateMainThreadScrollingReasons();
+ void UpdateDebugInfo();
void SetLayerClient(base::WeakPtr<LayerClient> client);
+ LayerClient* GetLayerClientForTesting() const { return inputs_.client.get(); }
virtual bool IsSnapped();
@@ -628,9 +647,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// The following elements can not and are not serialized.
base::WeakPtr<LayerClient> client;
- // During commit, the main thread is blocked on the compositor thread, so
- // we use the raw pointer to the LayerClient.
- LayerClient* client_rawptr;
+ std::unique_ptr<base::trace_event::TracedValue> debug_info;
base::Callback<void(const gfx::ScrollOffset&, const ElementId&)>
did_scroll_callback;
diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h
index 10ded49b5a5..c7bb4862c2f 100644
--- a/chromium/cc/layers/layer_client.h
+++ b/chromium/cc/layers/layer_client.h
@@ -11,7 +11,7 @@
namespace base {
namespace trace_event {
-class ConvertableToTraceFormat;
+class TracedValue;
}
}
@@ -28,10 +28,10 @@ class CC_EXPORT LayerClient {
//
// A pointer to the layer is provided for the convenience of layer clients
// which service multiple layers.
- virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
- TakeDebugInfo(Layer* layer) = 0;
- virtual void didUpdateMainThreadScrollingReasons() = 0;
- virtual void didChangeScrollbarsHiddenIfOverlay(bool) = 0;
+ virtual std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
+ Layer* layer) = 0;
+
+ virtual void DidChangeScrollbarsHiddenIfOverlay(bool) = 0;
protected:
virtual ~LayerClient() {}
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 89b4bdf6a80..2eee6d48f5a 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -114,7 +114,7 @@ ElementListType LayerImpl::GetElementTypeForAnimation() const {
}
void LayerImpl::SetDebugInfo(
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> debug_info) {
+ std::unique_ptr<base::trace_event::TracedValue> debug_info) {
owned_debug_info_ = std::move(debug_info);
debug_info_ = owned_debug_info_.get();
SetNeedsPushProperties();
@@ -408,6 +408,9 @@ std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() {
result->SetBoolean("Is3dSorted", Is3dSorted());
result->SetDouble("OPACITY", Opacity());
result->SetBoolean("ContentsOpaque", contents_opaque_);
+ result->SetString(
+ "mainThreadScrollingReasons",
+ MainThreadScrollingReason::AsText(main_thread_scrolling_reasons_));
if (scrollable())
result->SetBoolean("Scrollable", true);
@@ -764,25 +767,11 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetBoolean("trilinear_filtering", trilinear_filtering());
- if (debug_info_) {
- std::string str;
- debug_info_->AppendAsTraceFormat(&str);
- base::JSONReader json_reader;
- std::unique_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str));
-
- if (debug_info_value->is_dict()) {
- base::DictionaryValue* dictionary_value = nullptr;
- bool converted_to_dictionary =
- debug_info_value->GetAsDictionary(&dictionary_value);
- DCHECK(converted_to_dictionary);
- for (base::DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd();
- it.Advance()) {
- state->SetValue(it.key().data(), it.value().CreateDeepCopy());
- }
- } else {
- NOTREACHED();
- }
- }
+ MainThreadScrollingReason::AddToTracedValue(main_thread_scrolling_reasons_,
+ *state);
+
+ if (debug_info_)
+ state->SetValue("debug_info", *debug_info_);
}
size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h
index 6eb7daabac1..d130a695d45 100644
--- a/chromium/cc/layers/layer_impl.h
+++ b/chromium/cc/layers/layer_impl.h
@@ -45,7 +45,6 @@
namespace base {
namespace trace_event {
-class ConvertableToTraceFormat;
class TracedValue;
}
class DictionaryValue;
@@ -388,8 +387,7 @@ class CC_EXPORT LayerImpl {
virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark);
- void SetDebugInfo(
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> debug_info);
+ void SetDebugInfo(std::unique_ptr<base::trace_event::TracedValue> debug_info);
void set_contributes_to_drawn_render_surface(bool is_member) {
contributes_to_drawn_render_surface_ = is_member;
@@ -564,9 +562,8 @@ class CC_EXPORT LayerImpl {
DrawProperties draw_properties_;
PerformanceProperties<LayerImpl> performance_properties_;
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
- owned_debug_info_;
- base::trace_event::ConvertableToTraceFormat* debug_info_;
+ std::unique_ptr<base::trace_event::TracedValue> owned_debug_info_;
+ base::trace_event::TracedValue* debug_info_;
bool has_will_change_transform_hint_ : 1;
bool trilinear_filtering_ : 1;
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index 3c898c8c12d..594552cc344 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -65,6 +65,20 @@ using ::testing::_;
grand_child->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
grand_child.get()));
+#define EXECUTE_AND_VERIFY_SUBTREE_NOT_CHANGED(code_to_test) \
+ code_to_test; \
+ root->layer_tree_host()->BuildPropertyTreesForTesting(); \
+ EXPECT_FALSE(root->subtree_property_changed()); \
+ EXPECT_FALSE(root->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
+ root.get())); \
+ EXPECT_FALSE(child->subtree_property_changed()); \
+ EXPECT_FALSE(child->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
+ child.get())); \
+ EXPECT_FALSE(grand_child->subtree_property_changed()); \
+ EXPECT_FALSE( \
+ grand_child->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
+ grand_child.get()));
+
#define EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(code_to_test) \
code_to_test; \
EXPECT_FALSE(root->subtree_property_changed()); \
@@ -848,23 +862,24 @@ TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
EXPECT_FALSE(test_layer->NeedsDisplayForTesting());
uint32_t reasons = 0, reasons_to_clear = 0, reasons_after_clearing = 0;
- reasons |= MainThreadScrollingReason::kNonFastScrollableRegion;
- reasons |= MainThreadScrollingReason::kContinuingMainThreadScroll;
+ reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
+ reasons |= MainThreadScrollingReason::kHandlingScrollFromMainThread;
reasons |= MainThreadScrollingReason::kScrollbarScrolling;
- reasons_to_clear |= MainThreadScrollingReason::kContinuingMainThreadScroll;
- reasons_to_clear |= MainThreadScrollingReason::kThreadedScrollingDisabled;
+ reasons_to_clear |= MainThreadScrollingReason::kHandlingScrollFromMainThread;
+ reasons_to_clear |= MainThreadScrollingReason::kCustomScrollbarScrolling;
- reasons_after_clearing |= MainThreadScrollingReason::kNonFastScrollableRegion;
+ reasons_after_clearing |=
+ MainThreadScrollingReason::kThreadedScrollingDisabled;
reasons_after_clearing |= MainThreadScrollingReason::kScrollbarScrolling;
// Check that the reasons are added correctly.
EXPECT_SET_NEEDS_COMMIT(
1, test_layer->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kNonFastScrollableRegion));
+ MainThreadScrollingReason::kThreadedScrollingDisabled));
EXPECT_SET_NEEDS_COMMIT(
1, test_layer->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kContinuingMainThreadScroll));
+ MainThreadScrollingReason::kHandlingScrollFromMainThread));
EXPECT_SET_NEEDS_COMMIT(1,
test_layer->AddMainThreadScrollingReasons(
MainThreadScrollingReason::kScrollbarScrolling));
@@ -878,8 +893,8 @@ TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
// Check that clearing non-set reasons doesn't set needs commit.
reasons_to_clear = 0;
- reasons_to_clear |= MainThreadScrollingReason::kThreadedScrollingDisabled;
- reasons_to_clear |= MainThreadScrollingReason::kNoScrollingLayer;
+ reasons_to_clear |= MainThreadScrollingReason::kCustomScrollbarScrolling;
+ reasons_to_clear |= MainThreadScrollingReason::kPageOverlay;
EXPECT_SET_NEEDS_COMMIT(
0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
EXPECT_EQ(reasons_after_clearing,
@@ -888,7 +903,7 @@ TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
// Check that adding an existing condition doesn't set needs commit.
EXPECT_SET_NEEDS_COMMIT(
0, test_layer->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kNonFastScrollableRegion));
+ MainThreadScrollingReason::kThreadedScrollingDisabled));
}
TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
@@ -921,7 +936,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
gfx::ScrollOffset(10, 10)));
EXPECT_SET_NEEDS_COMMIT(
1, test_layer->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kNonFastScrollableRegion));
+ MainThreadScrollingReason::kThreadedScrollingDisabled));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion(
Region(gfx::Rect(1, 1, 2, 2))));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(
diff --git a/chromium/cc/layers/nine_patch_layer_impl.h b/chromium/cc/layers/nine_patch_layer_impl.h
index 9e5c9d65580..4841059fcaf 100644
--- a/chromium/cc/layers/nine_patch_layer_impl.h
+++ b/chromium/cc/layers/nine_patch_layer_impl.h
@@ -13,7 +13,6 @@
#include "cc/layers/layer_impl.h"
#include "cc/layers/nine_patch_generator.h"
#include "cc/layers/ui_resource_layer_impl.h"
-#include "cc/resources/resource_provider.h"
#include "cc/resources/ui_resource_client.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
diff --git a/chromium/cc/layers/nine_patch_layer_unittest.cc b/chromium/cc/layers/nine_patch_layer_unittest.cc
index db3dc399a33..969de99e8cf 100644
--- a/chromium/cc/layers/nine_patch_layer_unittest.cc
+++ b/chromium/cc/layers/nine_patch_layer_unittest.cc
@@ -5,7 +5,6 @@
#include "cc/layers/nine_patch_layer.h"
#include "cc/animation/animation_host.h"
-#include "cc/resources/resource_provider.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index e52dfccf2c4..4dc5f16985f 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -771,6 +771,10 @@ void PictureLayerImpl::UpdateRasterSource(
// We could do this after doing UpdateTiles, which would avoid doing this for
// tilings that are going to disappear on the pending tree (if scale changed).
// But that would also be more complicated, so we just do it here for now.
+ //
+ // TODO(crbug.com/843787): If the LayerTreeFrameSink is lost, and we activate,
+ // this ends up running with the old LayerTreeFrameSink, or possibly with a
+ // null LayerTreeFrameSink, which can give incorrect results or maybe crash.
if (pending_set) {
tilings_->UpdateTilingsToCurrentRasterSourceForActivation(
raster_source_, pending_set, invalidation_, MinimumContentsScale(),
@@ -932,8 +936,7 @@ bool PictureLayerImpl::ShouldAnimate(PaintImage::Id paint_image_id) const {
gfx::Size PictureLayerImpl::CalculateTileSize(
const gfx::Size& content_bounds) const {
- int max_texture_size =
- layer_tree_impl()->resource_provider()->max_texture_size();
+ int max_texture_size = layer_tree_impl()->max_texture_size();
if (mask_type_ == Layer::LayerMaskType::SINGLE_TEXTURE_MASK) {
// Masks are not tiled, so if we can't cover the whole mask with one tile,
@@ -1452,10 +1455,10 @@ float PictureLayerImpl::MaximumContentsScale() const {
// have tilings that would become larger than the max_texture_size since they
// use a single tile for the entire tiling. Other layers can have tilings such
// that dimension * scale does not overflow.
- float max_dimension = static_cast<float>(
- mask_type_ == Layer::LayerMaskType::SINGLE_TEXTURE_MASK
- ? layer_tree_impl()->resource_provider()->max_texture_size()
- : std::numeric_limits<int>::max());
+ float max_dimension =
+ static_cast<float>(mask_type_ == Layer::LayerMaskType::SINGLE_TEXTURE_MASK
+ ? layer_tree_impl()->max_texture_size()
+ : std::numeric_limits<int>::max());
float max_scale_width = max_dimension / bounds().width();
float max_scale_height = max_dimension / bounds().height();
float max_scale = std::min(max_scale_width, max_scale_height);
diff --git a/chromium/cc/layers/picture_layer_impl.h b/chromium/cc/layers/picture_layer_impl.h
index d0348102464..6f850859e72 100644
--- a/chromium/cc/layers/picture_layer_impl.h
+++ b/chromium/cc/layers/picture_layer_impl.h
@@ -163,11 +163,20 @@ class CC_EXPORT PictureLayerImpl
scoped_refptr<RasterSource> raster_source_;
Region invalidation_;
+ // Ideal scales are calcuated from the transforms applied to the layer. They
+ // represent the best known scale from the layer to the final output.
+ // Page scale is from user pinch/zoom.
float ideal_page_scale_;
+ // Device scale is from screen dpi, and it comes from device scale facter.
float ideal_device_scale_;
+ // Source scale comes from javascript css scale.
float ideal_source_scale_;
+ // Contents scale = device scale * page scale * source scale.
float ideal_contents_scale_;
+ // Raster scales are set from ideal scales. They are scales we choose to
+ // raster at. They may not match the ideal scales at times to avoid raster for
+ // performance reasons.
float raster_page_scale_;
float raster_device_scale_;
float raster_source_scale_;
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index 38e0a3ac30a..90f76f90953 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -1258,7 +1258,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
// Resize larger than the max texture size.
- int max_texture_size = host_impl()->resource_provider()->max_texture_size();
+ int max_texture_size = host_impl()->max_texture_size();
gfx::Size huge_bounds(max_texture_size + 1, 10);
scoped_refptr<FakeRasterSource> huge_raster_source =
FakeRasterSource::CreateFilled(huge_bounds);
@@ -1451,10 +1451,10 @@ TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) {
ResetTilingsAndRasterScales();
// Change the max texture size on the output surface context.
- std::unique_ptr<viz::TestWebGraphicsContext3D> context =
- viz::TestWebGraphicsContext3D::Create();
- context->set_max_texture_size(140);
- ResetLayerTreeFrameSink(FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_max_texture_size(140);
+ ResetLayerTreeFrameSink(
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
false);
@@ -1486,10 +1486,10 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
ResetTilingsAndRasterScales();
// Change the max texture size on the output surface context.
- std::unique_ptr<viz::TestWebGraphicsContext3D> context =
- viz::TestWebGraphicsContext3D::Create();
- context->set_max_texture_size(140);
- ResetLayerTreeFrameSink(FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_max_texture_size(140);
+ ResetLayerTreeFrameSink(
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
false);
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index c0614fcfbf2..02caf7cb7e7 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -26,6 +26,7 @@
#include "components/viz/common/quads/render_pass_draw_quad.h"
#include "components/viz/common/quads/shared_quad_state.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
+#include "components/viz/common/quads/tile_draw_quad.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/transform.h"
@@ -267,8 +268,8 @@ void RenderSurfaceImpl::CalculateContentRectFromAccumulatedContentRect(
// use accumulated content rect, and then try to clip it.
gfx::Rect surface_content_rect = CalculateClippedAccumulatedContentRect();
- // The RenderSurfaceImpl backing texture cannot exceed the maximum
- // supported texture size.
+ // The RenderSurfaceImpl backing texture cannot exceed the maximum supported
+ // texture size.
surface_content_rect.set_width(
std::min(surface_content_rect.width(), max_texture_size));
surface_content_rect.set_height(
@@ -384,9 +385,9 @@ std::unique_ptr<viz::RenderPass> RenderSurfaceImpl::CreateRenderPass() {
void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) {
- gfx::Rect visible_layer_rect =
+ gfx::Rect unoccluded_content_rect =
occlusion_in_content_space().GetUnoccludedContentRect(content_rect());
- if (visible_layer_rect.IsEmpty())
+ if (unoccluded_content_rect.IsEmpty())
return;
const PropertyTrees* property_trees = layer_tree_impl_->property_trees();
@@ -406,7 +407,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
auto* debug_border_quad =
render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
debug_border_quad->SetNew(shared_quad_state, content_rect(),
- visible_layer_rect, GetDebugBorderColor(),
+ unoccluded_content_rect, GetDebugBorderColor(),
GetDebugBorderWidth());
}
@@ -429,7 +430,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
"mask_layer_gpu_memory_usage",
mask_layer->GPUMemoryUsageInBytes());
if (mask_layer->mask_type() == Layer::LayerMaskType::MULTI_TEXTURE_MASK) {
- TileMaskLayer(render_pass, shared_quad_state, visible_layer_rect);
+ TileMaskLayer(render_pass, shared_quad_state, unoccluded_content_rect);
return;
}
gfx::SizeF mask_uv_size;
@@ -448,21 +449,25 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
gfx::RectF tex_coord_rect(gfx::Rect(content_rect().size()));
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- quad->SetNew(shared_quad_state, content_rect(), visible_layer_rect, id(),
+ quad->SetNew(shared_quad_state, content_rect(), unoccluded_content_rect, id(),
mask_resource_id, mask_uv_rect, mask_texture_size,
surface_contents_scale, FiltersOrigin(), tex_coord_rect,
!layer_tree_impl_->settings().enable_edge_anti_aliasing);
}
-void RenderSurfaceImpl::TileMaskLayer(viz::RenderPass* render_pass,
- viz::SharedQuadState* shared_quad_state,
- const gfx::Rect& visible_layer_rect) {
+void RenderSurfaceImpl::TileMaskLayer(
+ viz::RenderPass* render_pass,
+ viz::SharedQuadState* shared_quad_state,
+ const gfx::Rect& unoccluded_content_rect) {
DCHECK(MaskLayer());
DCHECK(Filters().IsEmpty());
LayerImpl* mask_layer = MaskLayer();
gfx::Vector2dF owning_layer_to_surface_contents_scale =
OwningEffectNode()->surface_contents_scale;
+
+ // Use the picture layer's AppendQuads logic to generate TileDrawQuads. These
+ // DrawQuads are used to generate tiled RenderPassDrawQuad for the mask.
std::unique_ptr<viz::RenderPass> temp_render_pass = viz::RenderPass::Create();
AppendQuadsData temp_append_quads_data;
mask_layer->AppendQuads(temp_render_pass.get(), &temp_append_quads_data);
@@ -470,92 +475,158 @@ void RenderSurfaceImpl::TileMaskLayer(viz::RenderPass* render_pass,
auto* temp_quad = temp_render_pass->quad_list.front();
if (!temp_quad)
return;
- gfx::Transform mask_quad_to_surface_contents =
+
+ // There are two spaces we are dealing with here:
+ // 1. quad space: This is the space where the draw quads generated by the
+ // PictureLayerImpl's logic are in. In other words, this is the space where
+ // the |temp_quad|'s rect is in.
+ // 2. surface space: This is the contents space of |this| render surface.
+ // Since |mask_layer|'s target is the render surface it's masking, the surface
+ // space is also the target space for the quads generated by
+ // PictureLayerImpl's logic.
+
+ gfx::Transform quad_space_to_surface_space_transform =
temp_quad->shared_quad_state->quad_to_target_transform;
- // Draw transform of a mask layer should be a 2d scale.
- DCHECK(mask_quad_to_surface_contents.IsScale2d());
- gfx::Vector2dF mask_quad_to_surface_contents_scale =
- mask_quad_to_surface_contents.Scale2d();
- shared_quad_state->quad_to_target_transform.matrix().preScale(
- mask_quad_to_surface_contents_scale.x(),
- mask_quad_to_surface_contents_scale.y(), 1.f);
- shared_quad_state->quad_layer_rect =
- gfx::ScaleToEnclosingRect(shared_quad_state->quad_layer_rect,
- 1.f / mask_quad_to_surface_contents_scale.x(),
- 1.f / mask_quad_to_surface_contents_scale.y());
+ // This transform should be a 2d scale + offset, so would be invertible.
+ gfx::Transform surface_space_to_quad_space_transform;
+ bool invertible = quad_space_to_surface_space_transform.GetInverse(
+ &surface_space_to_quad_space_transform);
+ DCHECK(invertible) << "RenderSurfaceImpl::TileMaskLayer created quads with "
+ "non-invertible transform.";
+
+ // While converting from the TileDrawQuads to RenderPassDrawQuads, we keep the
+ // quad rects in the same space, and modify every other rect that is not in
+ // quad space accordingly.
+
+ // The |shared_quad_state| being passed in is generated with |this| render
+ // surface's draw properties. It holds a transform from the surface contents
+ // space to the surface target space. We want to change the origin space to
+ // match the |mask_layer|'s quad space, so we must include the transform from
+ // the quad space to the surface contents space. Then the transform is from
+ // the |mask_layer|'s quad space to our target space.
+ shared_quad_state->quad_to_target_transform.PreconcatTransform(
+ quad_space_to_surface_space_transform);
+
+ // Next, we need to modify the rects on |shared_quad_state| that are in
+ // surface's "quad space" (surface space) to quad space.
+ shared_quad_state->quad_layer_rect = MathUtil::ProjectEnclosingClippedRect(
+ surface_space_to_quad_space_transform,
+ shared_quad_state->quad_layer_rect);
shared_quad_state->visible_quad_layer_rect =
- gfx::ScaleToEnclosingRect(shared_quad_state->visible_quad_layer_rect,
- 1.f / mask_quad_to_surface_contents_scale.x(),
- 1.f / mask_quad_to_surface_contents_scale.y());
- gfx::Rect content_rect_in_coverage_space = gfx::ScaleToEnclosingRect(
- content_rect(), 1.f / mask_quad_to_surface_contents_scale.x(),
- 1.f / mask_quad_to_surface_contents_scale.y());
- gfx::Rect visible_layer_rect_in_coverage_space = gfx::ScaleToEnclosingRect(
- visible_layer_rect, 1.f / mask_quad_to_surface_contents_scale.x(),
- 1.f / mask_quad_to_surface_contents_scale.y());
-
+ MathUtil::ProjectEnclosingClippedRect(
+ surface_space_to_quad_space_transform,
+ shared_quad_state->visible_quad_layer_rect);
+
+ // The |shared_quad_state|'s |quad_layer_rect| and |visible_quad_layer_rect|
+ // is set from content_rect(). content_rect() defines the size of the source
+ // texture to be masked. PictureLayerImpl's generated |quad_layer_rect| and
+ // |visible_quad_layer_rect| is from the mask layer's |bounds| and
+ // |visible_layer_rect|. These rect defines the size of the mask texture. The
+ // intersection of the two rects is the rect we can draw.
+ shared_quad_state->quad_layer_rect.Intersect(
+ temp_quad->shared_quad_state->quad_layer_rect);
+ shared_quad_state->visible_quad_layer_rect.Intersect(
+ temp_quad->shared_quad_state->visible_quad_layer_rect);
+
+ // Cache content_rect() and |unoccluded_content_rect| in quad space.
+ gfx::Rect content_rect_in_quad_space = MathUtil::MapEnclosingClippedRect(
+ surface_space_to_quad_space_transform, content_rect());
+ gfx::Rect unoccluded_content_rect_in_quad_space =
+ MathUtil::MapEnclosingClippedRect(surface_space_to_quad_space_transform,
+ unoccluded_content_rect);
+
+ // Generate RenderPassDrawQuads based on the temporary quads created by
+ // |mask_layer|.
for (auto* temp_quad : temp_render_pass->quad_list) {
- gfx::Rect quad_rect = temp_quad->rect;
- if (!quad_rect.Intersects(content_rect_in_coverage_space))
+ gfx::Rect temp_quad_rect = temp_quad->rect;
+ // If the |temp_quad_rect| is entirely outside render surface's
+ // content_rect(), ignore the quad.
+ if (!temp_quad_rect.Intersects(content_rect_in_quad_space))
continue;
- gfx::Rect render_quad_rect =
- gfx::IntersectRects(quad_rect, content_rect_in_coverage_space);
- gfx::Rect quad_visible_rect_in_coverage_space = gfx::IntersectRects(
- render_quad_rect, visible_layer_rect_in_coverage_space);
- if (quad_visible_rect_in_coverage_space.IsEmpty())
+ // We only care about the quads that are inside the content_rect().
+ gfx::Rect quad_rect =
+ gfx::IntersectRects(temp_quad_rect, content_rect_in_quad_space);
+
+ gfx::Rect visible_quad_rect =
+ gfx::IntersectRects(quad_rect, unoccluded_content_rect_in_quad_space);
+ if (visible_quad_rect.IsEmpty())
continue;
- gfx::RectF quad_rect_in_surface_contents_space = gfx::ScaleRect(
- gfx::RectF(render_quad_rect), mask_quad_to_surface_contents_scale.x(),
- mask_quad_to_surface_contents_scale.y());
- gfx::RectF quad_rect_in_non_normalized_texture_space =
- quad_rect_in_surface_contents_space;
- quad_rect_in_non_normalized_texture_space.Offset(
- -content_rect().OffsetFromOrigin());
+ // |tex_coord_rect| is non-normalized sub-rect of the render surface's
+ // texture that is being masked. Its origin is (0,0) and it is in surface
+ // space. For example the |tex_coord_rect| for the entire texture would be
+ // (0,0 content_rect.width X content_rect.height).
+
+ // In order to calculate the |tex_coord_rect|, we calculate what quad's rect
+ // would be masking in the surface contents space, then remove the offset.
+ gfx::RectF tex_coord_rect = MathUtil::MapClippedRect(
+ quad_space_to_surface_space_transform, gfx::RectF(quad_rect));
+ tex_coord_rect.Offset(-content_rect().OffsetFromOrigin());
switch (temp_quad->material) {
case viz::DrawQuad::TILED_CONTENT: {
DCHECK_EQ(1U, temp_quad->resources.count);
- gfx::Size mask_texture_size =
- static_cast<viz::ContentDrawQuadBase*>(temp_quad)->texture_size;
+ // When the |temp_quad| is actually a texture, we need to calculate
+ // |mask_uv_rect|. The |mask_uv_rect| is the normalized sub-rect for
+ // applying the mask's texture. To get |mask_uv_rect|, we need the newly
+ // calculated |quad_rect| in the texture's space, then normalized by the
+ // texture's size.
+
+ // We are applying the |temp_quad|'s texture as a mask, so we start with
+ // the |tex_coord_rect| of the |temp_quad|.
gfx::RectF temp_tex_coord_rect =
- static_cast<viz::ContentDrawQuadBase*>(temp_quad)->tex_coord_rect;
- gfx::Transform coverage_to_non_normalized_mask =
- gfx::Transform(SkMatrix44(SkMatrix::MakeRectToRect(
- RectToSkRect(quad_rect), RectFToSkRect(temp_tex_coord_rect),
- SkMatrix::kFill_ScaleToFit)));
- gfx::Transform coverage_to_normalized_mask =
- coverage_to_non_normalized_mask;
- coverage_to_normalized_mask.matrix().postScale(
- 1.f / mask_texture_size.width(), 1.f / mask_texture_size.height(),
- 1.f);
- gfx::RectF mask_uv_rect = gfx::RectF(render_quad_rect);
- coverage_to_normalized_mask.TransformRect(&mask_uv_rect);
+ viz::TileDrawQuad::MaterialCast(temp_quad)->tex_coord_rect;
+
+ // The |quad_rect| is in the same space as |temp_quad_rect|. Calculate
+ // the scale transform between the texture space and the quad space.
+ float scale_x = temp_tex_coord_rect.width() / temp_quad_rect.width();
+ float scale_y = temp_tex_coord_rect.height() / temp_quad_rect.height();
+ // Start by setting up the correct size of mask_uv_rect in texture
+ // space.
+ gfx::RectF mask_uv_rect(quad_rect.width() * scale_x,
+ quad_rect.height() * scale_y);
+
+ // Now figure out what is the correct offset. Start with the original
+ // temp_tex_coord_rect's offset.
+ mask_uv_rect.Offset(temp_tex_coord_rect.OffsetFromOrigin());
+ // Next figure out what offset to apply by checking the difference in
+ // offset between |temp_quad_rect| and |quad_rect| which is
+ // intersected by the content_rect().
+ gfx::Vector2dF offset(quad_rect.OffsetFromOrigin());
+ offset -= temp_quad_rect.OffsetFromOrigin();
+ // Convert the difference in offset into texture space.
+ offset.Scale(scale_x, scale_y);
+ mask_uv_rect.Offset(offset);
+
+ // |mask_uv_rect| is normalized to [0..1] by the |mask_texture_size|.
+ gfx::Size mask_texture_size =
+ viz::TileDrawQuad::MaterialCast(temp_quad)->texture_size;
+ mask_uv_rect.Scale(1.f / mask_texture_size.width(),
+ 1.f / mask_texture_size.height());
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- quad->SetNew(shared_quad_state, render_quad_rect,
- quad_visible_rect_in_coverage_space, id(),
+ quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, id(),
temp_quad->resources.ids[0], mask_uv_rect,
mask_texture_size, owning_layer_to_surface_contents_scale,
- FiltersOrigin(), quad_rect_in_non_normalized_texture_space,
+ FiltersOrigin(), tex_coord_rect,
!layer_tree_impl_->settings().enable_edge_anti_aliasing);
} break;
case viz::DrawQuad::SOLID_COLOR: {
- if (!static_cast<viz::SolidColorDrawQuad*>(temp_quad)->color)
+ SkColor temp_color =
+ viz::SolidColorDrawQuad::MaterialCast(temp_quad)->color;
+ if (!temp_color)
continue;
SkAlpha solid = SK_AlphaOPAQUE;
- DCHECK_EQ(SkColorGetA(
- static_cast<viz::SolidColorDrawQuad*>(temp_quad)->color),
- solid);
+ DCHECK_EQ(SkColorGetA(temp_color), solid);
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- quad->SetNew(shared_quad_state, render_quad_rect,
- quad_visible_rect_in_coverage_space, id(), 0, gfx::RectF(),
- gfx::Size(), owning_layer_to_surface_contents_scale,
- FiltersOrigin(), quad_rect_in_non_normalized_texture_space,
+ quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, id(), 0,
+ gfx::RectF(), gfx::Size(),
+ owning_layer_to_surface_contents_scale, FiltersOrigin(),
+ tex_coord_rect,
!layer_tree_impl_->settings().enable_edge_anti_aliasing);
} break;
case viz::DrawQuad::DEBUG_BORDER:
diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h
index 00b05df4860..8e7c143087f 100644
--- a/chromium/cc/layers/render_surface_impl.h
+++ b/chromium/cc/layers/render_surface_impl.h
@@ -189,7 +189,7 @@ class CC_EXPORT RenderSurfaceImpl {
const gfx::Transform& target_to_surface);
void TileMaskLayer(viz::RenderPass* render_pass,
viz::SharedQuadState* shared_quad_state,
- const gfx::Rect& visible_layer_rect);
+ const gfx::Rect& unoccluded_content_rect);
LayerTreeImpl* layer_tree_impl_;
uint64_t stable_id_;
diff --git a/chromium/cc/layers/render_surface_impl_unittest.cc b/chromium/cc/layers/render_surface_impl_unittest.cc
index 0690231faea..8fb231d5a30 100644
--- a/chromium/cc/layers/render_surface_impl_unittest.cc
+++ b/chromium/cc/layers/render_surface_impl_unittest.cc
@@ -153,8 +153,11 @@ TEST(RenderSurfaceLayerImplTest,
viz::RenderPassDrawQuad::MaterialCast(render_pass->quad_list.front());
EXPECT_EQ(gfx::Transform(),
quad->shared_quad_state->quad_to_target_transform);
+ // With tiled mask layer, we only generate mask quads for visible rect. In
+ // this case |quad_layer_rect| is not fully covered, but
+ // |visible_quad_layer_rect| is fully covered.
LayerTestCommon::VerifyQuadsExactlyCoverRect(
- render_pass->quad_list, quad->shared_quad_state->quad_layer_rect);
+ render_pass->quad_list, quad->shared_quad_state->visible_quad_layer_rect);
}
} // namespace
diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc
index 714ddd49916..14f74ecc27e 100644
--- a/chromium/cc/layers/render_surface_unittest.cc
+++ b/chromium/cc/layers/render_surface_unittest.cc
@@ -245,6 +245,8 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceDropsOccludedRenderPassDrawQuads) {
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink =
FakeLayerTreeFrameSink::Create3d();
FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner);
+ // Set a big enough viewport to show the entire render pass.
+ host_impl.SetViewportSize(gfx::Size(1000, 1000));
std::unique_ptr<LayerImpl> root_layer =
LayerImpl::Create(host_impl.active_tree(), 1);
@@ -312,6 +314,8 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceIgnoreMaskLayerOcclusion) {
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink =
FakeLayerTreeFrameSink::Create3d();
FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner);
+ // Set a big enough viewport to show the entire render pass.
+ host_impl.SetViewportSize(gfx::Size(1000, 1000));
std::unique_ptr<LayerImpl> root_layer =
LayerImpl::Create(host_impl.active_tree(), 1);
diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc
index 94935c08f07..131182ac2d0 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -1351,7 +1351,7 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest {
layer_tree_host_->SetViewportSizeAndScale(
layer_tree_host_->device_viewport_size(), test_scale,
- layer_tree_host_->local_surface_id());
+ layer_tree_host_->local_surface_id_from_parent());
scrollbar_layer->Update();
@@ -1417,7 +1417,7 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest {
layer_tree_host_->SetViewportSizeAndScale(
layer_tree_host_->device_viewport_size(), test_scale,
- layer_tree_host_->local_surface_id());
+ layer_tree_host_->local_surface_id_from_parent());
scrollbar_layer->Update();
diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
index 395533bae64..5f0a8e8a419 100644
--- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc
+++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
@@ -188,7 +188,7 @@ TEST(SolidColorLayerImplTest, VerifyNeedsBlending) {
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
EXPECT_FALSE(layer->contents_opaque());
- layer->SetBackgroundColor(SkColorSetARGBInline(255, 10, 20, 30));
+ layer->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30));
EXPECT_TRUE(layer->contents_opaque());
{
DebugScopedSetImplThread scoped_impl_thread(host->GetTaskRunnerProvider());
@@ -215,7 +215,7 @@ TEST(SolidColorLayerImplTest, VerifyNeedsBlending) {
}
EXPECT_TRUE(layer->contents_opaque());
- layer->SetBackgroundColor(SkColorSetARGBInline(254, 10, 20, 30));
+ layer->SetBackgroundColor(SkColorSetARGB(254, 10, 20, 30));
EXPECT_FALSE(layer->contents_opaque());
{
DebugScopedSetImplThread scoped_impl_thread(host->GetTaskRunnerProvider());
diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc
index 8a123ca8587..6124fe42fbf 100644
--- a/chromium/cc/layers/surface_layer.cc
+++ b/chromium/cc/layers/surface_layer.cc
@@ -59,10 +59,10 @@ void SurfaceLayer::SetStretchContentToFillBounds(
SetNeedsPushProperties();
}
-void SurfaceLayer::SetHitTestable(bool hit_testable) {
- if (hit_testable_ == hit_testable)
+void SurfaceLayer::SetSurfaceHitTestable(bool surface_hit_testable) {
+ if (surface_hit_testable_ == surface_hit_testable)
return;
- hit_testable_ = hit_testable;
+ surface_hit_testable_ = surface_hit_testable;
SetNeedsPushProperties();
}
@@ -100,7 +100,7 @@ void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
deadline_in_frames_ = 0u;
layer_impl->SetFallbackSurfaceId(fallback_surface_id_);
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
- layer_impl->SetHitTestable(hit_testable_);
+ layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
}
} // namespace cc
diff --git a/chromium/cc/layers/surface_layer.h b/chromium/cc/layers/surface_layer.h
index 3ed0b9ad140..87c5a26dfe2 100644
--- a/chromium/cc/layers/surface_layer.h
+++ b/chromium/cc/layers/surface_layer.h
@@ -32,8 +32,8 @@ class CC_EXPORT SurfaceLayer : public Layer {
return stretch_content_to_fill_bounds_;
}
- void SetHitTestable(bool hit_testable);
- bool hit_testable() const { return hit_testable_; }
+ void SetSurfaceHitTestable(bool surface_hit_testable);
+ bool surface_hit_testable() const { return surface_hit_testable_; }
// Layer overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
@@ -64,7 +64,14 @@ class CC_EXPORT SurfaceLayer : public Layer {
base::Optional<uint32_t> deadline_in_frames_ = 0u;
bool stretch_content_to_fill_bounds_ = false;
- bool hit_testable_ = false;
+
+ // Whether or not the surface should submit hit test data when submitting
+ // compositor frame. The bit represents that the surface layer may be
+ // associated with an out-of-process iframe and viz hit testing needs to know
+ // the hit test information of that iframe. This bit is different from a layer
+ // being hit testable in the renderer, a hit testable surface layer may not
+ // be surface hit testable (e.g., a surface layer created by video).
+ bool surface_hit_testable_ = false;
DISALLOW_COPY_AND_ASSIGN(SurfaceLayer);
};
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index d90e233bfd3..def5281514d 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -54,11 +54,11 @@ void SurfaceLayerImpl::SetStretchContentToFillBounds(bool stretch_content) {
NoteLayerPropertyChanged();
}
-void SurfaceLayerImpl::SetHitTestable(bool hit_testable) {
- if (hit_testable_ == hit_testable)
+void SurfaceLayerImpl::SetSurfaceHitTestable(bool surface_hit_testable) {
+ if (surface_hit_testable_ == surface_hit_testable)
return;
- hit_testable_ = hit_testable;
+ surface_hit_testable_ = surface_hit_testable;
NoteLayerPropertyChanged();
}
@@ -71,7 +71,7 @@ void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
deadline_in_frames_ = 0u;
layer_impl->SetFallbackSurfaceId(fallback_surface_id_);
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
- layer_impl->SetHitTestable(hit_testable_);
+ layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
}
void SurfaceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
diff --git a/chromium/cc/layers/surface_layer_impl.h b/chromium/cc/layers/surface_layer_impl.h
index d51dd6ad9a6..ce243205514 100644
--- a/chromium/cc/layers/surface_layer_impl.h
+++ b/chromium/cc/layers/surface_layer_impl.h
@@ -50,8 +50,8 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
return stretch_content_to_fill_bounds_;
}
- void SetHitTestable(bool hit_testable);
- bool hit_testable() const { return hit_testable_; }
+ void SetSurfaceHitTestable(bool surface_hit_testable);
+ bool surface_hit_testable() const { return surface_hit_testable_; }
// LayerImpl overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
@@ -79,7 +79,7 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
base::Optional<uint32_t> deadline_in_frames_;
bool stretch_content_to_fill_bounds_ = false;
- bool hit_testable_ = false;
+ bool surface_hit_testable_ = false;
DISALLOW_COPY_AND_ASSIGN(SurfaceLayerImpl);
};
diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc
index 0e55c54f17f..359cbf8955d 100644
--- a/chromium/cc/layers/texture_layer.cc
+++ b/chromium/cc/layers/texture_layer.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
+#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/simple_enclosed_region.h"
@@ -273,20 +274,40 @@ TextureLayer::TransferableResourceHolder::MainThreadReference::
TextureLayer::TransferableResourceHolder::MainThreadReference::
~MainThreadReference() {
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock hold(holder_->posted_internal_derefs_lock_);
+ ++holder_->posted_internal_derefs_;
+ }
+#endif
holder_->InternalRelease();
}
TextureLayer::TransferableResourceHolder::TransferableResourceHolder(
const viz::TransferableResource& resource,
std::unique_ptr<viz::SingleReleaseCallback> release_callback)
- : internal_references_(0),
- resource_(resource),
+ : resource_(resource),
release_callback_(std::move(release_callback)),
- sync_token_(resource.mailbox_holder.sync_token),
- is_lost_(false) {}
+ sync_token_(resource.mailbox_holder.sync_token) {}
TextureLayer::TransferableResourceHolder::~TransferableResourceHolder() {
- DCHECK_EQ(0u, internal_references_);
+#if DCHECK_IS_ON()
+ {
+ // If the MessageLoop is destroyed while a posted deref is waiting to run,
+ // this object will be destroyed with an internal_references_ still present.
+ // So we must also include the outstanding posted derefences.
+ base::AutoLock hold(posted_internal_derefs_lock_);
+ DCHECK_EQ(internal_references_, posted_internal_derefs_);
+ }
+#endif
+ if (release_callback_) {
+ // We land here if the dereferences are posted but not run and the
+ // MessageLoop is destroyed, destroying those tasks and this object with it.
+ // We run the ReleaseCallback in that case assuming the MessageLoop is being
+ // destroyed on the main thread.
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ release_callback_->Run(sync_token_, is_lost_);
+ }
}
std::unique_ptr<TextureLayer::TransferableResourceHolder::MainThreadReference>
@@ -310,7 +331,7 @@ TextureLayer::TransferableResourceHolder::GetCallbackForImplThread(
scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner) {
// We can't call GetCallbackForImplThread if we released the main thread
// reference.
- DCHECK_GT(internal_references_, 0u);
+ DCHECK_GT(internal_references_, 0);
InternalAddRef();
return viz::SingleReleaseCallback::Create(
base::Bind(&TransferableResourceHolder::ReturnAndReleaseOnImplThread,
@@ -323,6 +344,12 @@ void TextureLayer::TransferableResourceHolder::InternalAddRef() {
void TextureLayer::TransferableResourceHolder::InternalRelease() {
DCHECK(main_thread_checker_.CalledOnValidThread());
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock hold(posted_internal_derefs_lock_);
+ --posted_internal_derefs_;
+ }
+#endif
if (!--internal_references_) {
release_callback_->Run(sync_token_, is_lost_);
resource_ = viz::TransferableResource();
@@ -335,6 +362,12 @@ void TextureLayer::TransferableResourceHolder::ReturnAndReleaseOnImplThread(
const gpu::SyncToken& sync_token,
bool is_lost) {
Return(sync_token, is_lost);
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock hold(posted_internal_derefs_lock_);
+ ++posted_internal_derefs_;
+ }
+#endif
main_thread_task_runner->PostTask(
FROM_HERE,
base::Bind(&TransferableResourceHolder::InternalRelease, this));
diff --git a/chromium/cc/layers/texture_layer.h b/chromium/cc/layers/texture_layer.h
index af32a87c81e..c8c77755b53 100644
--- a/chromium/cc/layers/texture_layer.h
+++ b/chromium/cc/layers/texture_layer.h
@@ -84,7 +84,13 @@ class CC_EXPORT TextureLayer : public Layer, SharedBitmapIdRegistrar {
// These members are only accessed on the main thread, or on the impl thread
// during commit where the main thread is blocked.
- unsigned internal_references_;
+ int internal_references_ = 0;
+#if DCHECK_IS_ON()
+ // The number of derefs posted from the impl thread, and a lock for
+ // accessing it.
+ base::Lock posted_internal_derefs_lock_;
+ int posted_internal_derefs_ = 0;
+#endif
viz::TransferableResource resource_;
std::unique_ptr<viz::SingleReleaseCallback> release_callback_;
@@ -94,7 +100,7 @@ class CC_EXPORT TextureLayer : public Layer, SharedBitmapIdRegistrar {
// ReturnAndReleaseOnImplThread() defines their values.
base::Lock arguments_lock_;
gpu::SyncToken sync_token_;
- bool is_lost_;
+ bool is_lost_ = false;
base::ThreadChecker main_thread_checker_;
DISALLOW_COPY_AND_ASSIGN(TransferableResourceHolder);
};
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index 24463ef1a26..08919e42ed9 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -15,6 +15,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
@@ -105,7 +106,7 @@ class MockReleaseCallback {
const gpu::SyncToken& sync_token,
bool lost_resource));
MOCK_METHOD3(Release2,
- void(viz::SharedBitmap* shared_bitmap,
+ void(const viz::SharedBitmapId& shared_bitmap_id,
const gpu::SyncToken& sync_token,
bool lost_resource));
};
@@ -133,14 +134,12 @@ struct CommonResourceObjects {
resource2_ = viz::TransferableResource::MakeGL(
mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
gfx::Size size(128, 128);
- shared_bitmap_ = manager->AllocateSharedBitmap(size, viz::RGBA_8888);
- DCHECK(shared_bitmap_);
+ shared_bitmap_id_ = viz::SharedBitmap::GenerateId();
release_callback3_ =
base::Bind(&MockReleaseCallback::Release2,
- base::Unretained(&mock_callback_), shared_bitmap_.get());
- resource3_ = viz::TransferableResource::MakeSoftware(
- shared_bitmap_->id(), shared_bitmap_->sequence_number(), size,
- viz::RGBA_8888);
+ base::Unretained(&mock_callback_), shared_bitmap_id_);
+ resource3_ = viz::TransferableResource::MakeSoftware(shared_bitmap_id_,
+ size, viz::RGBA_8888);
}
using RepeatingReleaseCallback =
@@ -155,7 +154,7 @@ struct CommonResourceObjects {
RepeatingReleaseCallback release_callback3_;
gpu::SyncToken sync_token1_;
gpu::SyncToken sync_token2_;
- std::unique_ptr<viz::SharedBitmap> shared_bitmap_;
+ viz::SharedBitmapId shared_bitmap_id_;
viz::TransferableResource resource1_;
viz::TransferableResource resource2_;
viz::TransferableResource resource3_;
@@ -281,7 +280,7 @@ TEST_F(TextureLayerWithResourceTest, ReplaceMailboxOnMainThreadBeforeCommit) {
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
EXPECT_CALL(test_data_.mock_callback_,
- Release2(test_data_.shared_bitmap_.get(), _, false))
+ Release2(test_data_.shared_bitmap_id_, _, false))
.Times(1);
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
@@ -505,9 +504,8 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
return std::make_unique<viz::TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
- refresh_rate);
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
}
void AdvanceTestCase() {
@@ -782,9 +780,8 @@ TEST_F(TextureLayerImplWithResourceTest, TestWillDraw) {
test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
.Times(AnyNumber());
- EXPECT_CALL(
- test_data_.mock_callback_,
- Release2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false))
+ EXPECT_CALL(test_data_.mock_callback_,
+ Release2(test_data_.shared_bitmap_id_, gpu::SyncToken(), false))
.Times(AnyNumber());
// Hardware mode.
{
@@ -1401,9 +1398,9 @@ class SoftwareTextureLayerTest : public LayerTreeTest {
!HasImplThread() &&
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
auto sink = std::make_unique<viz::TestLayerTreeFrameSink>(
- nullptr, nullptr, shared_bitmap_manager(), gpu_memory_buffer_manager(),
- renderer_settings, ImplThreadTaskRunner(), synchronous_composite,
- disable_display_vsync, refresh_rate);
+ nullptr, nullptr, gpu_memory_buffer_manager(), renderer_settings,
+ ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
+ refresh_rate);
frame_sink_ = sink.get();
num_frame_sinks_created_++;
return sink;
@@ -1450,7 +1447,7 @@ class SoftwareTextureLayerSwitchTreesTest : public SoftwareTextureLayerTest {
// Give the TextureLayer a resource so it contributes to the frame. It
// doesn't need to register the SharedBitmapId otherwise.
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
@@ -1558,7 +1555,7 @@ class SoftwareTextureLayerMultipleRegisterTest
// Give the TextureLayer a resource so it contributes to the frame. It
// doesn't need to register the SharedBitmapId otherwise.
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id1_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id1_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
@@ -1660,7 +1657,7 @@ class SoftwareTextureLayerRegisterUnregisterTest
// Give the TextureLayer a resource so it contributes to the frame. It
// doesn't need to register the SharedBitmapId otherwise.
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id1_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id1_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
@@ -1725,6 +1722,18 @@ class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
}
void DidCommitAndDrawFrame() override {
+ // We run the next step in a clean stack, so that we don't cause side
+ // effects that will interfere with this current stack unwinding.
+ // Specifically, removing the LayerTreeFrameSink destroys the Display
+ // and the BeginFrameSource, but they can be on the stack (see
+ // https://crbug.com/829484).
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SoftwareTextureLayerLoseFrameSinkTest::NextStep,
+ base::Unretained(this)));
+ }
+
+ void NextStep() {
step_ = layer_tree_host()->SourceFrameNumber();
switch (step_) {
case 1:
@@ -1736,7 +1745,7 @@ class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
// Give the TextureLayer a resource so it contributes to the frame. It
// doesn't need to register the SharedBitmapId otherwise.
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
@@ -1756,7 +1765,7 @@ class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
// VizDisplayCompositor.
texture_layer_->ClearClient();
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
@@ -1807,8 +1816,7 @@ class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
void* first_frame_sink_;
};
-// TODO(crbug.com/829923): Flaky with a heap-use-after-free.
-// SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerLoseFrameSinkTest);
+SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerLoseFrameSinkTest);
class SoftwareTextureLayerUnregisterRegisterTest
: public SoftwareTextureLayerTest {
@@ -1847,7 +1855,7 @@ class SoftwareTextureLayerUnregisterRegisterTest
// Give the TextureLayer a resource so it contributes to the frame. It
// doesn't need to register the SharedBitmapId otherwise.
texture_layer_->SetTransferableResource(
- viz::TransferableResource::MakeSoftware(id_, 0, gfx::Size(1, 1),
+ viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
viz::RGBA_8888),
viz::SingleReleaseCallback::Create(
base::BindOnce([](const gpu::SyncToken&, bool) {})));
diff --git a/chromium/cc/layers/ui_resource_layer_impl.h b/chromium/cc/layers/ui_resource_layer_impl.h
index 8660ab7a913..ed37db2cfd1 100644
--- a/chromium/cc/layers/ui_resource_layer_impl.h
+++ b/chromium/cc/layers/ui_resource_layer_impl.h
@@ -11,7 +11,6 @@
#include "base/memory/ptr_util.h"
#include "cc/cc_export.h"
#include "cc/layers/layer_impl.h"
-#include "cc/resources/resource_provider.h"
#include "cc/resources/ui_resource_client.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -21,6 +20,7 @@ class DictionaryValue;
}
namespace cc {
+class LayerTreeResourceProvider;
class CC_EXPORT UIResourceLayerImpl : public LayerImpl {
public:
diff --git a/chromium/cc/layers/ui_resource_layer_unittest.cc b/chromium/cc/layers/ui_resource_layer_unittest.cc
index 87a21390da3..e4e21aabf65 100644
--- a/chromium/cc/layers/ui_resource_layer_unittest.cc
+++ b/chromium/cc/layers/ui_resource_layer_unittest.cc
@@ -6,7 +6,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
-#include "cc/resources/resource_provider.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/geometry_test_utils.h"
diff --git a/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc
index 19481d3929e..32627b820e6 100644
--- a/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc
+++ b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc
@@ -41,7 +41,7 @@ class VideoFrameProviderClientImplTest : public testing::Test,
DebugSetImplThreadAndMainThreadBlocked(impl_.task_runner_provider());
}
- ~VideoFrameProviderClientImplTest() {
+ ~VideoFrameProviderClientImplTest() override {
if (!client_impl_->Stopped()) {
client_impl_->Stop();
DCHECK(client_impl_->Stopped());
diff --git a/chromium/cc/layers/video_layer_impl.cc b/chromium/cc/layers/video_layer_impl.cc
index d431a96572c..4e2843f2ca3 100644
--- a/chromium/cc/layers/video_layer_impl.cc
+++ b/chromium/cc/layers/video_layer_impl.cc
@@ -10,7 +10,8 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "cc/layers/video_frame_provider_client_impl.h"
-#include "cc/resources/resource_provider.h"
+#include "cc/resources/layer_tree_resource_provider.h"
+#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/occlusion.h"
#include "cc/trees/task_runner_provider.h"
@@ -107,7 +108,9 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode,
layer_tree_impl()->layer_tree_frame_sink(),
layer_tree_impl()->resource_provider(),
settings.use_stream_video_draw_quad,
- settings.resource_settings.use_gpu_memory_buffer_resources);
+ settings.resource_settings.use_gpu_memory_buffer_resources,
+ settings.resource_settings.use_r16_texture,
+ layer_tree_impl()->max_texture_size());
}
updater_->ObtainFrameResources(frame_);
return true;
diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc
index d19c08cdd93..fe4371883bb 100644
--- a/chromium/cc/layers/viewport.cc
+++ b/chromium/cc/layers/viewport.cc
@@ -150,7 +150,6 @@ gfx::Vector2dF Viewport::ScrollAnimated(const gfx::Vector2dF& delta,
will_animate =
host_impl_->ScrollAnimationCreate(outer_node, outer_delta, delayed_by);
}
-
if (will_animate) {
// Consume entire scroll delta as long as we are starting an animation.
return delta;
diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h
index d5733643139..0d8f3afaddf 100644
--- a/chromium/cc/layers/viewport.h
+++ b/chromium/cc/layers/viewport.h
@@ -62,6 +62,8 @@ class CC_EXPORT Viewport {
gfx::Vector2dF ScrollAnimated(const gfx::Vector2dF& delta,
base::TimeDelta delayed_by);
+ gfx::ScrollOffset TotalScrollOffset() const;
+
void PinchUpdate(float magnify_delta, const gfx::Point& anchor);
void PinchEnd(const gfx::Point& anchor, bool snap_to_min);
@@ -84,7 +86,6 @@ class CC_EXPORT Viewport {
gfx::Vector2dF ScrollBrowserControls(const gfx::Vector2dF& delta);
gfx::ScrollOffset MaxTotalScrollOffset() const;
- gfx::ScrollOffset TotalScrollOffset() const;
LayerImpl* InnerScrollLayer() const;
LayerImpl* OuterScrollLayer() const;
diff --git a/chromium/cc/output/overlay_candidate.cc b/chromium/cc/output/overlay_candidate.cc
deleted file mode 100644
index 829cacd0516..00000000000
--- a/chromium/cc/output/overlay_candidate.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/output/overlay_candidate.h"
-
-#include <algorithm>
-#include <limits>
-#include "base/logging.h"
-#include "cc/base/math_util.h"
-#include "cc/resources/display_resource_provider.h"
-#include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/common/quads/stream_video_draw_quad.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/quads/tile_draw_quad.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/vector3d_f.h"
-
-namespace cc {
-
-namespace {
-// Tolerance for considering axis vector elements to be zero.
-const SkMScalar kEpsilon = std::numeric_limits<float>::epsilon();
-
-const gfx::BufferFormat kOverlayFormats[] = {
- gfx::BufferFormat::RGBX_8888, gfx::BufferFormat::RGBA_8888,
- gfx::BufferFormat::BGRX_8888, gfx::BufferFormat::BGRA_8888,
- gfx::BufferFormat::BGR_565, gfx::BufferFormat::YUV_420_BIPLANAR};
-
-enum Axis { NONE, AXIS_POS_X, AXIS_NEG_X, AXIS_POS_Y, AXIS_NEG_Y };
-
-Axis VectorToAxis(const gfx::Vector3dF& vec) {
- if (std::abs(vec.z()) > kEpsilon)
- return NONE;
- const bool x_zero = (std::abs(vec.x()) <= kEpsilon);
- const bool y_zero = (std::abs(vec.y()) <= kEpsilon);
- if (x_zero && !y_zero)
- return (vec.y() > 0) ? AXIS_POS_Y : AXIS_NEG_Y;
- else if (y_zero && !x_zero)
- return (vec.x() > 0) ? AXIS_POS_X : AXIS_NEG_X;
- else
- return NONE;
-}
-
-gfx::OverlayTransform GetOverlayTransform(const gfx::Transform& quad_transform,
- bool y_flipped) {
- if (!quad_transform.Preserves2dAxisAlignment()) {
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
-
- gfx::Vector3dF x_axis = MathUtil::GetXAxis(quad_transform);
- gfx::Vector3dF y_axis = MathUtil::GetYAxis(quad_transform);
- if (y_flipped) {
- y_axis.Scale(-1);
- }
-
- Axis x_to = VectorToAxis(x_axis);
- Axis y_to = VectorToAxis(y_axis);
-
- if (x_to == AXIS_POS_X && y_to == AXIS_POS_Y)
- return gfx::OVERLAY_TRANSFORM_NONE;
- else if (x_to == AXIS_NEG_X && y_to == AXIS_POS_Y)
- return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- else if (x_to == AXIS_POS_X && y_to == AXIS_NEG_Y)
- return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- else if (x_to == AXIS_NEG_Y && y_to == AXIS_POS_X)
- return gfx::OVERLAY_TRANSFORM_ROTATE_270;
- else if (x_to == AXIS_NEG_X && y_to == AXIS_NEG_Y)
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- else if (x_to == AXIS_POS_Y && y_to == AXIS_NEG_X)
- return gfx::OVERLAY_TRANSFORM_ROTATE_90;
- else
- return gfx::OVERLAY_TRANSFORM_INVALID;
-}
-
-// Apply transform |delta| to |in| and return the resulting transform,
-// or OVERLAY_TRANSFORM_INVALID.
-gfx::OverlayTransform ComposeTransforms(gfx::OverlayTransform delta,
- gfx::OverlayTransform in) {
- // There are 8 different possible transforms. We can characterize these
- // by looking at where the origin moves and the direction the horizontal goes.
- // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
- // NONE: TL, H
- // FLIP_VERTICAL: BL, H
- // FLIP_HORIZONTAL: TR, H
- // ROTATE_90: TR, V
- // ROTATE_180: BR, H
- // ROTATE_270: BL, V
- // Missing transforms: TL, V & BR, V
- // Basic combinations:
- // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
- // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
- // Rotate + Rotate simply adds values.
- // Rotate 90/270 + flip is invalid because we can only have verticals with
- // the origin in TR or BL.
- if (delta == gfx::OVERLAY_TRANSFORM_NONE)
- return in;
- switch (in) {
- case gfx::OVERLAY_TRANSFORM_NONE:
- return delta;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_ROTATE_270;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_NONE;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_ROTATE_270;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_ROTATE_90;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_ROTATE_90;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
-}
-
-} // namespace
-
-OverlayCandidate::OverlayCandidate()
- : transform(gfx::OVERLAY_TRANSFORM_NONE),
- format(gfx::BufferFormat::RGBA_8888),
- uv_rect(0.f, 0.f, 1.f, 1.f),
- is_clipped(false),
- is_opaque(false),
- use_output_surface_for_resource(false),
- resource_id(0),
-#if defined(OS_ANDROID)
- is_backed_by_surface_texture(false),
- is_promotable_hint(false),
-#endif
- plane_z_order(0),
- is_unoccluded(false),
- overlay_handled(false) {
-}
-
-OverlayCandidate::OverlayCandidate(const OverlayCandidate& other) = default;
-
-OverlayCandidate::~OverlayCandidate() = default;
-
-// static
-bool OverlayCandidate::FromDrawQuad(DisplayResourceProvider* resource_provider,
- const SkMatrix44& output_color_matrix,
- const viz::DrawQuad* quad,
- OverlayCandidate* candidate) {
- // It is currently not possible to set a color conversion matrix on an HW
- // overlay plane.
- // TODO(dcastagna): Remove this check once crbug.com/792757 is resolved.
- if (!output_color_matrix.isIdentity())
- return false;
-
- // We don't support an opacity value different than one for an overlay plane.
- if (quad->shared_quad_state->opacity != 1.f)
- return false;
- // We support only kSrc (no blending) and kSrcOver (blending with premul).
- if (!(quad->shared_quad_state->blend_mode == SkBlendMode::kSrc ||
- quad->shared_quad_state->blend_mode == SkBlendMode::kSrcOver))
- return false;
-
- switch (quad->material) {
- case viz::DrawQuad::TEXTURE_CONTENT:
- return FromTextureQuad(resource_provider,
- viz::TextureDrawQuad::MaterialCast(quad),
- candidate);
- case viz::DrawQuad::TILED_CONTENT:
- return FromTileQuad(resource_provider,
- viz::TileDrawQuad::MaterialCast(quad), candidate);
- case viz::DrawQuad::STREAM_VIDEO_CONTENT:
- return FromStreamVideoQuad(resource_provider,
- viz::StreamVideoDrawQuad::MaterialCast(quad),
- candidate);
- default:
- break;
- }
-
- return false;
-}
-
-// static
-bool OverlayCandidate::IsInvisibleQuad(const viz::DrawQuad* quad) {
- float opacity = quad->shared_quad_state->opacity;
- if (opacity < std::numeric_limits<float>::epsilon())
- return true;
- if (quad->material == viz::DrawQuad::SOLID_COLOR) {
- SkColor color = viz::SolidColorDrawQuad::MaterialCast(quad)->color;
- float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
- return quad->ShouldDrawWithBlending() &&
- alpha < std::numeric_limits<float>::epsilon();
- }
- return false;
-}
-
-// static
-bool OverlayCandidate::IsOccluded(const OverlayCandidate& candidate,
- viz::QuadList::ConstIterator quad_list_begin,
- viz::QuadList::ConstIterator quad_list_end) {
- // Check that no visible quad overlaps the candidate.
- for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end;
- ++overlap_iter) {
- gfx::RectF overlap_rect = MathUtil::MapClippedRect(
- overlap_iter->shared_quad_state->quad_to_target_transform,
- gfx::RectF(overlap_iter->rect));
- if (candidate.display_rect.Intersects(overlap_rect) &&
- !OverlayCandidate::IsInvisibleQuad(*overlap_iter))
- return true;
- }
- return false;
-}
-
-// static
-bool OverlayCandidate::FromDrawQuadResource(
- DisplayResourceProvider* resource_provider,
- const viz::DrawQuad* quad,
- viz::ResourceId resource_id,
- bool y_flipped,
- OverlayCandidate* candidate) {
- if (!resource_provider->IsOverlayCandidate(resource_id))
- return false;
-
- candidate->format = resource_provider->GetBufferFormat(resource_id);
- if (std::find(std::begin(kOverlayFormats), std::end(kOverlayFormats),
- candidate->format) == std::end(kOverlayFormats))
- return false;
-
- gfx::OverlayTransform overlay_transform = GetOverlayTransform(
- quad->shared_quad_state->quad_to_target_transform, y_flipped);
- if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
- return false;
-
- auto& transform = quad->shared_quad_state->quad_to_target_transform;
- candidate->display_rect = gfx::RectF(quad->rect);
- transform.TransformRect(&candidate->display_rect);
-
- candidate->clip_rect = quad->shared_quad_state->clip_rect;
- candidate->is_clipped = quad->shared_quad_state->is_clipped;
- candidate->is_opaque = !quad->ShouldDrawWithBlending();
-
- candidate->resource_id = resource_id;
- candidate->transform = overlay_transform;
-
- return true;
-}
-
-// static
-bool OverlayCandidate::FromTextureQuad(
- DisplayResourceProvider* resource_provider,
- const viz::TextureDrawQuad* quad,
- OverlayCandidate* candidate) {
- if (quad->background_color != SK_ColorTRANSPARENT)
- return false;
- if (!FromDrawQuadResource(resource_provider, quad, quad->resource_id(),
- quad->y_flipped, candidate)) {
- return false;
- }
- candidate->resource_size_in_pixels = quad->resource_size_in_pixels();
- candidate->uv_rect = BoundingRect(quad->uv_top_left, quad->uv_bottom_right);
- return true;
-}
-
-// static
-bool OverlayCandidate::FromTileQuad(DisplayResourceProvider* resource_provider,
- const viz::TileDrawQuad* quad,
- OverlayCandidate* candidate) {
- if (!FromDrawQuadResource(resource_provider, quad, quad->resource_id(), false,
- candidate)) {
- return false;
- }
- candidate->resource_size_in_pixels = quad->texture_size;
- candidate->uv_rect = quad->tex_coord_rect;
- return true;
-}
-
-// static
-bool OverlayCandidate::FromStreamVideoQuad(
- DisplayResourceProvider* resource_provider,
- const viz::StreamVideoDrawQuad* quad,
- OverlayCandidate* candidate) {
- if (!FromDrawQuadResource(resource_provider, quad, quad->resource_id(), false,
- candidate)) {
- return false;
- }
- if (!quad->matrix.IsScaleOrTranslation()) {
- // We cannot handle anything other than scaling & translation for texture
- // coordinates yet.
- return false;
- }
- candidate->resource_id = quad->resource_id();
- candidate->resource_size_in_pixels = quad->resource_size_in_pixels();
-#if defined(OS_ANDROID)
- candidate->is_backed_by_surface_texture =
- resource_provider->IsBackedBySurfaceTexture(quad->resource_id());
-#endif
-
- gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
- gfx::Point3F uv1 = gfx::Point3F(1, 1, 0);
- quad->matrix.TransformPoint(&uv0);
- quad->matrix.TransformPoint(&uv1);
- gfx::Vector3dF delta = uv1 - uv0;
- if (delta.x() < 0) {
- candidate->transform = ComposeTransforms(
- gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL, candidate->transform);
- float x0 = uv0.x();
- uv0.set_x(uv1.x());
- uv1.set_x(x0);
- delta.set_x(-delta.x());
- }
-
- if (delta.y() < 0) {
- // In this situation, uv0y < uv1y. Since we overlay inverted, a request
- // to invert the source texture means we can just output the texture
- // normally and it will be correct.
- candidate->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y());
- } else {
- candidate->transform = ComposeTransforms(
- gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL, candidate->transform);
- candidate->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y());
- }
- return true;
-}
-
-OverlayCandidateList::OverlayCandidateList() = default;
-
-OverlayCandidateList::OverlayCandidateList(const OverlayCandidateList& other) =
- default;
-
-OverlayCandidateList::OverlayCandidateList(OverlayCandidateList&& other) =
- default;
-
-OverlayCandidateList::~OverlayCandidateList() = default;
-
-OverlayCandidateList& OverlayCandidateList::operator=(
- const OverlayCandidateList& other) = default;
-
-OverlayCandidateList& OverlayCandidateList::operator=(
- OverlayCandidateList&& other) = default;
-
-void OverlayCandidateList::AddPromotionHint(const OverlayCandidate& candidate) {
- promotion_hint_info_map_[candidate.resource_id] = candidate.display_rect;
-}
-
-} // namespace cc
diff --git a/chromium/cc/output/overlay_candidate.h b/chromium/cc/output/overlay_candidate.h
deleted file mode 100644
index f304951e83a..00000000000
--- a/chromium/cc/output/overlay_candidate.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_OUTPUT_OVERLAY_CANDIDATE_H_
-#define CC_OUTPUT_OVERLAY_CANDIDATE_H_
-
-#include <map>
-#include <vector>
-
-#include "cc/cc_export.h"
-#include "components/viz/common/quads/render_pass.h"
-#include "components/viz/common/resources/resource_id.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/overlay_transform.h"
-#include "ui/gfx/transform.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace viz {
-class StreamVideoDrawQuad;
-class TextureDrawQuad;
-class TileDrawQuad;
-} // namespace viz
-
-namespace cc {
-class DisplayResourceProvider;
-
-class CC_EXPORT OverlayCandidate {
- public:
- // Returns true and fills in |candidate| if |draw_quad| is of a known quad
- // type and contains an overlayable resource.
- static bool FromDrawQuad(DisplayResourceProvider* resource_provider,
- const SkMatrix44& output_color_matrix,
- const viz::DrawQuad* quad,
- OverlayCandidate* candidate);
- // Returns true if |quad| will not block quads underneath from becoming
- // an overlay.
- static bool IsInvisibleQuad(const viz::DrawQuad* quad);
-
- // Returns true if any any of the quads in the list given by |quad_list_begin|
- // and |quad_list_end| are visible and on top of |candidate|.
- static bool IsOccluded(const OverlayCandidate& candidate,
- viz::QuadList::ConstIterator quad_list_begin,
- viz::QuadList::ConstIterator quad_list_end);
-
- OverlayCandidate();
- OverlayCandidate(const OverlayCandidate& other);
- ~OverlayCandidate();
-
- // Transformation to apply to layer during composition.
- gfx::OverlayTransform transform;
- // Format of the buffer to scanout.
- gfx::BufferFormat format;
- // Size of the resource, in pixels.
- gfx::Size resource_size_in_pixels;
- // Rect on the display to position the overlay to. Implementer must convert
- // to integer coordinates if setting |overlay_handled| to true.
- gfx::RectF display_rect;
- // Crop within the buffer to be placed inside |display_rect|.
- gfx::RectF uv_rect;
- // Clip rect in the target content space after composition.
- gfx::Rect clip_rect;
- // If the quad is clipped after composition.
- bool is_clipped;
- // If the quad doesn't require blending.
- bool is_opaque;
- // True if the texture for this overlay should be the same one used by the
- // output surface's main overlay.
- bool use_output_surface_for_resource;
- // Texture resource to present in an overlay.
- unsigned resource_id;
-
-#if defined(OS_ANDROID)
- // For candidates from StreamVideoDrawQuads, this records whether the quad is
- // marked as being backed by a SurfaceTexture or not. If so, it's not really
- // promotable to an overlay.
- bool is_backed_by_surface_texture;
-
- // Filled in by the OverlayCandidateValidator to indicate whether this is a
- // promotable candidate or not.
- bool is_promotable_hint;
-#endif
-
- // Stacking order of the overlay plane relative to the main surface,
- // which is 0. Signed to allow for "underlays".
- int plane_z_order;
- // True if the overlay does not have any visible quads on top of it. Set by
- // the strategy so the OverlayProcessor can consider subtracting damage caused
- // by underlay quads.
- bool is_unoccluded;
-
- // To be modified by the implementer if this candidate can go into
- // an overlay.
- bool overlay_handled;
-
- private:
- static bool FromDrawQuadResource(DisplayResourceProvider* resource_provider,
- const viz::DrawQuad* quad,
- viz::ResourceId resource_id,
- bool y_flipped,
- OverlayCandidate* candidate);
- static bool FromTextureQuad(DisplayResourceProvider* resource_provider,
- const viz::TextureDrawQuad* quad,
- OverlayCandidate* candidate);
- static bool FromTileQuad(DisplayResourceProvider* resource_provider,
- const viz::TileDrawQuad* quad,
- OverlayCandidate* candidate);
- static bool FromStreamVideoQuad(DisplayResourceProvider* resource_provider,
- const viz::StreamVideoDrawQuad* quad,
- OverlayCandidate* candidate);
-};
-
-class CC_EXPORT OverlayCandidateList : public std::vector<OverlayCandidate> {
- public:
- OverlayCandidateList();
- OverlayCandidateList(const OverlayCandidateList&);
- OverlayCandidateList(OverlayCandidateList&&);
- ~OverlayCandidateList();
-
- OverlayCandidateList& operator=(const OverlayCandidateList&);
- OverlayCandidateList& operator=(OverlayCandidateList&&);
-
- // [id] == candidate's |display_rect| for all promotable resources.
- using PromotionHintInfoMap = std::map<viz::ResourceId, gfx::RectF>;
-
- // For android, this provides a set of resources that could be promoted to
- // overlay, if one backs them with a SurfaceView.
- PromotionHintInfoMap promotion_hint_info_map_;
-
- // Helper to insert |candidate| into |promotion_hint_info_|.
- void AddPromotionHint(const OverlayCandidate& candidate);
-};
-
-} // namespace cc
-
-#endif // CC_OUTPUT_OVERLAY_CANDIDATE_H_
diff --git a/chromium/cc/paint/BUILD.gn b/chromium/cc/paint/BUILD.gn
index 535acba1472..92306d62373 100644
--- a/chromium/cc/paint/BUILD.gn
+++ b/chromium/cc/paint/BUILD.gn
@@ -67,6 +67,8 @@ cc_component("paint") {
"paint_typeface.h",
"paint_typeface_transfer_cache_entry.cc",
"paint_typeface_transfer_cache_entry.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",
@@ -75,6 +77,8 @@ cc_component("paint") {
"render_surface_filters.h",
"scoped_raster_flags.cc",
"scoped_raster_flags.h",
+ "shader_transfer_cache_entry.cc",
+ "shader_transfer_cache_entry.h",
"skia_paint_canvas.cc",
"skia_paint_canvas.h",
"skia_paint_image_generator.cc",
@@ -120,6 +124,7 @@ fuzzer_test("paint_op_buffer_fuzzer") {
"//cc:test_support",
"//cc/paint",
"//components/viz/test:test_support",
+ "//gpu/command_buffer/service:gles2",
]
}
diff --git a/chromium/cc/paint/DEPS b/chromium/cc/paint/DEPS
index 3761569771d..7c3f35427c6 100644
--- a/chromium/cc/paint/DEPS
+++ b/chromium/cc/paint/DEPS
@@ -1,6 +1,7 @@
specific_include_rules = {
"paint_op_buffer_fuzzer.cc": [
"+components/viz/test",
+ "+gpu/command_buffer",
],
"transfer_cache_fuzzer.cc": [
"+components/viz/test",
diff --git a/chromium/cc/paint/display_item_list.h b/chromium/cc/paint/display_item_list.h
index 0ade2b179f3..feb8e5407b7 100644
--- a/chromium/cc/paint/display_item_list.h
+++ b/chromium/cc/paint/display_item_list.h
@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -28,6 +29,7 @@ class SkCanvas;
namespace gpu {
namespace raster {
+class RasterImplementation;
class RasterImplementationGLES;
} // namespace raster
} // namespace gpu
@@ -192,6 +194,7 @@ class CC_PAINT_EXPORT DisplayItemList
private:
FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, AsValueWithNoOps);
FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, AsValueWithOps);
+ friend gpu::raster::RasterImplementation;
friend gpu::raster::RasterImplementationGLES;
~DisplayItemList();
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index c0f6d025f2c..493a9840a18 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -59,7 +59,11 @@ uint32_t ClientImageTransferCacheEntry::Id() const {
bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
DCHECK_GE(data.size(), SerializedSize());
- PaintOpWriter writer(data.data(), data.size(), nullptr, nullptr);
+ // 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, SkMatrix::I());
+ PaintOpWriter writer(data.data(), data.size(), options);
writer.Write(pixmap_->colorType());
writer.Write(pixmap_->width());
writer.Write(pixmap_->height());
@@ -90,7 +94,10 @@ size_t ServiceImageTransferCacheEntry::CachedSize() const {
bool ServiceImageTransferCacheEntry::Deserialize(
GrContext* context,
base::span<const uint8_t> data) {
- PaintOpReader reader(data.data(), data.size(), nullptr);
+ // We don't need to populate the DeSerializeOptions here since the reader is
+ // only used for de-serializing primitives.
+ PaintOp::DeserializeOptions options(nullptr, nullptr);
+ PaintOpReader reader(data.data(), data.size(), options);
SkColorType color_type;
reader.Read(&color_type);
uint32_t width;
diff --git a/chromium/cc/paint/image_transfer_cache_entry.h b/chromium/cc/paint/image_transfer_cache_entry.h
index fd3937d0926..3e709cafd64 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.h
+++ b/chromium/cc/paint/image_transfer_cache_entry.h
@@ -56,9 +56,6 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
- void set_image_for_testing(sk_sp<SkImage> image) {
- image_ = std::move(image);
- }
const sk_sp<SkImage>& image() { return image_; }
private:
diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc
index 6850d6f9ad9..cb3168a7783 100644
--- a/chromium/cc/paint/oop_pixeltest.cc
+++ b/chromium/cc/paint/oop_pixeltest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
#include <vector>
#include "base/command_line.h"
@@ -10,7 +11,9 @@
#include "cc/base/region.h"
#include "cc/layers/recording_source.h"
#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"
@@ -50,25 +53,25 @@ scoped_refptr<DisplayItemList> MakeNoopDisplayItemList() {
class OopPixelTest : public testing::Test {
public:
void SetUp() override {
- // Add an OOP rasterization command line flag so that we set
- // |chromium_raster_transport| features flag.
- // TODO(vmpstr): Is there a better way to do this?
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableOOPRasterization)) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableOOPRasterization);
- }
-
- context_provider_ =
- base::MakeRefCounted<TestInProcessContextProvider>(nullptr, true);
- int max_texture_size =
- context_provider_->ContextCapabilities().max_texture_size;
+ raster_context_provider_ =
+ base::MakeRefCounted<TestInProcessContextProvider>(
+ /*enable_oop_rasterization=*/true);
+ const int raster_max_texture_size =
+ raster_context_provider_->ContextCapabilities().max_texture_size;
oop_image_cache_.reset(new GpuImageDecodeCache(
- context_provider_.get(), true, kRGBA_8888_SkColorType, kWorkingSetSize,
- max_texture_size));
+ raster_context_provider_.get(), true, kRGBA_8888_SkColorType,
+ kWorkingSetSize, raster_max_texture_size));
+
+ gles2_context_provider_ =
+ base::MakeRefCounted<TestInProcessContextProvider>(
+ /*enable_oop_rasterization=*/false);
+ const int gles2_max_texture_size =
+ raster_context_provider_->ContextCapabilities().max_texture_size;
gpu_image_cache_.reset(new GpuImageDecodeCache(
- context_provider_.get(), false, kRGBA_8888_SkColorType, kWorkingSetSize,
- max_texture_size));
+ gles2_context_provider_.get(), false, kRGBA_8888_SkColorType,
+ kWorkingSetSize, gles2_max_texture_size));
+
+ ASSERT_EQ(raster_max_texture_size, gles2_max_texture_size);
}
class RasterOptions {
@@ -107,24 +110,25 @@ class OopPixelTest : public testing::Test {
SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
TestInProcessContextProvider::ScopedRasterContextLock lock(
- context_provider_.get());
+ raster_context_provider_.get());
PlaybackImageProvider image_provider(oop_image_cache_.get(),
options.color_space,
PlaybackImageProvider::Settings());
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ 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;
- auto* raster_implementation = context_provider_->RasterInterface();
+
+ 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, 1, width, height);
raster_implementation->TexParameteri(raster_texture_id,
- GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ GL_TEXTURE_MIN_FILTER, GL_NEAREST);
EXPECT_EQ(raster_implementation->GetError(),
static_cast<unsigned>(GL_NO_ERROR));
@@ -211,8 +215,8 @@ class OopPixelTest : public testing::Test {
scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
TestInProcessContextProvider::ScopedRasterContextLock lock(
- context_provider_.get());
- context_provider_->GrContext()->resetContext();
+ gles2_context_provider_.get());
+ gles2_context_provider_->GrContext()->resetContext();
// Generate bitmap via the "in process" raster path. This verifies
// that the preamble setup in RasterSource::PlaybackToCanvas matches
@@ -244,8 +248,8 @@ class OopPixelTest : public testing::Test {
}
SkImageInfo image_info = SkImageInfo::MakeN32Premul(
options.resource_size.width(), options.resource_size.height());
- auto surface = SkSurface::MakeRenderTarget(context_provider_->GrContext(),
- SkBudgeted::kYes, image_info);
+ auto surface = SkSurface::MakeRenderTarget(
+ gles2_context_provider_->GrContext(), SkBudgeted::kYes, image_info);
SkCanvas* canvas = surface->getCanvas();
if (options.preclear)
canvas->drawColor(options.preclear_color);
@@ -259,7 +263,7 @@ class OopPixelTest : public testing::Test {
options.full_raster_rect, options.playback_rect, raster_transform,
settings);
surface->prepareForExternalIO();
- EXPECT_EQ(context_provider_->ContextGL()->GetError(),
+ EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(),
static_cast<unsigned>(GL_NO_ERROR));
SkBitmap bitmap;
@@ -269,7 +273,7 @@ class OopPixelTest : public testing::Test {
bitmap.allocPixels(info, options.resource_size.width() * 4);
bool success = surface->readPixels(bitmap, 0, 0);
CHECK(success);
- EXPECT_EQ(context_provider_->ContextGL()->GetError(),
+ EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(),
static_cast<unsigned>(GL_NO_ERROR));
return bitmap;
}
@@ -293,7 +297,8 @@ class OopPixelTest : public testing::Test {
protected:
enum { kWorkingSetSize = 64 * 1024 * 1024 };
- scoped_refptr<TestInProcessContextProvider> context_provider_;
+ scoped_refptr<TestInProcessContextProvider> raster_context_provider_;
+ scoped_refptr<TestInProcessContextProvider> gles2_context_provider_;
std::unique_ptr<GpuImageDecodeCache> gpu_image_cache_;
std::unique_ptr<GpuImageDecodeCache> oop_image_cache_;
gl::DisableNullDrawGLBindings enable_pixel_output_;
@@ -305,9 +310,11 @@ class OopImagePixelTest : public OopPixelTest,
public ::testing::WithParamInterface<bool> {
public:
bool UseTooLargeImage() { return GetParam(); }
+ SkFilterQuality FilterQuality() { return kNone_SkFilterQuality; }
+
gfx::Size GetImageSize() {
const int kMaxSize = 20000;
- DCHECK_GT(kMaxSize, context_provider_->GrContext()->maxTextureSize());
+ DCHECK_GT(kMaxSize, gles2_context_provider_->GrContext()->maxTextureSize());
return UseTooLargeImage() ? gfx::Size(10, kMaxSize) : gfx::Size(10, 10);
}
};
@@ -401,6 +408,9 @@ TEST_F(OopPixelTest, DrawRect) {
}
TEST_P(OopImagePixelTest, DrawImage) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
gfx::Rect rect(10, 10);
gfx::Size image_size = GetImageSize();
@@ -423,7 +433,9 @@ TEST_P(OopImagePixelTest, DrawImage) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
@@ -434,7 +446,136 @@ TEST_P(OopImagePixelTest, DrawImage) {
EXPECT_EQ(actual.getColor(0, 0), SK_ColorMAGENTA);
}
+TEST_P(OopImagePixelTest, DrawImageScaled) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
+ gfx::Rect rect(10, 10);
+ gfx::Size image_size = GetImageSize();
+
+ SkBitmap bitmap;
+ bitmap.allocPixelsFlags(
+ SkImageInfo::MakeN32Premul(image_size.width(), image_size.height()),
+ SkBitmap::kZeroPixels_AllocFlag);
+
+ SkCanvas canvas(bitmap);
+ canvas.drawColor(SK_ColorMAGENTA);
+ SkPaint green;
+ green.setColor(SK_ColorGREEN);
+ canvas.drawRect(SkRect::MakeXYWH(1, 2, 3, 4), green);
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ auto builder = PaintImageBuilder::WithDefault().set_image(image, 0).set_id(
+ PaintImage::GetNextId());
+ auto paint_image = builder.TakePaintImage();
+
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+ display_item_list->StartPaint();
+ display_item_list->push<ScaleOp>(0.5f, 0.5f);
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
+ display_item_list->EndPaintOfUnpaired(rect);
+ display_item_list->Finalize();
+
+ auto actual = Raster(display_item_list, rect.size());
+ auto expected = RasterExpectedBitmap(display_item_list, rect.size());
+ ExpectEquals(actual, expected);
+}
+
+TEST_P(OopImagePixelTest, DrawImageShaderScaled) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
+ gfx::Rect rect(10, 10);
+ gfx::Size image_size = GetImageSize();
+
+ SkBitmap bitmap;
+ bitmap.allocPixelsFlags(
+ SkImageInfo::MakeN32Premul(image_size.width(), image_size.height()),
+ SkBitmap::kZeroPixels_AllocFlag);
+
+ SkCanvas canvas(bitmap);
+ canvas.drawColor(SK_ColorMAGENTA);
+ SkPaint green;
+ green.setColor(SK_ColorGREEN);
+ canvas.drawRect(SkRect::MakeXYWH(1, 2, 3, 4), green);
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ auto builder = PaintImageBuilder::WithDefault().set_image(image, 0).set_id(
+ PaintImage::GetNextId());
+ auto paint_image = builder.TakePaintImage();
+ auto paint_image_shader =
+ PaintShader::MakeImage(paint_image, SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode, nullptr);
+
+ auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+ display_item_list->StartPaint();
+ display_item_list->push<ScaleOp>(0.5f, 0.5f);
+ PaintFlags flags;
+ flags.setShader(paint_image_shader);
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawRectOp>(gfx::RectToSkRect(rect), flags);
+ display_item_list->EndPaintOfUnpaired(rect);
+ display_item_list->Finalize();
+
+ auto actual = Raster(display_item_list, rect.size());
+ auto expected = RasterExpectedBitmap(display_item_list, rect.size());
+ ExpectEquals(actual, expected);
+}
+
+TEST_P(OopImagePixelTest, DrawRecordShaderWithImageScaled) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
+ gfx::Rect rect(10, 10);
+ gfx::Size image_size = GetImageSize();
+
+ SkBitmap bitmap;
+ bitmap.allocPixelsFlags(
+ SkImageInfo::MakeN32Premul(image_size.width(), image_size.height()),
+ SkBitmap::kZeroPixels_AllocFlag);
+
+ SkCanvas canvas(bitmap);
+ canvas.drawColor(SK_ColorMAGENTA);
+ SkPaint green;
+ green.setColor(SK_ColorGREEN);
+ canvas.drawRect(SkRect::MakeXYWH(1, 2, 3, 4), green);
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ auto builder = PaintImageBuilder::WithDefault().set_image(image, 0).set_id(
+ PaintImage::GetNextId());
+ auto paint_image = builder.TakePaintImage();
+ auto paint_record = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ paint_record->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
+ 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();
+ display_item_list->push<ScaleOp>(0.5f, 0.5f);
+ PaintFlags raster_flags;
+ raster_flags.setShader(paint_record_shader);
+ raster_flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawRectOp>(gfx::RectToSkRect(rect), raster_flags);
+ display_item_list->EndPaintOfUnpaired(rect);
+ display_item_list->Finalize();
+
+ auto actual = Raster(display_item_list, rect.size());
+ auto expected = RasterExpectedBitmap(display_item_list, rect.size());
+ ExpectEquals(actual, expected);
+}
+
TEST_P(OopImagePixelTest, DrawImageWithTargetColorSpace) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
gfx::Rect rect(10, 10);
gfx::Size image_size = GetImageSize();
@@ -457,7 +598,9 @@ TEST_P(OopImagePixelTest, DrawImageWithTargetColorSpace) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
@@ -473,6 +616,9 @@ TEST_P(OopImagePixelTest, DrawImageWithTargetColorSpace) {
}
TEST_P(OopImagePixelTest, DrawImageWithSourceColorSpace) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
gfx::Rect rect(10, 10);
gfx::Size image_size = GetImageSize();
@@ -498,7 +644,9 @@ TEST_P(OopImagePixelTest, DrawImageWithSourceColorSpace) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
@@ -513,6 +661,9 @@ TEST_P(OopImagePixelTest, DrawImageWithSourceColorSpace) {
}
TEST_P(OopImagePixelTest, DrawImageWithSourceAndTargetColorSpace) {
+ SCOPED_TRACE(base::StringPrintf("UseTooLargeImage: %d, FilterQuality: %d\n",
+ UseTooLargeImage(), FilterQuality()));
+
gfx::Rect rect(10, 10);
gfx::Size image_size = GetImageSize();
@@ -538,7 +689,9 @@ TEST_P(OopImagePixelTest, DrawImageWithSourceAndTargetColorSpace) {
auto display_item_list = base::MakeRefCounted<DisplayItemList>();
display_item_list->StartPaint();
- display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
+ PaintFlags flags;
+ flags.setFilterQuality(FilterQuality());
+ display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags);
display_item_list->EndPaintOfUnpaired(rect);
display_item_list->Finalize();
@@ -1047,7 +1200,112 @@ TEST_F(OopPixelTest, DrawRectColorSpace) {
ExpectEquals(actual, expected);
}
-INSTANTIATE_TEST_CASE_P(P, OopImagePixelTest, ::testing::Values(false, true));
+scoped_refptr<PaintTextBlob> buildTextBlob() {
+ SkFontStyle style;
+ PaintTypeface typeface =
+ PaintTypeface::FromFamilyNameAndFontStyle("monospace", style);
+
+ PaintFont font;
+ font.SetTypeface(typeface);
+ font.SetTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ font.SetHinting(SkPaint::kNormal_Hinting);
+ font.SetTextSize(10u);
+
+ PaintTextBlobBuilder builder;
+ SkRect bounds = SkRect::MakeWH(100, 100);
+ const int glyphCount = 10;
+ 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();
+}
+
+TEST_F(OopPixelTest, DrawTextBlob) {
+ 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();
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ display_item_list->push<DrawTextBlobOp>(buildTextBlob(), 0u, 0u, 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_F(OopPixelTest, DrawRecordShaderWithTextScaled) {
+ 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 paint_record = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ paint_record->push<DrawTextBlobOp>(buildTextBlob(), 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);
+}
+
+TEST_F(OopPixelTest, DrawRecordFilterWithTextScaled) {
+ 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 paint_record = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+ flags.setColor(SK_ColorGREEN);
+ paint_record->push<DrawTextBlobOp>(buildTextBlob(), 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);
+}
+
+INSTANTIATE_TEST_CASE_P(P, OopImagePixelTest, ::testing::Bool());
} // namespace
} // namespace cc
diff --git a/chromium/cc/paint/paint_filter.cc b/chromium/cc/paint/paint_filter.cc
index 947973cb130..f410b273562 100644
--- a/chromium/cc/paint/paint_filter.cc
+++ b/chromium/cc/paint/paint_filter.cc
@@ -980,8 +980,7 @@ PaintFlagsPaintFilter::PaintFlagsPaintFilter(PaintFlags flags,
: PaintFilter(kType, crop_rect, flags.HasDiscardableImages()),
flags_(std::move(flags)) {
if (image_provider) {
- raster_flags_.emplace(&flags_, image_provider, SkMatrix::I(), 255u,
- true /* create_skia_shaders */);
+ raster_flags_.emplace(&flags_, image_provider, SkMatrix::I(), 255u);
}
cached_sk_filter_ = SkPaintImageFilter::Make(
raster_flags_ ? raster_flags_->flags()->ToSkPaint() : flags_.ToSkPaint(),
diff --git a/chromium/cc/paint/paint_image.cc b/chromium/cc/paint/paint_image.cc
index 414e5988442..805520f8b37 100644
--- a/chromium/cc/paint/paint_image.cc
+++ b/chromium/cc/paint/paint_image.cc
@@ -15,8 +15,8 @@
namespace cc {
namespace {
-base::AtomicSequenceNumber g_next_id_;
-base::AtomicSequenceNumber g_next_content_id_;
+base::AtomicSequenceNumber g_next_image_id;
+base::AtomicSequenceNumber g_next_image_content_id;
} // namespace
const PaintImage::Id PaintImage::kNonLazyStableId = -1;
@@ -74,12 +74,12 @@ PaintImage::DecodingMode PaintImage::GetConservative(DecodingMode one,
// static
PaintImage::Id PaintImage::GetNextId() {
- return g_next_id_.GetNext();
+ return g_next_image_id.GetNext();
}
// static
PaintImage::ContentId PaintImage::GetNextContentId() {
- return g_next_content_id_.GetNext();
+ return g_next_image_content_id.GetNext();
}
const sk_sp<SkImage>& PaintImage::GetSkImage() const {
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 446fc6e1ec6..45ae2526f15 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -26,6 +26,23 @@ DrawImage CreateDrawImage(const PaintImage& image,
flags ? flags->getFilterQuality() : kLow_SkFilterQuality,
matrix);
}
+
+bool IsScaleAdjustmentIdentity(const SkSize& scale_adjustment) {
+ return std::abs(scale_adjustment.width() - 1.f) < FLT_EPSILON &&
+ std::abs(scale_adjustment.height() - 1.f) < FLT_EPSILON;
+}
+
+SkRect AdjustSrcRectForScale(SkRect original, SkSize scale_adjustment) {
+ if (IsScaleAdjustmentIdentity(scale_adjustment))
+ return original;
+
+ float x_scale = scale_adjustment.width();
+ float y_scale = scale_adjustment.height();
+ return SkRect::MakeXYWH(original.x() * x_scale, original.y() * y_scale,
+ original.width() * x_scale,
+ original.height() * y_scale);
+}
+
} // namespace
#define TYPES(M) \
@@ -297,25 +314,37 @@ PlaybackParams::PlaybackParams(ImageProvider* image_provider,
PlaybackParams::~PlaybackParams() {}
-PaintOp::SerializeOptions::SerializeOptions() = default;
+PlaybackParams::PlaybackParams(const PlaybackParams& other) = default;
+PlaybackParams& PlaybackParams::operator=(const PlaybackParams& other) =
+ default;
PaintOp::SerializeOptions::SerializeOptions(
ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
SkCanvas* canvas,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text,
const SkMatrix& original_ctm)
- : transfer_cache(transfer_cache),
+ : image_provider(image_provider),
+ transfer_cache(transfer_cache),
canvas(canvas),
- image_provider(image_provider),
+ strike_server(strike_server),
+ color_space(color_space),
+ can_use_lcd_text(can_use_lcd_text),
original_ctm(original_ctm) {}
+PaintOp::DeserializeOptions::DeserializeOptions(
+ TransferCacheDeserializeHelper* transfer_cache,
+ SkStrikeClient* strike_client)
+ : transfer_cache(transfer_cache), strike_client(strike_client) {}
+
size_t AnnotateOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const AnnotateOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
helper.Write(op->annotation_type);
helper.Write(op->rect);
helper.Write(op->data);
@@ -327,8 +356,7 @@ size_t ClipPathOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const ClipPathOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
helper.Write(op->path);
helper.Write(op->op);
helper.Write(op->antialias);
@@ -375,8 +403,7 @@ size_t DrawDRRectOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawDRRectOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -391,15 +418,20 @@ size_t DrawImageOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawImageOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
helper.Write(*serialized_flags);
+
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
helper.Write(CreateDrawImage(op->image, serialized_flags,
- options.canvas->getTotalMatrix()));
+ options.canvas->getTotalMatrix()),
+ &scale_adjustment);
helper.AlignMemory(alignof(SkScalar));
+ helper.Write(scale_adjustment.width());
+ helper.Write(scale_adjustment.height());
+
helper.Write(op->left);
helper.Write(op->top);
return helper.size();
@@ -410,14 +442,22 @@ size_t DrawImageRectOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawImageRectOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
helper.Write(*serialized_flags);
+
+ // Note that we don't request subsets here since the GpuImageCache has no
+ // optimizations for using subsets.
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
helper.Write(CreateDrawImage(op->image, serialized_flags,
- options.canvas->getTotalMatrix()));
+ options.canvas->getTotalMatrix()),
+ &scale_adjustment);
+ helper.AlignMemory(alignof(SkScalar));
+ helper.Write(scale_adjustment.width());
+ helper.Write(scale_adjustment.height());
+
helper.Write(op->src);
helper.Write(op->dst);
helper.Write(op->constraint);
@@ -429,8 +469,7 @@ size_t DrawIRectOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawIRectOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -444,8 +483,7 @@ size_t DrawLineOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawLineOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -463,8 +501,7 @@ size_t DrawOvalOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawOvalOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -478,8 +515,7 @@ size_t DrawPathOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawPathOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -503,8 +539,7 @@ size_t DrawRectOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawRectOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -518,8 +553,7 @@ size_t DrawRRectOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawRRectOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -533,8 +567,7 @@ size_t DrawTextBlobOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const DrawTextBlobOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -579,8 +612,7 @@ size_t SaveLayerOp::Serialize(const PaintOp* base_op,
size_t size,
const SerializeOptions& options) {
auto* op = static_cast<const SaveLayerOp*>(base_op);
- PaintOpWriter helper(memory, size, options.transfer_cache,
- options.image_provider);
+ PaintOpWriter helper(memory, size, options);
const auto* serialized_flags = options.flags_to_serialize;
if (!serialized_flags)
serialized_flags = &op->flags;
@@ -654,7 +686,7 @@ PaintOp* AnnotateOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(AnnotateOp));
AnnotateOp* op = new (output) AnnotateOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->annotation_type);
helper.Read(&op->rect);
helper.Read(&op->data);
@@ -675,7 +707,7 @@ PaintOp* ClipPathOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(ClipPathOp));
ClipPathOp* op = new (output) ClipPathOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->path);
helper.Read(&op->op);
helper.Read(&op->antialias);
@@ -746,7 +778,7 @@ PaintOp* DrawDRRectOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawDRRectOp));
DrawDRRectOp* op = new (output) DrawDRRectOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->outer);
helper.Read(&op->inner);
@@ -766,10 +798,14 @@ PaintOp* DrawImageOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawImageOp));
DrawImageOp* op = new (output) DrawImageOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
+
helper.Read(&op->image);
helper.AlignMemory(alignof(SkScalar));
+ helper.Read(&op->scale_adjustment.fWidth);
+ helper.Read(&op->scale_adjustment.fHeight);
+
helper.Read(&op->left);
helper.Read(&op->top);
if (!helper.valid() || !op->IsValid()) {
@@ -788,9 +824,14 @@ PaintOp* DrawImageRectOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawImageRectOp));
DrawImageRectOp* op = new (output) DrawImageRectOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
+
helper.Read(&op->image);
+ helper.AlignMemory(alignof(SkScalar));
+ helper.Read(&op->scale_adjustment.fWidth);
+ helper.Read(&op->scale_adjustment.fHeight);
+
helper.Read(&op->src);
helper.Read(&op->dst);
helper.Read(&op->constraint);
@@ -810,7 +851,7 @@ PaintOp* DrawIRectOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawIRectOp));
DrawIRectOp* op = new (output) DrawIRectOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->rect);
if (!helper.valid() || !op->IsValid()) {
@@ -829,7 +870,7 @@ PaintOp* DrawLineOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawLineOp));
DrawLineOp* op = new (output) DrawLineOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.AlignMemory(alignof(SkScalar));
helper.Read(&op->x0);
@@ -852,7 +893,7 @@ PaintOp* DrawOvalOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawOvalOp));
DrawOvalOp* op = new (output) DrawOvalOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->oval);
if (!helper.valid() || !op->IsValid()) {
@@ -871,7 +912,7 @@ PaintOp* DrawPathOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawPathOp));
DrawPathOp* op = new (output) DrawPathOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->path);
if (!helper.valid() || !op->IsValid()) {
@@ -900,7 +941,7 @@ PaintOp* DrawRectOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawRectOp));
DrawRectOp* op = new (output) DrawRectOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->rect);
if (!helper.valid() || !op->IsValid()) {
@@ -919,7 +960,7 @@ PaintOp* DrawRRectOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawRRectOp));
DrawRRectOp* op = new (output) DrawRRectOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->rrect);
if (!helper.valid() || !op->IsValid()) {
@@ -938,7 +979,7 @@ PaintOp* DrawTextBlobOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(DrawTextBlobOp));
DrawTextBlobOp* op = new (output) DrawTextBlobOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.AlignMemory(alignof(SkScalar));
helper.Read(&op->x);
@@ -996,7 +1037,7 @@ PaintOp* SaveLayerOp::Deserialize(const volatile void* input,
DCHECK_GE(output_size, sizeof(SaveLayerOp));
SaveLayerOp* op = new (output) SaveLayerOp;
- PaintOpReader helper(input, input_size, options.transfer_cache);
+ PaintOpReader helper(input, input_size, options);
helper.Read(&op->flags);
helper.Read(&op->bounds);
if (!helper.valid() || !op->IsValid()) {
@@ -1119,6 +1160,12 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op,
SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
if (!params.image_provider) {
+ const bool needs_scale = !IsScaleAdjustmentIdentity(op->scale_adjustment);
+ SkAutoCanvasRestore save_restore(canvas, needs_scale);
+ if (needs_scale) {
+ canvas->scale(1.f / op->scale_adjustment.width(),
+ 1.f / op->scale_adjustment.height());
+ }
canvas->drawImage(op->image.GetSkImage().get(), op->left, op->top, &paint);
return;
}
@@ -1137,17 +1184,18 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op,
DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().width()));
DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().height()));
- bool need_scale = !decoded_image.is_scale_adjustment_identity();
- if (need_scale) {
- canvas->save();
- canvas->scale(1.f / (decoded_image.scale_adjustment().width()),
- 1.f / (decoded_image.scale_adjustment().height()));
- }
-
- paint.setFilterQuality(decoded_image.filter_quality());
- canvas->drawImage(decoded_image.image().get(), op->left, op->top, &paint);
- if (need_scale)
- canvas->restore();
+ SkSize scale_adjustment = SkSize::Make(
+ op->scale_adjustment.width() * decoded_image.scale_adjustment().width(),
+ op->scale_adjustment.height() *
+ decoded_image.scale_adjustment().height());
+ const bool needs_scale = !IsScaleAdjustmentIdentity(scale_adjustment);
+ SkAutoCanvasRestore save_restore(canvas, needs_scale);
+ if (needs_scale) {
+ canvas->scale(1.f / scale_adjustment.width(),
+ 1.f / scale_adjustment.height());
+ }
+ paint.setFilterQuality(decoded_image.filter_quality());
+ canvas->drawImage(decoded_image.image().get(), op->left, op->top, &paint);
}
void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
@@ -1160,7 +1208,8 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
if (!params.image_provider) {
- canvas->drawImageRect(op->image.GetSkImage().get(), op->src, op->dst,
+ SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment);
+ canvas->drawImageRect(op->image.GetSkImage().get(), adjusted_src, op->dst,
&paint, skconstraint);
return;
}
@@ -1183,20 +1232,17 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
const auto& decoded_image = scoped_decoded_draw_image.decoded_image();
DCHECK(decoded_image.image());
+ SkSize scale_adjustment = SkSize::Make(
+ op->scale_adjustment.width() * decoded_image.scale_adjustment().width(),
+ op->scale_adjustment.height() *
+ decoded_image.scale_adjustment().height());
SkRect adjusted_src =
op->src.makeOffset(decoded_image.src_rect_offset().width(),
decoded_image.src_rect_offset().height());
- if (!decoded_image.is_scale_adjustment_identity()) {
- float x_scale = decoded_image.scale_adjustment().width();
- float y_scale = decoded_image.scale_adjustment().height();
- adjusted_src = SkRect::MakeXYWH(
- adjusted_src.x() * x_scale, adjusted_src.y() * y_scale,
- adjusted_src.width() * x_scale, adjusted_src.height() * y_scale);
- }
-
- paint.setFilterQuality(decoded_image.filter_quality());
- canvas->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst,
- &paint, skconstraint);
+ adjusted_src = AdjustSrcRectForScale(adjusted_src, scale_adjustment);
+ paint.setFilterQuality(decoded_image.filter_quality());
+ canvas->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst,
+ &paint, skconstraint);
}
void DrawIRectOp::RasterWithFlags(const DrawIRectOp* op,
@@ -1522,6 +1568,9 @@ bool DrawImageOp::AreEqual(const PaintOp* base_left,
return false;
if (!AreEqualEvenIfNaN(left->top, right->top))
return false;
+
+ // scale_adjustment intentionally omitted because it is added during
+ // serialization based on raster scale.
return true;
}
@@ -1538,6 +1587,9 @@ bool DrawImageRectOp::AreEqual(const PaintOp* base_left,
return false;
if (!AreSkRectsEqual(left->dst, right->dst))
return false;
+
+ // scale_adjustment intentionally omitted because it is added during
+ // serialization based on raster scale.
return true;
}
@@ -2278,10 +2330,9 @@ void PaintOpBuffer::Playback(SkCanvas* canvas,
if (op->IsPaintOpWithFlags()) {
const auto* flags_op = static_cast<const PaintOpWithFlags*>(op);
- const bool create_skia_shaders = true;
const ScopedRasterFlags scoped_flags(
&flags_op->flags, new_params.image_provider, canvas->getTotalMatrix(),
- iter.alpha(), create_skia_shaders);
+ iter.alpha());
if (const auto* raster_flags = scoped_flags.flags())
flags_op->RasterWithFlags(canvas, raster_flags, new_params);
} else {
diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h
index 2228e487e9a..f803f0f27bb 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -28,6 +28,11 @@
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkTextBlob.h"
+#include "ui/gfx/color_space.h"
+
+class SkColorSpace;
+class SkStrikeClient;
+class SkStrikeServer;
// PaintOpBuffer is a reimplementation of SkLiteDL.
// See: third_party/skia/src/core/SkLiteDL.h.
@@ -105,8 +110,11 @@ struct CC_PAINT_EXPORT PlaybackParams {
DidDrawOpCallback did_draw_op_callback = DidDrawOpCallback());
~PlaybackParams();
+ PlaybackParams(const PlaybackParams& other);
+ PlaybackParams& operator=(const PlaybackParams& other);
+
ImageProvider* image_provider;
- const SkMatrix original_ctm;
+ SkMatrix original_ctm;
CustomDataRasterCallback custom_callback;
DidDrawOpCallback did_draw_op_callback;
};
@@ -132,26 +140,35 @@ class CC_PAINT_EXPORT PaintOp {
bool operator!=(const PaintOp& other) const { return !(*this == other); }
struct CC_PAINT_EXPORT SerializeOptions {
- SerializeOptions();
SerializeOptions(ImageProvider* image_provider,
TransferCacheSerializeHelper* transfer_cache,
SkCanvas* canvas,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text,
const SkMatrix& original_ctm);
// Required.
+ ImageProvider* image_provider = nullptr;
TransferCacheSerializeHelper* transfer_cache = nullptr;
SkCanvas* canvas = nullptr;
+ SkStrikeServer* strike_server = nullptr;
+ SkColorSpace* color_space = nullptr;
+ bool can_use_lcd_text = false;
// Optional.
- ImageProvider* image_provider = nullptr;
SkMatrix original_ctm = SkMatrix::I();
// The flags to use when serializing this op. This can be used to override
// the flags serialized with the op. Valid only for PaintOpWithFlags.
const PaintFlags* flags_to_serialize = nullptr;
};
- struct DeserializeOptions {
+ struct CC_PAINT_EXPORT DeserializeOptions {
+ DeserializeOptions(TransferCacheDeserializeHelper* transfer_cache,
+ SkStrikeClient* strike_client);
TransferCacheDeserializeHelper* transfer_cache = nullptr;
+ uint32_t raster_color_space_id = gfx::ColorSpace::kInvalidId;
+ SkStrikeClient* strike_client = nullptr;
};
// Indicates how PaintImages are serialized.
@@ -457,7 +474,10 @@ class CC_PAINT_EXPORT DrawImageOp final : public PaintOpWithFlags {
const PaintFlags* flags,
SkCanvas* canvas,
const PlaybackParams& params);
- bool IsValid() const { return flags.IsValid(); }
+ bool IsValid() const {
+ return flags.IsValid() && SkScalarIsFinite(scale_adjustment.width()) &&
+ SkScalarIsFinite(scale_adjustment.height());
+ }
static bool AreEqual(const PaintOp* left, const PaintOp* right);
bool HasDiscardableImages() const;
bool HasNonAAPaint() const { return false; }
@@ -469,6 +489,10 @@ class CC_PAINT_EXPORT DrawImageOp final : public PaintOpWithFlags {
private:
DrawImageOp();
+
+ // Scale that has already been applied to the decoded image during
+ // serialization. Used with OOP raster.
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
};
class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags {
@@ -486,7 +510,9 @@ class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags {
SkCanvas* canvas,
const PlaybackParams& params);
bool IsValid() const {
- return flags.IsValid() && src.isFinite() && dst.isFinite();
+ return flags.IsValid() && src.isFinite() && dst.isFinite() &&
+ SkScalarIsFinite(scale_adjustment.width()) &&
+ SkScalarIsFinite(scale_adjustment.height());
}
static bool AreEqual(const PaintOp* left, const PaintOp* right);
bool HasDiscardableImages() const;
@@ -499,6 +525,10 @@ class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags {
private:
DrawImageRectOp();
+
+ // Scale that has already been applied to the decoded image during
+ // serialization. Used with OOP raster.
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
};
class CC_PAINT_EXPORT DrawIRectOp final : public PaintOpWithFlags {
diff --git a/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc
index d773388df43..553136dd883 100644
--- a/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_eq_fuzzer.cc
@@ -7,7 +7,7 @@
#include "cc/paint/paint_op_buffer.h"
#include "cc/test/paint_op_helper.h"
-#include "cc/test/transfer_cache_test_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
@@ -36,14 +36,8 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
const size_t kMaxSerializedSize = 1000000;
- // TODO(enne): add an image provider here once deserializing supports that.
SkNoDrawCanvas canvas(100, 100);
- cc::TransferCacheTestHelper transfer_cache_helper;
- cc::PaintOp::SerializeOptions serialize_options;
- serialize_options.transfer_cache = &transfer_cache_helper;
- serialize_options.canvas = &canvas;
- cc::PaintOp::DeserializeOptions deserialize_options;
- deserialize_options.transfer_cache = &transfer_cache_helper;
+ cc::TestOptionsProvider test_options_provider;
// Need 4 bytes to be able to read the type/skip.
if (size < 4)
@@ -63,7 +57,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size_t bytes_read1 = 0;
cc::PaintOp* deserialized_op1 = cc::PaintOp::Deserialize(
data, size, deserialized1.get(), sizeof(cc::LargestPaintOp), &bytes_read1,
- deserialize_options);
+ test_options_provider.deserialize_options());
// Failed to deserialize, so abort.
if (!deserialized_op1)
@@ -94,8 +88,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
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, serialize_options);
+ 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(
@@ -104,7 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size_t bytes_read2 = 0;
cc::PaintOp* deserialized_op2 = cc::PaintOp::Deserialize(
data, size, deserialized2.get(), sizeof(cc::LargestPaintOp), &bytes_read2,
- deserialize_options);
+ test_options_provider.deserialize_options());
CHECK(deserialized_op2);
CHECK_EQ(bytes_read1, bytes_read2);
@@ -112,8 +107,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
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, serialize_options);
+ 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)
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index ec34033f9e9..dfbbf34c49e 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -5,18 +5,77 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/command_line.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "components/viz/test/test_context_provider.h"
+#include "gpu/command_buffer/common/buffer.h"
+#include "gpu/command_buffer/service/service_font_manager.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
+struct Environment {
+ Environment() {
+ // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+ // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+ logging::SetMinLogLevel(logging::LOG_FATAL);
+ }
+};
+
+class FontSupport : public gpu::ServiceFontManager::Client {
+ public:
+ FontSupport() = default;
+ ~FontSupport() override = default;
+
+ // gpu::ServiceFontManager::Client implementation.
+ scoped_refptr<gpu::Buffer> GetShmBuffer(uint32_t shm_id) override {
+ auto it = buffers_.find(shm_id);
+ if (it != buffers_.end())
+ return it->second;
+ return CreateBuffer(shm_id);
+ }
+
+ private:
+ scoped_refptr<gpu::Buffer> CreateBuffer(uint32_t shm_id) {
+ std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
+ static const size_t kBufferSize = 2048u;
+ shared_memory->CreateAndMapAnonymous(kBufferSize);
+ auto buffer =
+ gpu::MakeBufferFromSharedMemory(std::move(shared_memory), kBufferSize);
+ buffers_[shm_id] = buffer;
+ return buffer;
+ }
+
+ base::flat_map<uint32_t, scoped_refptr<gpu::Buffer>> buffers_;
+};
+
// Deserialize an arbitrary number of cc::PaintOps and raster them
// using gpu raster into an SkCanvas.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size <= sizeof(size_t))
+ return 0;
+
+ static Environment* env = new Environment();
+ ALLOW_UNUSED_LOCAL(env);
+ base::CommandLine::Init(0, nullptr);
const size_t kMaxSerializedSize = 1000000;
const size_t kRasterDimension = 32;
+ // Partition the data to use some bytes for populating the font cache.
+ size_t bytes_for_fonts = data[0];
+ if (bytes_for_fonts > size)
+ bytes_for_fonts = size / 2;
+
+ FontSupport font_support;
+ gpu::ServiceFontManager font_manager(&font_support);
+ std::vector<SkDiscardableHandleId> locked_handles;
+ if (bytes_for_fonts > 0u) {
+ font_manager.Deserialize(reinterpret_cast<const char*>(data),
+ bytes_for_fonts, &locked_handles);
+ data += bytes_for_fonts;
+ size -= bytes_for_fonts;
+ }
+
SkImageInfo image_info = SkImageInfo::MakeN32(
kRasterDimension, kRasterDimension, kOpaque_SkAlphaType);
scoped_refptr<viz::TestContextProvider> context_provider =
@@ -28,8 +87,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
cc::PlaybackParams params(nullptr, canvas->getTotalMatrix());
cc::TransferCacheTestHelper transfer_cache_helper;
- cc::PaintOp::DeserializeOptions deserialize_options;
- deserialize_options.transfer_cache = &transfer_cache_helper;
+ cc::PaintOp::DeserializeOptions deserialize_options(
+ &transfer_cache_helper, font_manager.strike_client());
// Need 4 bytes to be able to read the type/skip.
while (size >= 4) {
@@ -58,5 +117,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size -= bytes_read;
data += bytes_read;
}
+
+ font_manager.Unlock(locked_handles);
return 0;
}
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.cc b/chromium/cc/paint/paint_op_buffer_serializer.cc
index 4dc024e0fb3..869d7c5403b 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.cc
+++ b/chromium/cc/paint/paint_op_buffer_serializer.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "cc/paint/scoped_raster_flags.h"
+#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "ui/gfx/skia_util.h"
namespace cc {
@@ -24,17 +25,52 @@ class ScopedFlagsOverride {
PaintOp::SerializeOptions* options_;
};
+// Copied from LayerTreeResourceProvider.
+SkSurfaceProps ComputeSurfaceProps(bool can_use_lcd_text) {
+ uint32_t flags = 0;
+ // Use unknown pixel geometry to disable LCD text.
+ SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
+ if (can_use_lcd_text) {
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ surface_props =
+ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
+ }
+ return surface_props;
+}
+
+PlaybackParams MakeParams(const SkCanvas* canvas) {
+ // We don't use an ImageProvider here since the ops are played onto a no-draw
+ // canvas for state tracking and don't need decoded images.
+ return PlaybackParams(nullptr, canvas->getTotalMatrix());
+}
+
+// Use half of the max int as the extent for the SkNoDrawCanvas. The correct
+// clip is applied to the canvas during serialization.
+const int kMaxExtent = std::numeric_limits<int>::max() >> 1;
+
} // namespace
PaintOpBufferSerializer::PaintOpBufferSerializer(
SerializeCallback serialize_cb,
ImageProvider* image_provider,
- TransferCacheSerializeHelper* transfer_cache)
+ TransferCacheSerializeHelper* transfer_cache,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text)
: serialize_cb_(std::move(serialize_cb)),
- canvas_(100, 100),
image_provider_(image_provider),
- transfer_cache_(transfer_cache) {
+ transfer_cache_(transfer_cache),
+ strike_server_(strike_server),
+ color_space_(color_space),
+ can_use_lcd_text_(can_use_lcd_text),
+ text_blob_canvas_(kMaxExtent,
+ kMaxExtent,
+ SkMatrix::I(),
+ ComputeSurfaceProps(can_use_lcd_text),
+ strike_server) {
DCHECK(serialize_cb_);
+ canvas_ = SkCreateColorSpaceXformCanvas(&text_blob_canvas_,
+ sk_ref_sp<SkColorSpace>(color_space));
}
PaintOpBufferSerializer::~PaintOpBufferSerializer() = default;
@@ -42,19 +78,18 @@ PaintOpBufferSerializer::~PaintOpBufferSerializer() = default;
void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
const std::vector<size_t>* offsets,
const Preamble& preamble) {
- canvas_.resetCanvas(preamble.full_raster_rect.width(),
- preamble.full_raster_rect.height());
- DCHECK(canvas_.getTotalMatrix().isIdentity());
+ DCHECK(canvas_->getTotalMatrix().isIdentity());
static const int kInitialSaveCount = 1;
- DCHECK_EQ(kInitialSaveCount, canvas_.getSaveCount());
+ DCHECK_EQ(kInitialSaveCount, canvas_->getSaveCount());
// These SerializeOptions and PlaybackParams use the initial (identity) canvas
// matrix, as they are only used for serializing the preamble and the initial
// save / final restore. SerializeBuffer will create its own SerializeOptions
// and PlaybackParams based on the post-preamble canvas.
- PaintOp::SerializeOptions options(image_provider_, transfer_cache_, &canvas_,
- canvas_.getTotalMatrix());
- PlaybackParams params(image_provider_, canvas_.getTotalMatrix());
+ PaintOp::SerializeOptions options(
+ image_provider_, transfer_cache_, canvas_.get(), strike_server_,
+ color_space_, can_use_lcd_text_, canvas_->getTotalMatrix());
+ PlaybackParams params = MakeParams(canvas_.get());
Save(options, params);
SerializePreamble(preamble, options, params);
@@ -63,27 +98,22 @@ void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
}
void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer) {
- // Use half of the max int as the extent for the SkNoDrawCanvas.
- static const int extent = std::numeric_limits<int>::max() >> 1;
- // Reset the canvas to the maximum extents of our playback rect, ensuring this
- // rect will not reject images.
- canvas_.resetCanvas(extent, extent);
- DCHECK(canvas_.getTotalMatrix().isIdentity());
+ DCHECK(canvas_->getTotalMatrix().isIdentity());
SerializeBuffer(buffer, nullptr);
}
-void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
- const gfx::Rect& playback_rect,
- const gfx::SizeF& post_scale) {
- // Reset the canvas to the maximum extents of our playback rect, ensuring this
- // rect will not reject images.
- canvas_.resetCanvas(playback_rect.width(), playback_rect.height());
- DCHECK(canvas_.getTotalMatrix().isIdentity());
+void PaintOpBufferSerializer::Serialize(
+ const PaintOpBuffer* buffer,
+ const gfx::Rect& playback_rect,
+ const gfx::SizeF& post_scale,
+ const SkMatrix& post_matrix_for_analysis) {
+ DCHECK(canvas_->getTotalMatrix().isIdentity());
- PaintOp::SerializeOptions options(image_provider_, transfer_cache_, &canvas_,
- canvas_.getTotalMatrix());
- PlaybackParams params(image_provider_, canvas_.getTotalMatrix());
+ PaintOp::SerializeOptions options(
+ image_provider_, transfer_cache_, canvas_.get(), strike_server_,
+ color_space_, can_use_lcd_text_, canvas_->getTotalMatrix());
+ PlaybackParams params = MakeParams(canvas_.get());
// TODO(khushalsagar): remove this clip rect if it's not needed.
if (!playback_rect.IsEmpty()) {
@@ -97,6 +127,7 @@ void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
SerializeOp(&scale_op, options, params);
}
+ canvas_->concat(post_matrix_for_analysis);
SerializeBuffer(buffer, nullptr);
}
@@ -199,9 +230,10 @@ void PaintOpBufferSerializer::SerializeBuffer(
const PaintOpBuffer* buffer,
const std::vector<size_t>* offsets) {
DCHECK(buffer);
- PaintOp::SerializeOptions options(image_provider_, transfer_cache_, &canvas_,
- canvas_.getTotalMatrix());
- PlaybackParams params(image_provider_, canvas_.getTotalMatrix());
+ PaintOp::SerializeOptions options(
+ image_provider_, transfer_cache_, canvas_.get(), strike_server_,
+ color_space_, can_use_lcd_text_, canvas_->getTotalMatrix());
+ PlaybackParams params = MakeParams(canvas_.get());
for (PaintOpBuffer::PlaybackFoldingIterator iter(buffer, offsets); iter;
++iter) {
@@ -210,7 +242,7 @@ void PaintOpBufferSerializer::SerializeBuffer(
// Skip ops outside the current clip if they have images. This saves
// performing an unnecessary expensive decode.
const bool skip_op = PaintOp::OpHasDiscardableImages(op) &&
- PaintOp::QuickRejectDraw(op, &canvas_);
+ PaintOp::QuickRejectDraw(op, canvas_.get());
if (skip_op)
continue;
@@ -228,7 +260,7 @@ void PaintOpBufferSerializer::SerializeBuffer(
continue;
}
- int save_count = canvas_.getSaveCount();
+ int save_count = canvas_->getSaveCount();
Save(options, params);
SerializeBuffer(static_cast<const DrawRecordOp*>(op)->record.get(),
nullptr);
@@ -241,13 +273,10 @@ bool PaintOpBufferSerializer::SerializeOpWithFlags(
PaintOp::SerializeOptions* options,
const PlaybackParams& params,
uint8_t alpha) {
- // We don't need the skia backing for decoded shaders during serialization,
- // since those are created on the service side where the record is rasterized.
- const bool create_skia_shaders = false;
-
+ // We use a null |image_provider| here because images are decoded during
+ // serialization.
const ScopedRasterFlags scoped_flags(
- &flags_op->flags, options->image_provider,
- options->canvas->getTotalMatrix(), alpha, create_skia_shaders);
+ &flags_op->flags, nullptr, options->canvas->getTotalMatrix(), alpha);
const PaintFlags* flags_to_serialize = scoped_flags.flags();
if (!flags_to_serialize)
return true;
@@ -272,11 +301,11 @@ bool PaintOpBufferSerializer::SerializeOp(
DCHECK_GE(bytes, 4u);
DCHECK_EQ(bytes % PaintOpBuffer::PaintOpAlign, 0u);
- // Only pass state-changing operations to the canvas.
- if (!op->IsDrawOp()) {
- // Note that we don't need to use overridden flags during raster here since
- // the override must not affect any state being tracked by this canvas.
- op->Raster(&canvas_, params);
+ if (op->IsPaintOpWithFlags() && options.flags_to_serialize) {
+ static_cast<const PaintOpWithFlags*>(op)->RasterWithFlags(
+ canvas_.get(), options.flags_to_serialize, params);
+ } else {
+ op->Raster(canvas_.get(), params);
}
return true;
}
@@ -292,7 +321,7 @@ void PaintOpBufferSerializer::RestoreToCount(
const PaintOp::SerializeOptions& options,
const PlaybackParams& params) {
RestoreOp restore_op;
- while (canvas_.getSaveCount() > count) {
+ while (canvas_->getSaveCount() > count) {
if (!SerializeOp(&restore_op, options, params))
return;
}
@@ -302,12 +331,18 @@ SimpleBufferSerializer::SimpleBufferSerializer(
void* memory,
size_t size,
ImageProvider* image_provider,
- TransferCacheSerializeHelper* transfer_cache)
+ TransferCacheSerializeHelper* transfer_cache,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text)
: PaintOpBufferSerializer(
base::Bind(&SimpleBufferSerializer::SerializeToMemory,
base::Unretained(this)),
image_provider,
- transfer_cache),
+ transfer_cache,
+ strike_server,
+ color_space,
+ can_use_lcd_text),
memory_(memory),
total_(size) {}
diff --git a/chromium/cc/paint/paint_op_buffer_serializer.h b/chromium/cc/paint/paint_op_buffer_serializer.h
index af793efde7c..9f4f21cfa2d 100644
--- a/chromium/cc/paint/paint_op_buffer_serializer.h
+++ b/chromium/cc/paint/paint_op_buffer_serializer.h
@@ -7,7 +7,7 @@
#include "cc/paint/paint_op_buffer.h"
-#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
+#include "third_party/skia/src/core/SkRemoteGlyphCache.h"
#include "ui/gfx/geometry/rect_f.h"
namespace cc {
@@ -20,7 +20,10 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
PaintOpBufferSerializer(SerializeCallback serialize_cb,
ImageProvider* image_provider,
- TransferCacheSerializeHelper* transfer_cache);
+ TransferCacheSerializeHelper* transfer_cache,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text);
virtual ~PaintOpBufferSerializer();
struct Preamble {
@@ -59,9 +62,14 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
// generally be used for internal PaintOpBuffers in PaintShaders that have
// a scale and a tiling, but don't want the clearing or other complicated
// logic of the top level Serialize.
+ // post_matrix_for_analysis adds a scale that is not added to the serialized
+ // buffer, but used in analysis. This is required for cases that don't modify
+ // the record during serialization, but need to send resources based on the
+ // raster scale (mainly PaintRecord backed PaintFilters).
void Serialize(const PaintOpBuffer* buffer,
const gfx::Rect& playback_rect,
- const gfx::SizeF& post_scale);
+ const gfx::SizeF& post_scale,
+ const SkMatrix& post_matrix_for_analysis);
bool valid() const { return valid_; }
@@ -85,9 +93,14 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
const PlaybackParams& params);
SerializeCallback serialize_cb_;
- SkNoDrawCanvas canvas_;
ImageProvider* image_provider_;
TransferCacheSerializeHelper* transfer_cache_;
+ SkStrikeServer* strike_server_;
+ SkColorSpace* color_space_;
+ bool can_use_lcd_text_;
+
+ SkTextBlobCacheDiffCanvas text_blob_canvas_;
+ std::unique_ptr<SkCanvas> canvas_;
bool valid_ = true;
};
@@ -97,7 +110,10 @@ class CC_PAINT_EXPORT SimpleBufferSerializer : public PaintOpBufferSerializer {
SimpleBufferSerializer(void* memory,
size_t size,
ImageProvider* image_provider,
- TransferCacheSerializeHelper* transfer_cache);
+ TransferCacheSerializeHelper* transfer_cache,
+ SkStrikeServer* strike_server,
+ SkColorSpace* color_space,
+ bool can_use_lcd_text);
~SimpleBufferSerializer() override;
size_t written() const { return written_; }
diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc
index 7ab3a8c6ad7..b7b1d1e37fb 100644
--- a/chromium/cc/paint/paint_op_buffer_unittest.cc
+++ b/chromium/cc/paint/paint_op_buffer_unittest.cc
@@ -12,9 +12,11 @@
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/paint_op_reader.h"
#include "cc/paint/paint_op_writer.h"
+#include "cc/paint/shader_transfer_cache_entry.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/paint_op_helper.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_options_provider.h"
#include "cc/test/test_skcanvas.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,6 +25,7 @@
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkLayerDrawLooper.h"
#include "third_party/skia/include/effects/SkOffsetImageFilter.h"
+#include "third_party/skia/src/core/SkRemoteGlyphCache.h"
using testing::_;
using testing::Property;
@@ -73,71 +76,6 @@ class PaintOpSerializationTestUtils {
}
};
-class TestOptionsProvider : public ImageProvider,
- public TransferCacheTestHelper {
- public:
- TestOptionsProvider() {
- serialize_options_.canvas = &canvas_;
- serialize_options_.image_provider = this;
- serialize_options_.transfer_cache = this;
- deserialize_options_.transfer_cache = this;
- }
- ~TestOptionsProvider() override = default;
-
- const PaintOp::SerializeOptions& serialize_options() const {
- return serialize_options_;
- }
- PaintOp::SerializeOptions& mutable_serialize_options() {
- return serialize_options_;
- }
- const PaintOp::DeserializeOptions deserialize_options() const {
- return deserialize_options_;
- }
- PaintOp::DeserializeOptions mutable_deserialize_options() {
- return deserialize_options_;
- }
- ImageProvider* image_provider() { return this; }
- TransferCacheTestHelper* transfer_cache_helper() { return this; }
-
- const std::vector<DrawImage>& decoded_images() const {
- return decoded_images_;
- }
-
- private:
- ScopedDecodedDrawImage GetDecodedDrawImage(
- const DrawImage& draw_image) override {
- decoded_images_.push_back(draw_image);
- auto& entry = entry_map_[++transfer_cache_entry_id_];
- SkBitmap bitmap;
- const auto& paint_image = draw_image.paint_image();
- bitmap.allocPixelsFlags(
- SkImageInfo::MakeN32Premul(paint_image.width(), paint_image.height()),
- SkBitmap::kZeroPixels_AllocFlag);
- sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
- entry.set_image_for_testing(image);
- return ScopedDecodedDrawImage(DecodedDrawImage(
- transfer_cache_entry_id_, SkSize::MakeEmpty(), SkSize::Make(1u, 1u),
- draw_image.filter_quality(), true));
- }
-
- ServiceTransferCacheEntry* GetEntryInternal(TransferCacheEntryType entry_type,
- uint32_t entry_id) override {
- if (entry_type != TransferCacheEntryType::kImage)
- return TransferCacheTestHelper::GetEntryInternal(entry_type, entry_id);
- auto it = entry_map_.find(entry_id);
- CHECK(it != entry_map_.end());
- return &it->second;
- }
-
- uint32_t transfer_cache_entry_id_ = 0u;
- base::flat_map<uint32_t, ServiceImageTransferCacheEntry> entry_map_;
-
- testing::StrictMock<MockCanvas> canvas_;
- PaintOp::SerializeOptions serialize_options_;
- PaintOp::DeserializeOptions deserialize_options_;
- std::vector<DrawImage> decoded_images_;
-};
-
TEST(PaintOpBufferTest, Empty) {
PaintOpBuffer buffer;
EXPECT_EQ(buffer.size(), 0u);
@@ -1196,12 +1134,9 @@ std::vector<PaintFlags> test_flags = {
};
std::vector<SkColor> test_colors = {
- SkColorSetARGBInline(0, 0, 0, 0),
- SkColorSetARGBInline(255, 255, 255, 255),
- SkColorSetARGBInline(0, 255, 10, 255),
- SkColorSetARGBInline(255, 0, 20, 255),
- SkColorSetARGBInline(30, 255, 0, 255),
- SkColorSetARGBInline(255, 40, 0, 0),
+ SkColorSetARGB(0, 0, 0, 0), SkColorSetARGB(255, 255, 255, 255),
+ SkColorSetARGB(0, 255, 10, 255), SkColorSetARGB(255, 0, 20, 255),
+ SkColorSetARGB(30, 255, 0, 255), SkColorSetARGB(255, 40, 0, 0),
};
std::vector<std::string> test_strings = {
@@ -1334,12 +1269,12 @@ class DeserializerIterator {
public:
DeserializerIterator(const void* input,
size_t input_size,
- TransferCacheDeserializeHelper* transfer_cache)
+ const PaintOp::DeserializeOptions& options)
: DeserializerIterator(input,
static_cast<const char*>(input),
input_size,
input_size,
- transfer_cache) {}
+ options) {}
DeserializerIterator(DeserializerIterator&&) = default;
DeserializerIterator& operator=(DeserializerIterator&&) = default;
@@ -1348,13 +1283,12 @@ class DeserializerIterator {
DeserializerIterator begin() {
return DeserializerIterator(input_, static_cast<const char*>(input_),
- input_size_, input_size_,
- options_.transfer_cache);
+ input_size_, input_size_, options_);
}
DeserializerIterator end() {
return DeserializerIterator(input_,
static_cast<const char*>(input_) + input_size_,
- input_size_, 0, options_.transfer_cache);
+ input_size_, 0, options_);
}
bool operator!=(const DeserializerIterator& other) {
return input_ != other.input_ || current_ != other.current_ ||
@@ -1382,12 +1316,12 @@ class DeserializerIterator {
const char* current,
size_t input_size,
size_t remaining,
- TransferCacheDeserializeHelper* transfer_cache)
+ const PaintOp::DeserializeOptions& options)
: input_(input),
current_(current),
input_size_(input_size),
- remaining_(remaining) {
- options_.transfer_cache = transfer_cache;
+ remaining_(remaining),
+ options_(options) {
data_.reset(static_cast<char*>(base::AlignedAlloc(
sizeof(LargestPaintOp), PaintOpBuffer::PaintOpAlign)));
DeserializeCurrentOp();
@@ -1784,9 +1718,12 @@ TEST_P(PaintOpSerializationTest, SmokeTest) {
PaintOpBuffer::Iterator iter(&buffer_);
size_t i = 0;
- for (auto* base_written : DeserializerIterator(
- output_.get(), serializer.TotalBytesWritten(),
- serializer.options_provider()->transfer_cache_helper())) {
+ 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)) {
SCOPED_TRACE(base::StringPrintf(
"%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), i));
ASSERT_EQ(!*iter, !base_written);
@@ -1991,10 +1928,12 @@ TEST(PaintOpSerializationTest, CompleteBufferSerialization) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
serializer.Serialize(&buffer, nullptr, preamble);
ASSERT_NE(serializer.written(), 0u);
@@ -2066,10 +2005,12 @@ TEST(PaintOpSerializationTest, Preamble) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
serializer.Serialize(&buffer, nullptr, preamble);
ASSERT_NE(serializer.written(), 0u);
@@ -2164,10 +2105,12 @@ TEST(PaintOpSerializationTest, SerializesNestedRecords) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
PaintOpBufferSerializer::Preamble preamble;
serializer.Serialize(&buffer, nullptr, preamble);
ASSERT_NE(serializer.written(), 0u);
@@ -2236,10 +2179,12 @@ TEST(PaintOpBufferTest, ClipsImagesDuringSerialization) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
PaintOpBufferSerializer::Preamble preamble;
preamble.playback_rect = test_case.clip_rect;
preamble.full_raster_rect = gfx::Rect(0, 0, test_case.clip_rect.right(),
@@ -2297,10 +2242,12 @@ TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
serializer.Serialize(&buffer, nullptr, preamble);
ASSERT_NE(serializer.written(), 0u);
@@ -2892,6 +2839,68 @@ TEST(PaintOpBufferTest, ReplacesImagesFromProvider) {
buffer.Playback(&canvas, PlaybackParams(&image_provider));
}
+TEST(PaintOpBufferTest, ReplacesImagesFromProviderOOP) {
+ PaintOpBuffer buffer;
+ SkSize expected_scale = SkSize::Make(0.2f, 0.5f);
+
+ SkRect rect = SkRect::MakeWH(10, 10);
+ PaintFlags flags;
+ flags.setFilterQuality(kLow_SkFilterQuality);
+ PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
+ buffer.push<ScaleOp>(expected_scale.width(), expected_scale.height());
+ buffer.push<DrawImageOp>(paint_image, 0.0f, 0.0f, &flags);
+ buffer.push<DrawImageRectOp>(
+ paint_image, rect, rect, &flags,
+ PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint);
+ flags.setShader(
+ PaintShader::MakeImage(paint_image, SkShader::TileMode::kRepeat_TileMode,
+ SkShader::TileMode::kRepeat_TileMode, nullptr));
+ buffer.push<DrawOvalOp>(SkRect::MakeWH(10, 10), flags);
+
+ std::unique_ptr<char, base::AlignedFreeDeleter> memory(
+ static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
+ PaintOpBuffer::PaintOpAlign)));
+ TestOptionsProvider options_provider;
+ SimpleBufferSerializer serializer(
+ 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());
+ serializer.Serialize(&buffer);
+ ASSERT_NE(serializer.written(), 0u);
+
+ auto deserialized_buffer =
+ PaintOpBuffer::MakeFromMemory(memory.get(), serializer.written(),
+ options_provider.deserialize_options());
+ ASSERT_TRUE(deserialized_buffer);
+
+ for (auto* op : PaintOpBuffer::Iterator(deserialized_buffer.get())) {
+ testing::NiceMock<MockCanvas> canvas;
+ PlaybackParams params(nullptr);
+ testing::Sequence s;
+
+ if (op->GetType() == PaintOpType::DrawImage) {
+ // Save/scale/image/restore from DrawImageop.
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, didConcat(MatchesInvScale(expected_scale)));
+ EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f, _));
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ op->Raster(&canvas, params);
+ } else if (op->GetType() == PaintOpType::DrawImageRect) {
+ EXPECT_CALL(canvas, onDrawImageRect(NonLazyImage(),
+ MatchesRect(rect, expected_scale),
+ SkRect::MakeWH(10, 10), _,
+ SkCanvas::kFast_SrcRectConstraint));
+ op->Raster(&canvas, params);
+ } else if (op->GetType() == PaintOpType::DrawOval) {
+ EXPECT_CALL(canvas, onDrawOval(SkRect::MakeWH(10, 10),
+ MatchesShader(flags, expected_scale)));
+ op->Raster(&canvas, params);
+ }
+ }
+}
+
class PaintFilterSerializationTest : public ::testing::TestWithParam<bool> {};
INSTANTIATE_TEST_CASE_P(PaintFilterSerializationTests,
@@ -2966,15 +2975,22 @@ TEST_P(PaintFilterSerializationTest, Basic) {
buffer_size += PaintOpWriter::HeaderBytes();
memory.resize(buffer_size);
- PaintOpWriter writer(memory.data(), memory.size(),
- options_provider.transfer_cache_helper(),
- options_provider.image_provider(), GetParam());
+ PaintOp::SerializeOptions serialize_options(
+ options_provider.image_provider(),
+ options_provider.transfer_cache_helper(), nullptr,
+ options_provider.strike_server(), options_provider.color_space(),
+ options_provider.can_use_lcd_text(), SkMatrix::I());
+ PaintOpWriter writer(memory.data(), memory.size(), serialize_options,
+ GetParam());
writer.Write(filter.get());
ASSERT_GT(writer.size(), 0u) << PaintFilter::TypeToString(filter->type());
sk_sp<PaintFilter> deserialized_filter;
- PaintOpReader reader(memory.data(), writer.size(),
- options_provider.transfer_cache_helper(), GetParam());
+ PaintOp::DeserializeOptions deserialize_options(
+ options_provider.transfer_cache_helper(),
+ options_provider.strike_client());
+ PaintOpReader reader(memory.data(), writer.size(), deserialize_options,
+ GetParam());
reader.Read(&deserialized_filter);
ASSERT_TRUE(deserialized_filter);
EXPECT_TRUE(*filter == *deserialized_filter);
@@ -2996,10 +3012,12 @@ TEST(PaintOpBufferTest, PaintRecordShaderSerialization) {
PaintOpBuffer buffer;
buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 2, 3, 4), flags);
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
serializer.Serialize(&buffer);
ASSERT_TRUE(serializer.valid());
ASSERT_GT(serializer.written(), 0u);
@@ -3080,12 +3098,21 @@ TEST(PaintOpBufferTest, SecurityConstrainedImageSerialization) {
std::unique_ptr<char, base::AlignedFreeDeleter> memory(
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
- PaintOpWriter writer(memory.get(), PaintOpBuffer::kInitialBufferSize, nullptr,
- nullptr, enable_security_constraints);
+ TestOptionsProvider options_provider;
+ PaintOp::SerializeOptions serialize_options(
+ options_provider.image_provider(),
+ options_provider.transfer_cache_helper(), nullptr,
+ options_provider.strike_server(), options_provider.color_space(),
+ options_provider.can_use_lcd_text(), SkMatrix::I());
+ PaintOpWriter writer(memory.get(), PaintOpBuffer::kInitialBufferSize,
+ serialize_options, enable_security_constraints);
writer.Write(filter.get());
sk_sp<PaintFilter> out_filter;
- PaintOpReader reader(memory.get(), writer.size(), nullptr,
+ PaintOp::DeserializeOptions deserialize_options(
+ options_provider.transfer_cache_helper(),
+ options_provider.strike_client());
+ PaintOpReader reader(memory.get(), writer.size(), deserialize_options,
enable_security_constraints);
reader.Read(&out_filter);
EXPECT_TRUE(*filter == *out_filter);
@@ -3111,10 +3138,12 @@ TEST(PaintOpBufferTest, RecordShadersSerializeScaledImages) {
static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
PaintOpBuffer::PaintOpAlign)));
TestOptionsProvider options_provider;
- SimpleBufferSerializer serializer(memory.get(),
- PaintOpBuffer::kInitialBufferSize,
- options_provider.image_provider(),
- options_provider.transfer_cache_helper());
+ SimpleBufferSerializer serializer(
+ 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());
serializer.Serialize(buffer.get());
ASSERT_EQ(options_provider.decoded_images().size(), 1u);
@@ -3123,6 +3152,176 @@ TEST(PaintOpBufferTest, RecordShadersSerializeScaledImages) {
EXPECT_EQ(scale.height(), 0.8f);
}
+TEST(PaintOpBufferTest, RecordShadersCached) {
+ auto record_buffer = sk_make_sp<PaintOpBuffer>();
+ record_buffer->push<DrawImageOp>(
+ CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f, 0.f, nullptr);
+ auto shader = PaintShader::MakePaintRecord(
+ record_buffer, SkRect::MakeWH(10.f, 10.f),
+ SkShader::TileMode::kRepeat_TileMode,
+ SkShader::TileMode::kRepeat_TileMode, nullptr);
+ shader->set_has_animated_images(false);
+ auto shader_id = shader->paint_record_shader_id();
+ TestOptionsProvider options_provider;
+ auto* transfer_cache = options_provider.transfer_cache_helper();
+
+ // Generate serialized |memory|.
+ std::unique_ptr<char, base::AlignedFreeDeleter> memory(
+ static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
+ PaintOpBuffer::PaintOpAlign)));
+ size_t memory_written = 0;
+ {
+ auto buffer = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setShader(shader);
+ buffer->push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags);
+
+ 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());
+ serializer.Serialize(buffer.get());
+ memory_written = serializer.written();
+ }
+
+ // Generate serialized |memory_scaled|, which is the same pob, but with
+ // a scale factor.
+ std::unique_ptr<char, base::AlignedFreeDeleter> memory_scaled(
+ static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
+ PaintOpBuffer::PaintOpAlign)));
+ size_t memory_scaled_written = 0;
+ {
+ auto buffer = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setShader(shader);
+ // This buffer has an additional scale op.
+ buffer->push<ScaleOp>(2.0f, 3.7f);
+ buffer->push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags);
+
+ 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());
+ serializer.Serialize(buffer.get());
+ memory_scaled_written = serializer.written();
+ }
+
+ // Hold onto records so PaintShader pointer comparisons are valid.
+ sk_sp<PaintRecord> records[5];
+ const SkShader* last_shader = nullptr;
+ PaintOp::DeserializeOptions deserialize_options(
+ transfer_cache, options_provider.strike_client());
+
+ // Several deserialization test cases:
+ // (0) deserialize once, verify cached is the same as deserialized version
+ // (1) deserialize again, verify shader gets reused
+ // (2) change color space, verify shader is new
+ // (3) change scale, verify shader is new
+ // (4) sanity check, same new scale + same new colorspace, shader is reused.
+ for (size_t i = 0; i < 5; ++i) {
+ if (i < 2) {
+ // arbitrary color space ids
+ deserialize_options.raster_color_space_id = 23;
+ } else {
+ deserialize_options.raster_color_space_id = 34;
+ }
+
+ if (i < 3) {
+ records[i] = PaintOpBuffer::MakeFromMemory(memory.get(), memory_written,
+ deserialize_options);
+ } else {
+ records[i] = PaintOpBuffer::MakeFromMemory(
+ memory_scaled.get(), memory_scaled_written, deserialize_options);
+ }
+
+ auto* entry =
+ transfer_cache->GetEntryAs<ServiceShaderTransferCacheEntry>(shader_id);
+ ASSERT_TRUE(entry);
+ EXPECT_EQ(entry->raster_color_space_id(),
+ deserialize_options.raster_color_space_id);
+ if (i < 3)
+ EXPECT_EQ(records[i]->size(), 1u);
+ else
+ EXPECT_EQ(records[i]->size(), 2u);
+
+ for (auto* base_op : PaintOpBuffer::Iterator(records[i].get())) {
+ if (base_op->GetType() != PaintOpType::DrawRect)
+ continue;
+ auto* op = static_cast<const DrawRectOp*>(base_op);
+
+ // In every case, the shader in the op should get cached for future
+ // use.
+ auto* op_skshader = op->flags.getShader()->GetSkShader().get();
+ EXPECT_EQ(op_skshader, entry->shader()->GetSkShader().get());
+ switch (i) {
+ case 0:
+ // Nothing to check.
+ break;
+ case 1:
+ EXPECT_EQ(op_skshader, last_shader);
+ break;
+ case 2:
+ EXPECT_NE(op_skshader, last_shader);
+ break;
+ case 3:
+ EXPECT_NE(op_skshader, last_shader);
+ break;
+ case 4:
+ EXPECT_EQ(op_skshader, last_shader);
+ break;
+ }
+ last_shader = op_skshader;
+ }
+ }
+}
+
+TEST(PaintOpBufferTest, RecordShadersCachedSize) {
+ auto record_buffer = sk_make_sp<PaintOpBuffer>();
+ size_t estimated_image_size = 30 * 30 * 4;
+ auto image = CreateBitmapImage(gfx::Size(30, 30));
+ record_buffer->push<DrawImageOp>(image, 0.f, 0.f, nullptr);
+ auto shader = PaintShader::MakePaintRecord(
+ record_buffer, SkRect::MakeWH(10.f, 10.f),
+ SkShader::TileMode::kRepeat_TileMode,
+ SkShader::TileMode::kRepeat_TileMode, nullptr);
+ shader->set_has_animated_images(false);
+ auto shader_id = shader->paint_record_shader_id();
+ TestOptionsProvider options_provider;
+ auto* transfer_cache = options_provider.transfer_cache_helper();
+
+ // Generate serialized |memory|.
+ std::unique_ptr<char, base::AlignedFreeDeleter> memory(
+ static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
+ PaintOpBuffer::PaintOpAlign)));
+ auto buffer = sk_make_sp<PaintOpBuffer>();
+ PaintFlags flags;
+ flags.setShader(shader);
+ buffer->push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags);
+
+ 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());
+ serializer.Serialize(buffer.get());
+
+ PaintOp::DeserializeOptions deserialize_options(
+ transfer_cache, options_provider.strike_client());
+ auto record = PaintOpBuffer::MakeFromMemory(
+ memory.get(), serializer.written(), deserialize_options);
+ auto* shader_entry =
+ transfer_cache->GetEntryAs<ServiceShaderTransferCacheEntry>(shader_id);
+ ASSERT_TRUE(shader_entry);
+
+ // The size of the shader in the cache should be bigger than both the record
+ // and the image. Exact numbers not used here to not overfit this test.
+ size_t shader_size = shader_entry->CachedSize();
+ EXPECT_GT(estimated_image_size, serializer.written());
+ EXPECT_GT(shader_size, estimated_image_size);
+}
+
TEST(PaintOpBufferTest, TotalOpCount) {
auto record_buffer = sk_make_sp<PaintOpBuffer>();
auto sub_record_buffer = sk_make_sp<PaintOpBuffer>();
diff --git a/chromium/cc/paint/paint_op_perftest.cc b/chromium/cc/paint/paint_op_perftest.cc
index ee9f92f5eb7..dfefd8a8afa 100644
--- a/chromium/cc/paint/paint_op_perftest.cc
+++ b/chromium/cc/paint/paint_op_perftest.cc
@@ -9,7 +9,7 @@
#include "cc/base/lap_timer.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/paint_op_buffer_serializer.h"
-#include "cc/test/transfer_cache_test_helper.h"
+#include "cc/test/test_options_provider.h"
#include "testing/perf/perf_test.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
@@ -40,11 +40,7 @@ class PaintOpPerfTest : public testing::Test {
PaintOpBuffer::PaintOpAlign))) {}
void RunTest(const std::string& name, const PaintOpBuffer& buffer) {
- TransferCacheTestHelper helper;
- PaintOp::SerializeOptions serialize_options;
- serialize_options.transfer_cache = &helper;
- PaintOp::DeserializeOptions deserialize_options;
- deserialize_options.transfer_cache = &helper;
+ TestOptionsProvider test_options_provider;
size_t bytes_written = 0u;
PaintOpBufferSerializer::Preamble preamble;
@@ -53,7 +49,11 @@ class PaintOpPerfTest : public testing::Test {
do {
SimpleBufferSerializer serializer(
serialized_data_.get(), kMaxSerializedBufferBytes,
- serialize_options.image_provider, serialize_options.transfer_cache);
+ test_options_provider.image_provider(),
+ test_options_provider.transfer_cache_helper(),
+ test_options_provider.strike_server(),
+ test_options_provider.color_space(),
+ test_options_provider.can_use_lcd_text());
serializer.Serialize(&buffer, nullptr, preamble);
bytes_written = serializer.written();
timer_.NextLap();
@@ -66,6 +66,7 @@ class PaintOpPerfTest : public testing::Test {
size_t bytes_read = 0;
timer_.Reset();
+ test_options_provider.PushFonts();
do {
size_t remaining_read_bytes = bytes_written;
@@ -74,7 +75,8 @@ class PaintOpPerfTest : public testing::Test {
while (true) {
PaintOp* deserialized_op = PaintOp::Deserialize(
to_read, remaining_read_bytes, deserialized_data_.get(),
- sizeof(LargestPaintOp), &bytes_read, deserialize_options);
+ sizeof(LargestPaintOp), &bytes_read,
+ test_options_provider.deserialize_options());
deserialized_op->DestroyThis();
DCHECK_GE(remaining_read_bytes, bytes_read);
diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc
index 2e7dbe089d9..e9c885c465d 100644
--- a/chromium/cc/paint/paint_op_reader.cc
+++ b/chromium/cc/paint/paint_op_reader.cc
@@ -14,11 +14,14 @@
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/paint_shader.h"
#include "cc/paint/paint_typeface_transfer_cache_entry.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"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkTextBlob.h"
+#include "third_party/skia/src/core/SkRemoteGlyphCache.h"
namespace cc {
namespace {
@@ -29,33 +32,6 @@ const size_t kMaxMergeFilterCount = 10000;
const size_t kMaxKernelSize = 1000;
const size_t kMaxRegionByteSize = 10 * 1024;
-struct TypefacesCatalog {
- TransferCacheDeserializeHelper* transfer_cache;
- bool had_null = false;
-};
-
-sk_sp<SkTypeface> ResolveTypeface(const void* data, size_t length, void* ctx) {
- TypefacesCatalog* catalog = static_cast<TypefacesCatalog*>(ctx);
- if (length != 4) {
- catalog->had_null = true;
- return nullptr;
- }
-
- uint32_t id;
- memcpy(&id, data, length);
- auto* entry = catalog->transfer_cache
- ->GetEntryAs<ServicePaintTypefaceTransferCacheEntry>(id);
- // TODO(vmpstr): The !entry->typeface() check is here because not all
- // typefaces are supported right now. Instead of making the reader invalid
- // during the typeface deserialization, which results in an invalid op,
- // instead just make the textblob be null by setting |had_null| to true.
- if (!entry || !entry->typeface()) {
- catalog->had_null = true;
- return nullptr;
- }
- return entry->typeface().ToSkTypeface();
-}
-
bool IsValidPaintShaderType(PaintShader::Type type) {
return static_cast<uint8_t>(type) <
static_cast<uint8_t>(PaintShader::Type::kShaderCount);
@@ -71,6 +47,24 @@ bool IsValidPaintShaderScalingBehavior(PaintShader::ScalingBehavior behavior) {
behavior == PaintShader::ScalingBehavior::kFixedScale;
}
+struct TypefaceCtx {
+ explicit TypefaceCtx(SkStrikeClient* client) : client(client) {}
+ bool invalid_typeface = false;
+ SkStrikeClient* client = nullptr;
+};
+
+sk_sp<SkTypeface> DeserializeTypeface(const void* data,
+ size_t length,
+ void* ctx) {
+ auto* typeface_ctx = static_cast<TypefaceCtx*>(ctx);
+ auto tf = typeface_ctx->client->deserializeTypeface(data, length);
+ if (tf)
+ return tf;
+
+ typeface_ctx->invalid_typeface = true;
+ return nullptr;
+}
+
} // namespace
// static
@@ -213,21 +207,18 @@ void PaintOpReader::Read(SkRRect* rect) {
}
void PaintOpReader::Read(SkPath* path) {
- AlignMemory(4);
+ uint32_t transfer_cache_entry_id;
+ ReadSimple(&transfer_cache_entry_id);
if (!valid_)
return;
-
- // This is assumed safe from TOCTOU violations as the SkPath deserializing
- // function uses an SkRBuffer which reads each piece of memory once much
- // like PaintOpReader does. Additionally, paths are later validated in
- // PaintOpBuffer.
- size_t read_bytes =
- path->readFromMemory(const_cast<const char*>(memory_), remaining_bytes_);
- if (!read_bytes)
- SetInvalid();
-
- memory_ += read_bytes;
- remaining_bytes_ -= read_bytes;
+ auto* entry =
+ options_.transfer_cache->GetEntryAs<ServicePathTransferCacheEntry>(
+ transfer_cache_entry_id);
+ if (entry) {
+ *path = entry->path();
+ } else {
+ valid_ = false;
+ }
}
void PaintOpReader::Read(PaintFlags* flags) {
@@ -238,10 +229,9 @@ void PaintOpReader::Read(PaintFlags* flags) {
ReadSimple(&flags->blend_mode_);
ReadSimple(&flags->bitfields_uint_);
- // TODO(enne): ReadTypeface, http://crbug.com/737629
-
// Flattenables must be read at 4-byte boundary, which should be the case
// here.
+ AlignMemory(4);
ReadFlattenable(&flags->path_effect_);
AlignMemory(4);
ReadFlattenable(&flags->mask_filter_);
@@ -335,8 +325,9 @@ void PaintOpReader::Read(PaintImage* image) {
if (transfer_cache_entry_id == kInvalidImageTransferCacheEntryId)
return;
- if (auto* entry = transfer_cache_->GetEntryAs<ServiceImageTransferCacheEntry>(
- transfer_cache_entry_id)) {
+ if (auto* entry =
+ options_.transfer_cache->GetEntryAs<ServiceImageTransferCacheEntry>(
+ transfer_cache_entry_id)) {
*image = PaintImageBuilder::WithDefault()
.set_id(PaintImage::GetNextId())
.set_image(entry->image(), PaintImage::kNonLazyStableId)
@@ -399,22 +390,18 @@ void PaintOpReader::Read(scoped_refptr<PaintTextBlob>* paint_blob) {
if (!valid_)
return;
- TypefacesCatalog catalog;
- catalog.transfer_cache = transfer_cache_;
-
+ DCHECK(options_.strike_client);
SkDeserialProcs procs;
- procs.fTypefaceProc = &ResolveTypeface;
- procs.fTypefaceCtx = &catalog;
+ TypefaceCtx typeface_ctx(options_.strike_client);
+ procs.fTypefaceProc = &DeserializeTypeface;
+ procs.fTypefaceCtx = &typeface_ctx;
sk_sp<SkTextBlob> blob = SkTextBlob::Deserialize(
const_cast<const char*>(memory_), data_bytes, procs);
- // TODO(vmpstr): If we couldn't serialize |blob|, we should make |paint_blob|
- // nullptr. However, this causes GL errors right now, because not all
- // typefaces are serialized. Fix this once we serialize everything. For now
- // the behavior is that the |paint_blob| op exists and is valid, but
- // internally it has a nullptr SkTextBlob which skia ignores.
- // See also: TODO in paint_op_buffer_eq_fuzzer.
- if (catalog.had_null)
- blob = nullptr;
+ if (typeface_ctx.invalid_typeface) {
+ SetInvalid();
+ return;
+ }
+
*paint_blob = base::MakeRefCounted<PaintTextBlob>(
std::move(blob), std::vector<PaintTypeface>());
memory_ += data_bytes;
@@ -464,8 +451,18 @@ void PaintOpReader::Read(sk_sp<PaintShader>* shader) {
Read(&ref.image_);
bool has_record = false;
ReadSimple(&has_record);
- if (has_record)
- Read(&ref.record_);
+ uint32_t shader_id = PaintShader::kInvalidRecordShaderId;
+ size_t shader_size = 0;
+ if (has_record) {
+ Read(&shader_id);
+
+ // Track dependent transfer cache entries to make cached shader size
+ // more realistic.
+ size_t pre_size = options_.transfer_cache->GetTotalEntrySizes();
+ size_t record_size = Read(&ref.record_);
+ size_t post_size = options_.transfer_cache->GetTotalEntrySizes();
+ shader_size = post_size - pre_size + record_size;
+ }
decltype(ref.colors_)::size_type colors_size = 0;
ReadSimple(&colors_size);
@@ -503,9 +500,40 @@ void PaintOpReader::Read(sk_sp<PaintShader>* shader) {
SetInvalid();
return;
}
- // TODO(vmpstr): We should have a PaintShader id and cache these shaders
- // instead of creating every time we deserialize.
- (*shader)->CreateSkShader();
+
+ if (shader_id == PaintShader::kInvalidRecordShaderId) {
+ // Paint record shaders must have ids.
+ if (shader_type == PaintShader::Type::kPaintRecord) {
+ SetInvalid();
+ return;
+ }
+ (*shader)->CreateSkShader();
+ return;
+ }
+
+ // Record shaders have shader ids. Attempt to use cached versions of
+ // these so that Skia can cache based on SkPictureShader::fUniqueId.
+ // These shaders are always serialized (and assumed to not be large
+ // records). Handling this edge case in this roundabout way prevents
+ // transfer cache entries from needing to depend on other transfer cache
+ // entries.
+ auto* entry =
+ options_.transfer_cache->GetEntryAs<ServiceShaderTransferCacheEntry>(
+ shader_id);
+ // Only consider entries that use the same scale and color space.
+ // This limits the service side transfer cache to only having one entry
+ // per shader but this will hit the common case of enabling Skia reuse.
+ if (entry && entry->shader()->tile_ == ref.tile_ &&
+ entry->raster_color_space_id() == options_.raster_color_space_id) {
+ DCHECK(!ref.cached_shader_);
+ ref.cached_shader_ = entry->shader()->GetSkShader();
+ } else {
+ ref.CreateSkShader();
+ std::unique_ptr<ServiceShaderTransferCacheEntry> entry(
+ new ServiceShaderTransferCacheEntry(
+ *shader, options_.raster_color_space_id, shader_size));
+ options_.transfer_cache->CreateLocalEntry(shader_id, std::move(entry));
+ }
}
void PaintOpReader::Read(SkMatrix* matrix) {
@@ -1164,7 +1192,7 @@ void PaintOpReader::ReadLightingSpotPaintFilter(
base::OptionalOrNullptr(crop_rect)));
}
-void PaintOpReader::Read(sk_sp<PaintRecord>* record) {
+size_t PaintOpReader::Read(sk_sp<PaintRecord>* record) {
size_t size_bytes = 0;
ReadSimple(&size_bytes);
AlignMemory(PaintOpBuffer::PaintOpAlign);
@@ -1174,27 +1202,25 @@ void PaintOpReader::Read(sk_sp<PaintRecord>* record) {
// enabled.
if (size_bytes != 0) {
SetInvalid();
- return;
+ return 0;
}
*record = sk_make_sp<PaintOpBuffer>();
- return;
+ return 0;
}
if (size_bytes > remaining_bytes_)
SetInvalid();
if (!valid_)
- return;
+ return 0;
- PaintOp::DeserializeOptions options;
- options.transfer_cache = transfer_cache_;
-
- *record = PaintOpBuffer::MakeFromMemory(memory_, size_bytes, options);
+ *record = PaintOpBuffer::MakeFromMemory(memory_, size_bytes, options_);
if (!*record) {
SetInvalid();
- return;
+ return 0;
}
memory_ += size_bytes;
remaining_bytes_ -= size_bytes;
+ return size_bytes;
}
void PaintOpReader::Read(SkRegion* region) {
diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h
index 5fc268af0ec..c8455fe8448 100644
--- a/chromium/cc/paint/paint_op_reader.h
+++ b/chromium/cc/paint/paint_op_reader.h
@@ -18,17 +18,18 @@ class PaintShader;
// PaintOpReader takes garbage |memory| and clobbers it with successive
// read functions.
-class TransferCacheDeserializeHelper;
class CC_PAINT_EXPORT PaintOpReader {
public:
+ // The DeserializeOptions passed to the reader must set all fields if it can
+ // be used to for deserializing images, paint records or text blobs.
PaintOpReader(const volatile void* memory,
size_t size,
- TransferCacheDeserializeHelper* transfer_cache,
+ const PaintOp::DeserializeOptions& options,
bool enable_security_constraints = false)
: memory_(static_cast<const volatile char*>(memory) +
PaintOpWriter::HeaderBytes()),
remaining_bytes_(size - PaintOpWriter::HeaderBytes()),
- transfer_cache_(transfer_cache),
+ options_(options),
enable_security_constraints_(enable_security_constraints) {
if (size < PaintOpWriter::HeaderBytes())
valid_ = false;
@@ -184,13 +185,15 @@ class CC_PAINT_EXPORT PaintOpReader {
sk_sp<PaintFilter>* filter,
const base::Optional<PaintFilter::CropRect>& crop_rect);
- void Read(sk_sp<PaintRecord>* record);
+ // Returns the size of the read record, 0 if error.
+ size_t Read(sk_sp<PaintRecord>* record);
+
void Read(SkRegion* region);
const volatile char* memory_ = nullptr;
size_t remaining_bytes_ = 0u;
bool valid_ = true;
- TransferCacheDeserializeHelper* transfer_cache_;
+ const PaintOp::DeserializeOptions& options_;
// Indicates that the data was serialized with the following constraints:
// 1) PaintRecords and SkDrawLoopers are ignored.
diff --git a/chromium/cc/paint/paint_op_writer.cc b/chromium/cc/paint/paint_op_writer.cc
index 697a9ea4647..00338a6ba2f 100644
--- a/chromium/cc/paint/paint_op_writer.cc
+++ b/chromium/cc/paint/paint_op_writer.cc
@@ -11,9 +11,11 @@
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/paint_shader.h"
#include "cc/paint/paint_typeface_transfer_cache_entry.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"
+#include "third_party/skia/src/core/SkRemoteGlyphCache.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h"
@@ -21,18 +23,16 @@ namespace cc {
namespace {
const size_t kSkiaAlignment = 4u;
-sk_sp<SkData> TypefaceCataloger(SkTypeface* typeface, void* ctx) {
- static_cast<TransferCacheSerializeHelper*>(ctx)->AssertLocked(
- TransferCacheEntryType::kPaintTypeface, typeface->uniqueID());
-
- uint32_t id = typeface->uniqueID();
- return SkData::MakeWithCopy(&id, sizeof(uint32_t));
-}
-
size_t RoundDownToAlignment(size_t bytes, size_t alignment) {
return bytes - (bytes & (alignment - 1));
}
+SkIRect MakeSrcRect(const PaintImage& image) {
+ if (!image)
+ return SkIRect::MakeEmpty();
+ return SkIRect::MakeWH(image.width(), image.height());
+}
+
} // namespace
// static
@@ -77,14 +77,12 @@ size_t PaintOpWriter::GetRecordSize(const PaintRecord* record) {
PaintOpWriter::PaintOpWriter(void* memory,
size_t size,
- TransferCacheSerializeHelper* transfer_cache,
- ImageProvider* image_provider,
+ const PaintOp::SerializeOptions& options,
bool enable_security_constraints)
: memory_(static_cast<char*>(memory) + HeaderBytes()),
size_(size),
remaining_bytes_(size - HeaderBytes()),
- transfer_cache_(transfer_cache),
- image_provider_(image_provider),
+ options_(options),
enable_security_constraints_(enable_security_constraints) {
// Leave space for header of type/skip.
DCHECK_GE(size, HeaderBytes());
@@ -169,16 +167,14 @@ void PaintOpWriter::Write(const SkRRect& rect) {
}
void PaintOpWriter::Write(const SkPath& path) {
- AlignMemory(4);
- size_t bytes = path.writeToMemory(nullptr);
- EnsureBytes(bytes);
- if (!valid_)
- return;
-
- size_t bytes_written = path.writeToMemory(memory_);
- DCHECK_LE(bytes_written, bytes);
- memory_ += bytes;
- remaining_bytes_ -= bytes;
+ 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);
}
void PaintOpWriter::Write(const PaintFlags& flags) {
@@ -189,10 +185,9 @@ void PaintOpWriter::Write(const PaintFlags& flags) {
WriteSimple(flags.blend_mode_);
WriteSimple(flags.bitfields_uint_);
- // TODO(enne): WriteTypeface, http://crbug.com/737629
-
// Flattenables must be written starting at a 4 byte boundary, which should be
// the case here.
+ AlignMemory(4);
WriteFlattenable(flags.path_effect_.get());
AlignMemory(4);
WriteFlattenable(flags.mask_filter_.get());
@@ -206,13 +201,26 @@ void PaintOpWriter::Write(const PaintFlags& flags) {
WriteFlattenable(flags.draw_looper_.get());
Write(flags.image_filter_.get());
- Write(flags.shader_.get());
+ Write(flags.shader_.get(), flags.getFilterQuality());
}
-void PaintOpWriter::Write(const DrawImage& image) {
+void PaintOpWriter::Write(const DrawImage& draw_image,
+ SkSize* scale_adjustment) {
+ // We never ask for subsets during serialization.
+ const PaintImage& paint_image = draw_image.paint_image();
+ DCHECK_EQ(paint_image.width(), draw_image.src_rect().width());
+ DCHECK_EQ(paint_image.height(), draw_image.src_rect().height());
+
+ // Empty image.
+ if (!draw_image.paint_image()) {
+ Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage));
+ return;
+ }
+
+ // Security constrained serialization inlines the image bitmap.
if (enable_security_constraints_) {
SkBitmap bm;
- if (!image.paint_image().GetSkImage()->asLegacyBitmap(&bm)) {
+ if (!draw_image.paint_image().GetSkImage()->asLegacyBitmap(&bm)) {
Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage));
return;
}
@@ -228,17 +236,24 @@ void PaintOpWriter::Write(const DrawImage& image) {
return;
}
- Write(
- static_cast<uint8_t>(PaintOp::SerializedImageType::kTransferCacheEntry));
- auto decoded_image = image_provider_->GetDecodedDrawImage(image);
+ // Default mode uses the transfer cache.
+ auto decoded_image = options_.image_provider->GetDecodedDrawImage(draw_image);
DCHECK(!decoded_image.decoded_image().image())
<< "Use transfer cache for image serialization";
+ const DecodedDrawImage& decoded_draw_image = decoded_image.decoded_image();
+ DCHECK(decoded_draw_image.src_rect_offset().isEmpty())
+ << "We shouldn't ask for image subsets";
- base::Optional<uint32_t> id =
- decoded_image.decoded_image().transfer_cache_entry_id();
-
+ base::Optional<uint32_t> id = decoded_draw_image.transfer_cache_entry_id();
+ *scale_adjustment = decoded_draw_image.scale_adjustment();
// In the case of a decode failure, id may not be set. Send an invalid ID.
- Write(id ? *id : kInvalidImageTransferCacheEntryId);
+ WriteImage(id ? *id : kInvalidImageTransferCacheEntryId);
+}
+
+void PaintOpWriter::WriteImage(uint32_t transfer_cache_entry_id) {
+ Write(
+ static_cast<uint8_t>(PaintOp::SerializedImageType::kTransferCacheEntry));
+ Write(transfer_cache_entry_id);
}
void PaintOpWriter::Write(const sk_sp<SkData>& data) {
@@ -272,9 +287,12 @@ void PaintOpWriter::Write(const SkColorSpace* color_space) {
remaining_bytes_ -= written;
}
-void PaintOpWriter::Write(const sk_sp<SkTextBlob>& blob) {
- DCHECK(blob);
+void PaintOpWriter::Write(const scoped_refptr<PaintTextBlob>& paint_blob) {
+ DCHECK(paint_blob);
+ if (!valid_)
+ return;
+ const auto& blob = paint_blob->ToSkTextBlob();
size_t size_offset = sizeof(size_t);
EnsureBytes(size_offset);
if (!valid_)
@@ -283,9 +301,15 @@ void PaintOpWriter::Write(const sk_sp<SkTextBlob>& blob) {
char* size_memory = memory_;
memory_ += size_offset;
remaining_bytes_ -= size_offset;
+
+ auto encodeTypeface = [](SkTypeface* tf, void* ctx) -> sk_sp<SkData> {
+ return static_cast<SkStrikeServer*>(ctx)->serializeTypeface(tf);
+ };
+ DCHECK(options_.strike_server);
SkSerialProcs procs;
- procs.fTypefaceProc = &TypefaceCataloger;
- procs.fTypefaceCtx = transfer_cache_;
+ procs.fTypefaceProc = encodeTypeface;
+ procs.fTypefaceCtx = options_.strike_server;
+
size_t bytes_written = blob->serialize(
procs, memory_, RoundDownToAlignment(remaining_bytes_, kSkiaAlignment));
if (bytes_written == 0u) {
@@ -297,25 +321,41 @@ void PaintOpWriter::Write(const sk_sp<SkTextBlob>& blob) {
remaining_bytes_ -= bytes_written;
}
-void PaintOpWriter::Write(const scoped_refptr<PaintTextBlob>& blob) {
- if (!valid_)
- return;
+sk_sp<PaintShader> PaintOpWriter::TransformShaderIfNecessary(
+ const PaintShader* original,
+ SkFilterQuality quality,
+ uint32_t* paint_image_transfer_cache_entry_id,
+ gfx::SizeF* paint_record_post_scale) {
+ DCHECK(!enable_security_constraints_);
+
+ const auto type = original->shader_type();
+ const auto& ctm = options_.canvas->getTotalMatrix();
- for (auto& typeface : blob->typefaces()) {
- auto locked = transfer_cache_->LockEntry(
- TransferCacheEntryType::kPaintTypeface, typeface.sk_id());
- if (locked)
- continue;
- transfer_cache_->CreateEntry(
- ClientPaintTypefaceTransferCacheEntry(typeface));
- transfer_cache_->AssertLocked(TransferCacheEntryType::kPaintTypeface,
- typeface.sk_id());
+ if (type == PaintShader::Type::kImage) {
+ return original->CreateDecodedImage(ctm, quality, options_.image_provider,
+ paint_image_transfer_cache_entry_id,
+ &quality);
}
- Write(blob->ToSkTextBlob());
+ if (type == PaintShader::Type::kPaintRecord) {
+ return original->CreateScaledPaintRecord(ctm, paint_record_post_scale);
+ }
+
+ return sk_ref_sp<PaintShader>(original);
}
-void PaintOpWriter::Write(const PaintShader* shader) {
+void PaintOpWriter::Write(const PaintShader* shader, SkFilterQuality quality) {
+ sk_sp<PaintShader> transformed_shader;
+ uint32_t paint_image_transfer_cache_id = kInvalidImageTransferCacheEntryId;
+ gfx::SizeF paint_record_post_scale(1.f, 1.f);
+
+ if (!enable_security_constraints_ && shader) {
+ transformed_shader = TransformShaderIfNecessary(
+ shader, quality, &paint_image_transfer_cache_id,
+ &paint_record_post_scale);
+ shader = transformed_shader.get();
+ }
+
if (!shader) {
WriteSimple(false);
return;
@@ -345,21 +385,31 @@ void PaintOpWriter::Write(const PaintShader* shader) {
WriteSimple(shader->end_point_);
WriteSimple(shader->start_degrees_);
WriteSimple(shader->end_degrees_);
- Write(shader->image_);
+
+ if (enable_security_constraints_) {
+ DrawImage draw_image(shader->image_, MakeSrcRect(shader->image_), quality,
+ SkMatrix::I());
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
+ Write(draw_image, &scale_adjustment);
+ DCHECK_EQ(scale_adjustment.width(), 1.f);
+ DCHECK_EQ(scale_adjustment.height(), 1.f);
+ } else {
+ WriteImage(paint_image_transfer_cache_id);
+ }
+
if (shader->record_) {
Write(true);
- base::Optional<gfx::Rect> playback_rect;
- base::Optional<gfx::SizeF> post_scale;
- if (shader->tile_scale()) {
- playback_rect.emplace(
- gfx::ToEnclosingRect(gfx::SkRectToRectF(shader->tile())));
- post_scale.emplace(*shader->tile_scale());
- }
- Write(shader->record_.get(), std::move(playback_rect),
- std::move(post_scale));
+ DCHECK_NE(shader->id_, PaintShader::kInvalidRecordShaderId);
+ Write(shader->id_);
+ const gfx::Rect playback_rect(
+ gfx::ToEnclosingRect(gfx::SkRectToRectF(shader->tile())));
+ Write(shader->record_.get(), playback_rect, paint_record_post_scale,
+ SkMatrix::I());
} else {
+ DCHECK_EQ(shader->id_, PaintShader::kInvalidRecordShaderId);
Write(false);
}
+
WriteSimple(shader->colors_.size());
WriteData(shader->colors_.size() * sizeof(SkColor), shader->colors_.data());
@@ -583,7 +633,11 @@ void PaintOpWriter::Write(const ImagePaintFilter& filter) {
filter.image(),
SkIRect::MakeWH(filter.image().width(), filter.image().height()),
filter.filter_quality(), SkMatrix::I());
- Write(draw_image);
+ SkSize scale_adjustment = SkSize::Make(1.f, 1.f);
+ Write(draw_image, &scale_adjustment);
+ DCHECK_EQ(scale_adjustment.width(), 1.f);
+ DCHECK_EQ(scale_adjustment.height(), 1.f);
+
Write(filter.src_rect());
Write(filter.dst_rect());
Write(filter.filter_quality());
@@ -591,7 +645,8 @@ void PaintOpWriter::Write(const ImagePaintFilter& filter) {
void PaintOpWriter::Write(const RecordPaintFilter& filter) {
WriteSimple(filter.record_bounds());
- Write(filter.record().get());
+ Write(filter.record().get(), gfx::Rect(), gfx::SizeF(1.f, 1.f),
+ options_.canvas ? options_.canvas->getTotalMatrix() : SkMatrix::I());
}
void PaintOpWriter::Write(const MergePaintFilter& filter) {
@@ -672,9 +727,9 @@ void PaintOpWriter::Write(const LightingSpotPaintFilter& filter) {
}
void PaintOpWriter::Write(const PaintRecord* record,
- base::Optional<gfx::Rect> playback_rect,
- base::Optional<gfx::SizeF> post_scale) {
- DCHECK_EQ(playback_rect.has_value(), post_scale.has_value());
+ const gfx::Rect& playback_rect,
+ const gfx::SizeF& post_scale,
+ const SkMatrix& post_matrix_for_analysis) {
// We need to record how many bytes we will serialize, but we don't know this
// information until we do the serialization. So, skip the amount needed
// before writing.
@@ -697,13 +752,12 @@ void PaintOpWriter::Write(const PaintRecord* record,
return;
}
- SimpleBufferSerializer serializer(memory_, remaining_bytes_, image_provider_,
- transfer_cache_);
- if (playback_rect) {
- serializer.Serialize(record, *playback_rect, *post_scale);
- } else {
- serializer.Serialize(record);
- }
+ SimpleBufferSerializer serializer(
+ memory_, remaining_bytes_, options_.image_provider,
+ options_.transfer_cache, options_.strike_server, options_.color_space,
+ options_.can_use_lcd_text);
+ serializer.Serialize(record, playback_rect, post_scale,
+ post_matrix_for_analysis);
if (!serializer.valid()) {
valid_ = false;
@@ -725,20 +779,6 @@ void PaintOpWriter::Write(const PaintRecord* record,
remaining_bytes_ -= serializer.written();
}
-void PaintOpWriter::Write(const PaintImage& image) {
- if (!image) {
- Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage));
- return;
- }
- // Note that the filter quality doesn't matter here, since it's not
- // serialized. It's only used to determine the decoded draw image that we will
- // get. However, since we're requesting a full-sized image decode, the filter
- // quality is essentially ignored.
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, SkMatrix::I());
- Write(draw_image);
-}
-
void PaintOpWriter::Write(const SkRegion& region) {
size_t bytes_required = region.writeToMemory(nullptr);
std::unique_ptr<char[]> data(new char[bytes_required]);
diff --git a/chromium/cc/paint/paint_op_writer.h b/chromium/cc/paint/paint_op_writer.h
index 685ff92c857..ecca69ced59 100644
--- a/chromium/cc/paint/paint_op_writer.h
+++ b/chromium/cc/paint/paint_op_writer.h
@@ -19,16 +19,15 @@ class SkRRect;
namespace cc {
class DrawImage;
-class ImageProvider;
class PaintShader;
-class TransferCacheSerializeHelper;
class CC_PAINT_EXPORT PaintOpWriter {
public:
+ // The SerializeOptions passed to the writer must set the required fields
+ // if it can be used for serializing images, paint records or text blobs.
PaintOpWriter(void* memory,
size_t size,
- TransferCacheSerializeHelper* transfer_cache,
- ImageProvider* image_provider,
+ const PaintOp::SerializeOptions& options,
bool enable_security_constraints = false);
~PaintOpWriter();
@@ -58,10 +57,9 @@ class CC_PAINT_EXPORT PaintOpWriter {
void Write(const SkPath& path);
void Write(const PaintFlags& flags);
- void Write(const DrawImage& image);
void Write(const sk_sp<SkData>& data);
void Write(const SkColorSpace* data);
- void Write(const PaintShader* shader);
+ void Write(const PaintShader* shader, SkFilterQuality quality);
void Write(const PaintFilter* filter);
void Write(const scoped_refptr<PaintTextBlob>& blob);
void Write(SkColorType color_type);
@@ -92,13 +90,23 @@ class CC_PAINT_EXPORT PaintOpWriter {
static_assert(sizeof(T) == 0,
"Attempted to call a non-existent sk_sp override.");
}
+ template <typename T>
+ void Write(const T*) {
+ static_assert(sizeof(T) == 0,
+ "Attempted to call a non-existent T* override.");
+ }
+
+ // Serializes the given |draw_image|.
+ // |scale_adjustment| is set to the scale applied to the serialized image.
+ // |quality| is set to the quality that should be used when rasterizing this
+ // image.
+ void Write(const DrawImage& draw_image, SkSize* scale_adjustment);
private:
template <typename T>
void WriteSimple(const T& val);
void WriteFlattenable(const SkFlattenable* val);
- void Write(const sk_sp<SkTextBlob>& blob);
// The main entry point is Write(const PaintFilter* filter) which casts the
// filter and calls one of the following functions.
@@ -126,18 +134,23 @@ class CC_PAINT_EXPORT PaintOpWriter {
void Write(const LightingSpotPaintFilter& filter);
void Write(const PaintRecord* record,
- base::Optional<gfx::Rect> playback_rect = base::nullopt,
- base::Optional<gfx::SizeF> post_scale = base::nullopt);
- void Write(const PaintImage& image);
+ const gfx::Rect& playback_rect,
+ const gfx::SizeF& post_scale,
+ const SkMatrix& post_matrix_for_analysis);
void Write(const SkRegion& region);
+ void WriteImage(uint32_t transfer_cache_entry_id);
void EnsureBytes(size_t required_bytes);
+ sk_sp<PaintShader> TransformShaderIfNecessary(
+ const PaintShader* original,
+ SkFilterQuality quality,
+ uint32_t* paint_image_transfer_cache_entry_id,
+ gfx::SizeF* paint_record_post_scale);
char* memory_ = nullptr;
size_t size_ = 0u;
size_t remaining_bytes_ = 0u;
- TransferCacheSerializeHelper* transfer_cache_;
- ImageProvider* image_provider_;
+ const PaintOp::SerializeOptions& options_;
bool valid_ = true;
// Indicates that the following security constraints must be applied during
diff --git a/chromium/cc/paint/paint_shader.cc b/chromium/cc/paint/paint_shader.cc
index 6baee9fe6d3..f06e539ddd9 100644
--- a/chromium/cc/paint/paint_shader.cc
+++ b/chromium/cc/paint/paint_shader.cc
@@ -4,6 +4,8 @@
#include "cc/paint/paint_shader.h"
+#include "base/atomic_sequence_num.h"
+#include "cc/paint/paint_image_builder.h"
#include "cc/paint/paint_op_writer.h"
#include "cc/paint/paint_record.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
@@ -11,6 +13,7 @@
namespace cc {
namespace {
+base::AtomicSequenceNumber g_next_shader_id;
sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record,
const SkRect& bounds,
@@ -24,8 +27,27 @@ sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record,
return recorder.finishRecordingAsPicture();
}
+bool CompareMatrices(const SkMatrix& a,
+ const SkMatrix& b,
+ bool ignore_scaling_differences) {
+ if (!ignore_scaling_differences)
+ return PaintOp::AreSkMatricesEqual(a, b);
+
+ SkSize scale;
+ SkMatrix a_without_scale;
+ SkMatrix b_without_scale;
+ if (a.decomposeScale(&scale, &a_without_scale) !=
+ b.decomposeScale(&scale, &b_without_scale)) {
+ return false;
+ }
+
+ return PaintOp::AreSkMatricesEqual(a_without_scale, b_without_scale);
+}
+
} // namespace
+const PaintShader::RecordShaderId PaintShader::kInvalidRecordShaderId = -1;
+
sk_sp<PaintShader> PaintShader::MakeColor(SkColor color) {
sk_sp<PaintShader> shader(new PaintShader(Type::kColor));
@@ -151,6 +173,7 @@ sk_sp<PaintShader> PaintShader::MakePaintRecord(
sk_sp<PaintShader> shader(new PaintShader(Type::kPaintRecord));
shader->record_ = std::move(record);
+ shader->id_ = g_next_shader_id.GetNext();
shader->tile_ = tile;
shader->scaling_behavior_ = scaling_behavior;
shader->SetMatrixAndTiling(local_matrix, tx, ty);
@@ -175,6 +198,7 @@ size_t PaintShader::GetSerializedSize(const PaintShader* shader) {
sizeof(shader->end_degrees_) +
PaintOpWriter::GetImageSize(shader->image_) +
PaintOpWriter::GetImageSize(shader->image_) + bool_size +
+ sizeof(shader->id_) +
PaintOpWriter::GetRecordSize(shader->record_.get()) +
sizeof(shader->colors_.size()) +
shader->colors_.size() * sizeof(SkColor) +
@@ -235,9 +259,9 @@ bool PaintShader::GetRasterizationTileRect(const SkMatrix& ctm,
return true;
}
-sk_sp<PaintShader> PaintShader::CreateDecodedPaintRecord(
+sk_sp<PaintShader> PaintShader::CreateScaledPaintRecord(
const SkMatrix& ctm,
- ImageProvider* image_provider) const {
+ gfx::SizeF* raster_scale) const {
DCHECK_EQ(shader_type_, Type::kPaintRecord);
// For creating a decoded PaintRecord shader, we need to do the following:
@@ -258,6 +282,7 @@ sk_sp<PaintShader> PaintShader::CreateDecodedPaintRecord(
sk_sp<PaintShader> shader(new PaintShader(Type::kPaintRecord));
shader->record_ = record_;
+ shader->id_ = id_;
shader->tile_ = tile_rect;
// Use a fixed scale since we have already scaled the tile rect and fixed the
// raster scale.
@@ -265,21 +290,73 @@ sk_sp<PaintShader> PaintShader::CreateDecodedPaintRecord(
shader->tx_ = tx_;
shader->ty_ = ty_;
- shader->tile_scale_ =
+ *raster_scale =
gfx::SizeF(SkIntToScalar(tile_rect.width()) / tile_.width(),
SkIntToScalar(tile_rect.height()) / tile_.height());
shader->local_matrix_ = GetLocalMatrix();
- shader->local_matrix_->preScale(1 / shader->tile_scale_->width(),
- 1 / shader->tile_scale_->height());
+ shader->local_matrix_->preScale(1 / raster_scale->width(),
+ 1 / raster_scale->height());
return shader;
}
+sk_sp<PaintShader> PaintShader::CreateDecodedImage(
+ const SkMatrix& ctm,
+ SkFilterQuality quality,
+ ImageProvider* image_provider,
+ uint32_t* transfer_cache_entry_id,
+ SkFilterQuality* raster_quality) const {
+ DCHECK_EQ(shader_type_, Type::kImage);
+ if (!image_)
+ return nullptr;
+
+ SkMatrix total_image_matrix = GetLocalMatrix();
+ total_image_matrix.preConcat(ctm);
+ SkRect src_rect = SkRect::MakeIWH(image_.width(), image_.height());
+ SkIRect int_src_rect;
+ src_rect.roundOut(&int_src_rect);
+ DrawImage draw_image(image_, int_src_rect, quality, total_image_matrix);
+ auto decoded_draw_image = image_provider->GetDecodedDrawImage(draw_image);
+ if (!decoded_draw_image)
+ return nullptr;
+
+ auto decoded_image = decoded_draw_image.decoded_image();
+ SkMatrix final_matrix = GetLocalMatrix();
+ bool need_scale = !decoded_image.is_scale_adjustment_identity();
+ if (need_scale) {
+ final_matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
+ 1.f / decoded_image.scale_adjustment().height());
+ }
+
+ PaintImage decoded_paint_image;
+ if (decoded_image.transfer_cache_entry_id()) {
+ decoded_paint_image = image_;
+ *transfer_cache_entry_id = *decoded_image.transfer_cache_entry_id();
+ } else {
+ DCHECK(decoded_image.image());
+
+ sk_sp<SkImage> sk_image =
+ sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
+ decoded_paint_image =
+ PaintImageBuilder::WithDefault()
+ .set_id(image_.stable_id())
+ .set_image(std::move(sk_image), image_.content_id())
+ .TakePaintImage();
+ }
+
+ // TODO(khushalsagar): Remove filter quality from DecodedDrawImage. All we
+ // want to do is cap the filter quality used, but Gpu and Sw cache have
+ // different behaviour. D:
+ *raster_quality = decoded_image.filter_quality();
+ return PaintShader::MakeImage(decoded_paint_image, tx_, ty_, &final_matrix);
+}
+
sk_sp<SkShader> PaintShader::GetSkShader() const {
return cached_shader_;
}
-void PaintShader::CreateSkShader(ImageProvider* image_provider) {
+void PaintShader::CreateSkShader(const gfx::SizeF* raster_scale,
+ ImageProvider* image_provider) {
DCHECK(!cached_shader_);
switch (shader_type_) {
@@ -325,7 +402,7 @@ void PaintShader::CreateSkShader(ImageProvider* image_provider) {
case Type::kPaintRecord: {
// Create a recording at the desired scale if this record has images which
// have been decoded before raster.
- auto picture = ToSkPicture(record_, tile_, tile_scale(), image_provider);
+ auto picture = ToSkPicture(record_, tile_, raster_scale, image_provider);
switch (scaling_behavior_) {
// For raster scale, we create a picture shader directly.
@@ -426,16 +503,20 @@ bool PaintShader::operator==(const PaintShader& other) const {
if (shader_type_ != other.shader_type_)
return false;
+ // Record and image shaders are scaled during serialization.
+ const bool ignore_scaling_differences =
+ shader_type_ == PaintShader::Type::kPaintRecord ||
+ shader_type_ == PaintShader::Type::kImage;
+
// Variables that all shaders use.
- if (local_matrix_) {
- if (!other.local_matrix_.has_value())
- return false;
- if (!PaintOp::AreSkMatricesEqual(*local_matrix_, *other.local_matrix_))
- return false;
- } else {
- if (other.local_matrix_.has_value())
- return false;
+ const SkMatrix& local_matrix = local_matrix_ ? *local_matrix_ : SkMatrix::I();
+ const SkMatrix& other_local_matrix =
+ other.local_matrix_ ? *other.local_matrix_ : SkMatrix::I();
+ if (!CompareMatrices(local_matrix, other_local_matrix,
+ ignore_scaling_differences)) {
+ return false;
}
+
if (fallback_color_ != other.fallback_color_)
return false;
if (flags_ != other.flags_)
@@ -444,7 +525,9 @@ bool PaintShader::operator==(const PaintShader& other) const {
return false;
if (ty_ != other.ty_)
return false;
- if (scaling_behavior_ != other.scaling_behavior_)
+
+ if (!ignore_scaling_differences &&
+ scaling_behavior_ != other.scaling_behavior_)
return false;
// Variables that only some shaders use.
@@ -487,10 +570,8 @@ bool PaintShader::operator==(const PaintShader& other) const {
// aren't the same.
if (!record_ != !other.record_)
return false;
- if (record_ && *record_ != *other.record_)
- return false;
- if (!PaintOp::AreSkRectsEqual(tile_, other.tile_))
- return false;
+ // tile_ and record_ intentionally omitted since they are modified on the
+ // serialized shader based on the ctm.
break;
case Type::kShaderCount:
break;
diff --git a/chromium/cc/paint/paint_shader.h b/chromium/cc/paint/paint_shader.h
index 6c197b7919d..6c2e963fb40 100644
--- a/chromium/cc/paint/paint_shader.h
+++ b/chromium/cc/paint/paint_shader.h
@@ -16,6 +16,7 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkShader.h"
+#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size_f.h"
namespace cc {
@@ -36,6 +37,9 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
kShaderCount
};
+ using RecordShaderId = uint32_t;
+ static const RecordShaderId kInvalidRecordShaderId;
+
// Scaling behavior dictates how a PaintRecord shader will behave. Use
// RasterAtScale to create a picture shader. Use FixedScale to create an image
// shader that is backed by the paint record.
@@ -148,6 +152,11 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
bool operator==(const PaintShader& other) const;
bool operator!=(const PaintShader& other) const { return !(*this == other); }
+ RecordShaderId paint_record_shader_id() const {
+ DCHECK(id_ == kInvalidRecordShaderId || shader_type_ == Type::kPaintRecord);
+ return id_;
+ }
+
private:
friend class PaintFlags;
friend class PaintOpReader;
@@ -156,15 +165,34 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
friend class ScopedRasterFlags;
FRIEND_TEST_ALL_PREFIXES(PaintShaderTest, DecodePaintRecord);
FRIEND_TEST_ALL_PREFIXES(PaintOpBufferTest, PaintRecordShaderSerialization);
+ FRIEND_TEST_ALL_PREFIXES(PaintOpBufferTest, RecordShadersCached);
explicit PaintShader(Type type);
sk_sp<SkShader> GetSkShader() const;
- void CreateSkShader(ImageProvider* image_provider = nullptr);
-
- sk_sp<PaintShader> CreateDecodedPaintRecord(
- const SkMatrix& ctm,
- ImageProvider* image_provider) const;
+ void CreateSkShader(const gfx::SizeF* raster_scale = nullptr,
+ ImageProvider* image_provider = nullptr);
+
+ // Creates a PaintShader to be rasterized at the given ctm. |raster_scale| is
+ // set to the scale at which the record should be rasterized when the shader
+ // is used.
+ // Note that this does not create a skia backing for the shader.
+ // Valid only for PaintRecord backed shaders.
+ sk_sp<PaintShader> CreateScaledPaintRecord(const SkMatrix& ctm,
+ gfx::SizeF* raster_scale) const;
+
+ // Creates a PaintShader with images from |image_provider| to be rasterized
+ // at the given ctm.
+ // |transfer_cache_entry_id| is set to the transfer cache id for the image, if
+ // the decode is backed by the transfer cache.
+ // |raster_quality| is set to the filter quality the shader should be
+ // rasterized with.
+ // Valid only for PaintImage backed shaders.
+ sk_sp<PaintShader> CreateDecodedImage(const SkMatrix& ctm,
+ SkFilterQuality requested_quality,
+ ImageProvider* image_provider,
+ uint32_t* transfer_cache_entry_id,
+ SkFilterQuality* raster_quality) const;
void SetColorsAndPositions(const SkColor* colors,
const SkScalar* positions,
@@ -196,6 +224,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
PaintImage image_;
sk_sp<PaintRecord> record_;
+ RecordShaderId id_ = kInvalidRecordShaderId;
// For decoded PaintRecord shaders, specifies the scale at which the record
// will be rasterized.
diff --git a/chromium/cc/paint/path_transfer_cache_entry.cc b/chromium/cc/paint/path_transfer_cache_entry.cc
new file mode 100644
index 00000000000..c1490109c05
--- /dev/null
+++ b/chromium/cc/paint/path_transfer_cache_entry.cc
@@ -0,0 +1,54 @@
+// 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
new file mode 100644
index 00000000000..b1282e3c11f
--- /dev/null
+++ b/chromium/cc/paint/path_transfer_cache_entry.h
@@ -0,0 +1,46 @@
+// 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/scoped_raster_flags.cc b/chromium/cc/paint/scoped_raster_flags.cc
index b54f137e1dc..cee4465a8c6 100644
--- a/chromium/cc/paint/scoped_raster_flags.cc
+++ b/chromium/cc/paint/scoped_raster_flags.cc
@@ -5,6 +5,7 @@
#include "cc/paint/scoped_raster_flags.h"
#include "cc/paint/image_provider.h"
+#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_image_builder.h"
@@ -12,20 +13,16 @@ namespace cc {
ScopedRasterFlags::ScopedRasterFlags(const PaintFlags* flags,
ImageProvider* image_provider,
const SkMatrix& ctm,
- uint8_t alpha,
- bool create_skia_shader)
+ uint8_t alpha)
: original_flags_(flags) {
- if (flags->HasDiscardableImages() && image_provider) {
- // TODO(khushalsagar): The decoding of images in PaintFlags here is a bit of
- // a mess. We decode image shaders at the correct scale but ignore that
- // during serialization and just use the original image.
+ if (image_provider) {
decode_stashing_image_provider_.emplace(image_provider);
// We skip the op if any images fail to decode.
DecodeImageShader(ctm);
if (decode_failed_)
return;
- DecodeRecordShader(ctm, create_skia_shader);
+ DecodeRecordShader(ctm);
if (decode_failed_)
return;
DecodeFilter();
@@ -48,79 +45,40 @@ void ScopedRasterFlags::DecodeImageShader(const SkMatrix& ctm) {
flags()->getShader()->shader_type() != PaintShader::Type::kImage)
return;
- const PaintImage& paint_image = flags()->getShader()->paint_image();
- SkMatrix matrix = flags()->getShader()->GetLocalMatrix();
+ uint32_t transfer_cache_entry_id = kInvalidImageTransferCacheEntryId;
+ SkFilterQuality raster_quality = flags()->getFilterQuality();
+ auto decoded_shader = flags()->getShader()->CreateDecodedImage(
+ ctm, flags()->getFilterQuality(), &*decode_stashing_image_provider_,
+ &transfer_cache_entry_id, &raster_quality);
+ DCHECK_EQ(transfer_cache_entry_id, kInvalidImageTransferCacheEntryId);
- SkMatrix total_image_matrix = matrix;
- total_image_matrix.preConcat(ctm);
- SkRect src_rect = SkRect::MakeIWH(paint_image.width(), paint_image.height());
- SkIRect int_src_rect;
- src_rect.roundOut(&int_src_rect);
- DrawImage draw_image(paint_image, int_src_rect, flags()->getFilterQuality(),
- total_image_matrix);
- auto decoded_draw_image =
- decode_stashing_image_provider_->GetDecodedDrawImage(draw_image);
-
- if (!decoded_draw_image) {
+ if (!decoded_shader) {
decode_failed_ = true;
return;
}
- const auto& decoded_image = decoded_draw_image.decoded_image();
- // If this image is backed by a transfer cache entry id, then it's suitable
- // for serialization. We don't need to do anything here, because the image
- // provider (accessed via PaintOpWriter) will get the decode and serialize the
- // transfer cache id.
- // Note that if we replace this with the decoded paint image, the
- // serialization will fail, because a transfer cache backed image cannot on
- // its own construct an SkImage which is needed to create an underlying
- // SkShader.
- if (decoded_image.transfer_cache_entry_id()) {
- DCHECK(!decoded_image.image());
- return;
- }
- DCHECK(decoded_image.image());
-
- bool need_scale = !decoded_image.is_scale_adjustment_identity();
- if (need_scale) {
- matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
- 1.f / decoded_image.scale_adjustment().height());
- }
-
- sk_sp<SkImage> sk_image =
- sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
- PaintImage decoded_paint_image =
- PaintImageBuilder::WithDefault()
- .set_id(paint_image.stable_id())
- .set_image(std::move(sk_image), PaintImage::kNonLazyStableId)
- .TakePaintImage();
- MutableFlags()->setFilterQuality(decoded_image.filter_quality());
- MutableFlags()->setShader(
- PaintShader::MakeImage(decoded_paint_image, flags()->getShader()->tx(),
- flags()->getShader()->ty(), &matrix));
+ MutableFlags()->setFilterQuality(raster_quality);
+ MutableFlags()->setShader(decoded_shader);
}
-void ScopedRasterFlags::DecodeRecordShader(const SkMatrix& ctm,
- bool create_skia_shader) {
+void ScopedRasterFlags::DecodeRecordShader(const SkMatrix& ctm) {
if (!flags()->HasShader() ||
flags()->getShader()->shader_type() != PaintShader::Type::kPaintRecord)
return;
- // TODO(khushalsagar): For OOP, we have to decode everything during
- // serialization. This will force us to use original sized decodes.
+ // Only replace shaders with animated images. Creating transient shaders for
+ // replacing decodes during raster results in cache misses in skia's picture
+ // shader cache, which results in re-rasterizing the picture for every draw.
if (flags()->getShader()->image_analysis_state() !=
- ImageAnalysisState::kAnimatedImages)
- return;
-
- auto decoded_shader = flags()->getShader()->CreateDecodedPaintRecord(
- ctm, &*decode_stashing_image_provider_);
- if (!decoded_shader) {
- decode_failed_ = true;
+ ImageAnalysisState::kAnimatedImages) {
return;
}
- if (create_skia_shader)
- decoded_shader->CreateSkShader(&*decode_stashing_image_provider_);
+ gfx::SizeF raster_scale(1.f, 1.f);
+ auto decoded_shader =
+ flags()->getShader()->CreateScaledPaintRecord(ctm, &raster_scale);
+ decoded_shader->CreateSkShader(&raster_scale,
+ &*decode_stashing_image_provider_);
MutableFlags()->setShader(std::move(decoded_shader));
}
diff --git a/chromium/cc/paint/scoped_raster_flags.h b/chromium/cc/paint/scoped_raster_flags.h
index 5407b5e2655..91a6b871105 100644
--- a/chromium/cc/paint/scoped_raster_flags.h
+++ b/chromium/cc/paint/scoped_raster_flags.h
@@ -21,8 +21,7 @@ class CC_PAINT_EXPORT ScopedRasterFlags {
ScopedRasterFlags(const PaintFlags* flags,
ImageProvider* image_provider,
const SkMatrix& ctm,
- uint8_t alpha,
- bool create_skia_shaders);
+ uint8_t alpha);
~ScopedRasterFlags();
// The usage of these flags should not extend beyond the lifetime of this
@@ -36,7 +35,7 @@ class CC_PAINT_EXPORT ScopedRasterFlags {
private:
void DecodeImageShader(const SkMatrix& ctm);
- void DecodeRecordShader(const SkMatrix& ctm, bool create_skia_shader);
+ void DecodeRecordShader(const SkMatrix& ctm);
void DecodeFilter();
void AdjustStrokeIfNeeded(const SkMatrix& ctm);
diff --git a/chromium/cc/paint/scoped_raster_flags_unittest.cc b/chromium/cc/paint/scoped_raster_flags_unittest.cc
index b0ac2654d1d..801d6cfa933 100644
--- a/chromium/cc/paint/scoped_raster_flags_unittest.cc
+++ b/chromium/cc/paint/scoped_raster_flags_unittest.cc
@@ -60,7 +60,7 @@ TEST(ScopedRasterFlagsTest, KeepsDecodesAlive) {
PaintFlags flags;
flags.setShader(record_shader);
{
- ScopedRasterFlags scoped_flags(&flags, &provider, SkMatrix::I(), 255, true);
+ ScopedRasterFlags scoped_flags(&flags, &provider, SkMatrix::I(), 255);
ASSERT_TRUE(scoped_flags.flags());
EXPECT_NE(scoped_flags.flags(), &flags);
SkPaint paint = scoped_flags.flags()->ToSkPaint();
@@ -77,7 +77,7 @@ TEST(ScopedRasterFlagsTest, NoImageProvider) {
CreateDiscardablePaintImage(gfx::Size(10, 10)),
SkShader::TileMode::kClamp_TileMode, SkShader::TileMode::kClamp_TileMode,
&SkMatrix::I()));
- ScopedRasterFlags scoped_flags(&flags, nullptr, SkMatrix::I(), 10, true);
+ ScopedRasterFlags scoped_flags(&flags, nullptr, SkMatrix::I(), 10);
EXPECT_NE(scoped_flags.flags(), &flags);
EXPECT_EQ(scoped_flags.flags()->getAlpha(), SkMulDiv255Round(255, 10));
}
@@ -108,7 +108,7 @@ TEST(ScopedRasterFlagsTest, ThinAliasedStroke) {
};
for (const auto& test : tests) {
- ScopedRasterFlags scoped_flags(&flags, nullptr, test.ctm, test.alpha, true);
+ ScopedRasterFlags scoped_flags(&flags, nullptr, test.ctm, test.alpha);
ASSERT_TRUE(scoped_flags.flags());
EXPECT_EQ(scoped_flags.flags() == &flags, test.expect_same_flags);
diff --git a/chromium/cc/paint/shader_transfer_cache_entry.cc b/chromium/cc/paint/shader_transfer_cache_entry.cc
new file mode 100644
index 00000000000..5e66f1b6b95
--- /dev/null
+++ b/chromium/cc/paint/shader_transfer_cache_entry.cc
@@ -0,0 +1,31 @@
+// 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/shader_transfer_cache_entry.h"
+
+namespace cc {
+
+ServiceShaderTransferCacheEntry::ServiceShaderTransferCacheEntry(
+ sk_sp<PaintShader> shader,
+ uint32_t raster_color_space_id,
+ size_t size)
+ : shader_(std::move(shader)),
+ raster_color_space_id_(raster_color_space_id),
+ size_(size) {}
+
+ServiceShaderTransferCacheEntry::~ServiceShaderTransferCacheEntry() = default;
+
+size_t ServiceShaderTransferCacheEntry::CachedSize() const {
+ return size_;
+}
+
+bool ServiceShaderTransferCacheEntry::Deserialize(
+ GrContext* context,
+ base::span<const uint8_t> data) {
+ // These entries must be created directly via CreateLocalEntry.
+ NOTREACHED();
+ return false;
+}
+
+} // namespace cc
diff --git a/chromium/cc/paint/shader_transfer_cache_entry.h b/chromium/cc/paint/shader_transfer_cache_entry.h
new file mode 100644
index 00000000000..fcb6abb7572
--- /dev/null
+++ b/chromium/cc/paint/shader_transfer_cache_entry.h
@@ -0,0 +1,46 @@
+// 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_SHADER_TRANSFER_CACHE_ENTRY_H_
+#define CC_PAINT_SHADER_TRANSFER_CACHE_ENTRY_H_
+
+#include "base/containers/span.h"
+#include "cc/paint/paint_export.h"
+#include "cc/paint/paint_shader.h"
+#include "cc/paint/transfer_cache_entry.h"
+
+namespace cc {
+
+// There is only a service transfer cache entry here. The reason shaders
+// are cached at all are to reuse internal Skia caches for SkPictureShaders.
+// However, the major reason not to transfer from the client is that it
+// avoids the design change to make it possible for transfer cache entries
+// to depend on transfer cache entries. This adds a number of wrinkles
+// (during serialization, deserialization, scheduling). The assumption
+// is that most picture shaders are small (e.g. a few ops to draw a tiled
+// image) and that the design complication for this edge case isn't worth
+// it.
+
+class CC_PAINT_EXPORT ServiceShaderTransferCacheEntry
+ : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kShader> {
+ public:
+ explicit ServiceShaderTransferCacheEntry(sk_sp<PaintShader> shader,
+ uint32_t raster_color_space_id,
+ size_t size);
+ ~ServiceShaderTransferCacheEntry() final;
+ size_t CachedSize() const final;
+ bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
+
+ sk_sp<PaintShader> shader() const { return shader_; }
+ uint32_t raster_color_space_id() const { return raster_color_space_id_; }
+
+ private:
+ sk_sp<PaintShader> shader_;
+ uint32_t raster_color_space_id_;
+ size_t size_ = 0;
+};
+
+} // namespace cc
+
+#endif // CC_PAINT_SHADER_TRANSFER_CACHE_ENTRY_H_
diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc
index 83128d5c3a6..b5963ca9d05 100644
--- a/chromium/cc/paint/skia_paint_canvas.cc
+++ b/chromium/cc/paint/skia_paint_canvas.cc
@@ -16,8 +16,6 @@
namespace cc {
-const bool SkiaPaintCanvas::kCreateSkiaShaders = true;
-
SkiaPaintCanvas::ContextFlushes::ContextFlushes()
: enable(false), max_draws_before_flush(-1) {}
@@ -171,8 +169,7 @@ void SkiaPaintCanvas::drawLine(SkScalar x0,
SkScalar y1,
const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -183,8 +180,7 @@ void SkiaPaintCanvas::drawLine(SkScalar x0,
void SkiaPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -195,8 +191,7 @@ void SkiaPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) {
void SkiaPaintCanvas::drawIRect(const SkIRect& rect, const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -207,8 +202,7 @@ void SkiaPaintCanvas::drawIRect(const SkIRect& rect, const PaintFlags& flags) {
void SkiaPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -219,8 +213,7 @@ void SkiaPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) {
void SkiaPaintCanvas::drawRRect(const SkRRect& rrect, const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -233,8 +226,7 @@ void SkiaPaintCanvas::drawDRRect(const SkRRect& outer,
const SkRRect& inner,
const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -248,8 +240,7 @@ void SkiaPaintCanvas::drawRoundRect(const SkRect& rect,
SkScalar ry,
const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -260,8 +251,7 @@ void SkiaPaintCanvas::drawRoundRect(const SkRect& rect,
void SkiaPaintCanvas::drawPath(const SkPath& path, const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -277,7 +267,7 @@ void SkiaPaintCanvas::drawImage(const PaintImage& image,
base::Optional<ScopedRasterFlags> scoped_flags;
if (flags) {
scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(),
- 255u, kCreateSkiaShaders);
+ 255u);
if (!scoped_flags->flags())
return;
}
@@ -297,7 +287,7 @@ void SkiaPaintCanvas::drawImageRect(const PaintImage& image,
base::Optional<ScopedRasterFlags> scoped_flags;
if (flags) {
scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(),
- 255u, kCreateSkiaShaders);
+ 255u);
if (!scoped_flags->flags())
return;
}
@@ -316,8 +306,7 @@ void SkiaPaintCanvas::drawBitmap(const SkBitmap& bitmap,
const PaintFlags* flags) {
if (flags) {
ScopedRasterFlags raster_flags(flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
@@ -333,8 +322,7 @@ void SkiaPaintCanvas::drawTextBlob(scoped_refptr<PaintTextBlob> blob,
SkScalar y,
const PaintFlags& flags) {
ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), 255u,
- kCreateSkiaShaders);
+ canvas_->getTotalMatrix(), 255u);
if (!raster_flags.flags())
return;
SkPaint paint = raster_flags.flags()->ToSkPaint();
diff --git a/chromium/cc/paint/skia_paint_canvas.h b/chromium/cc/paint/skia_paint_canvas.h
index d5f39f657e4..c9e1936733e 100644
--- a/chromium/cc/paint/skia_paint_canvas.h
+++ b/chromium/cc/paint/skia_paint_canvas.h
@@ -142,9 +142,6 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas {
PlaybackParams::CustomDataRasterCallback custom_raster_callback);
private:
- // We always need skia shaders since the ops will be played on an SkCanvas.
- static const bool kCreateSkiaShaders;
-
void WrapCanvasInColorSpaceXformCanvas(
sk_sp<SkColorSpace> target_color_space);
void FlushAfterDrawIfNeeded();
diff --git a/chromium/cc/paint/skia_paint_image_generator.cc b/chromium/cc/paint/skia_paint_image_generator.cc
index 40b30df340f..d7b6c1a7e62 100644
--- a/chromium/cc/paint/skia_paint_image_generator.cc
+++ b/chromium/cc/paint/skia_paint_image_generator.cc
@@ -17,8 +17,8 @@ SkiaPaintImageGenerator::SkiaPaintImageGenerator(
SkiaPaintImageGenerator::~SkiaPaintImageGenerator() = default;
-SkData* SkiaPaintImageGenerator::onRefEncodedData() {
- return paint_image_generator_->GetEncodedData().release();
+sk_sp<SkData> SkiaPaintImageGenerator::onRefEncodedData() {
+ return paint_image_generator_->GetEncodedData();
}
bool SkiaPaintImageGenerator::onGetPixels(const SkImageInfo& info,
diff --git a/chromium/cc/paint/skia_paint_image_generator.h b/chromium/cc/paint/skia_paint_image_generator.h
index 97da522e806..859faf52298 100644
--- a/chromium/cc/paint/skia_paint_image_generator.h
+++ b/chromium/cc/paint/skia_paint_image_generator.h
@@ -18,7 +18,7 @@ class CC_PAINT_EXPORT SkiaPaintImageGenerator final : public SkImageGenerator {
size_t frame_index);
~SkiaPaintImageGenerator() override;
- SkData* onRefEncodedData() override;
+ sk_sp<SkData> onRefEncodedData() override;
bool onGetPixels(const SkImageInfo&,
void* pixels,
size_t row_bytes,
diff --git a/chromium/cc/paint/solid_color_analyzer.cc b/chromium/cc/paint/solid_color_analyzer.cc
index 4e59ffde676..1863cfb3778 100644
--- a/chromium/cc/paint/solid_color_analyzer.cc
+++ b/chromium/cc/paint/solid_color_analyzer.cc
@@ -263,17 +263,20 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
break;
}
- // The rest of the ops should only affect our state canvas.
+ // Don't affect the canvas, so ignore.
case PaintOpType::Annotate:
- case PaintOpType::Concat:
case PaintOpType::CustomData:
+ case PaintOpType::Noop:
+ break;
+
+ // The rest of the ops should only affect our state canvas.
+ case PaintOpType::Concat:
case PaintOpType::Scale:
case PaintOpType::SetMatrix:
case PaintOpType::Restore:
case PaintOpType::Rotate:
case PaintOpType::Save:
case PaintOpType::Translate:
- case PaintOpType::Noop:
op->Raster(&canvas, params);
break;
}
diff --git a/chromium/cc/paint/transfer_cache_deserialize_helper.h b/chromium/cc/paint/transfer_cache_deserialize_helper.h
index 48d4c6f04b9..530b4795de9 100644
--- a/chromium/cc/paint/transfer_cache_deserialize_helper.h
+++ b/chromium/cc/paint/transfer_cache_deserialize_helper.h
@@ -32,16 +32,28 @@ class CC_PAINT_EXPORT TransferCacheDeserializeHelper {
if (entry == nullptr) {
return nullptr;
}
+
+ total_size_ += entry->CachedSize();
+
// The service side entry is created using T::kType, so the class created is
// guaranteed to make the entry type.
DCHECK_EQ(entry->Type(), entry_type);
return static_cast<T*>(entry);
}
+ // Creates an entry directly. If an entry exists, it will be clobbered.
+ virtual void CreateLocalEntry(
+ uint32_t id,
+ std::unique_ptr<ServiceTransferCacheEntry> entry) = 0;
+
+ size_t GetTotalEntrySizes() const { return total_size_; }
+
private:
virtual ServiceTransferCacheEntry* GetEntryInternal(
TransferCacheEntryType entry_type,
uint32_t entry_id) = 0;
+
+ size_t total_size_ = 0;
};
}; // namespace cc
diff --git a/chromium/cc/paint/transfer_cache_entry.cc b/chromium/cc/paint/transfer_cache_entry.cc
index 46252c1850d..eb51292b2aa 100644
--- a/chromium/cc/paint/transfer_cache_entry.cc
+++ b/chromium/cc/paint/transfer_cache_entry.cc
@@ -10,7 +10,9 @@
#include "cc/paint/color_space_transfer_cache_entry.h"
#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/paint/paint_typeface_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"
namespace cc {
@@ -25,6 +27,12 @@ std::unique_ptr<ServiceTransferCacheEntry> ServiceTransferCacheEntry::Create(
return std::make_unique<ServicePaintTypefaceTransferCacheEntry>();
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.
+ return nullptr;
}
return nullptr;
diff --git a/chromium/cc/paint/transfer_cache_entry.h b/chromium/cc/paint/transfer_cache_entry.h
index 9ecde14aedc..474bd970344 100644
--- a/chromium/cc/paint/transfer_cache_entry.h
+++ b/chromium/cc/paint/transfer_cache_entry.h
@@ -24,8 +24,10 @@ enum class TransferCacheEntryType : uint32_t {
kImage,
kPaintTypeface,
kColorSpace,
+ kPath,
+ kShader,
// Add new entries above this line, make sure to update kLast.
- kLast = kColorSpace,
+ kLast = kShader,
};
// An interface used on the client to serialize a transfer cache entry
diff --git a/chromium/cc/paint/transfer_cache_unittest.cc b/chromium/cc/paint/transfer_cache_unittest.cc
index 4c1ea2875e8..d8fb589c35d 100644
--- a/chromium/cc/paint/transfer_cache_unittest.cc
+++ b/chromium/cc/paint/transfer_cache_unittest.cc
@@ -14,12 +14,12 @@
#include "gpu/command_buffer/client/client_transfer_cache.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/service/service_transfer_cache.h"
#include "gpu/config/gpu_switches.h"
-#include "gpu/ipc/gl_in_process_context.h"
+#include "gpu/ipc/raster_in_process_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImage.h"
#include "ui/gl/gl_implementation.h"
@@ -29,10 +29,9 @@ namespace {
class TransferCacheTest : public testing::Test {
public:
- TransferCacheTest()
- : testing::Test(), test_client_entry_(std::vector<uint8_t>(100)) {}
+ TransferCacheTest() : test_client_entry_(std::vector<uint8_t>(100)) {}
+
void SetUp() override {
- bool is_offscreen = true;
gpu::ContextCreationAttribs attribs;
attribs.alpha_size = -1;
attribs.depth_size = 24;
@@ -43,21 +42,15 @@ class TransferCacheTest : public testing::Test {
attribs.bind_generates_resource = false;
// Enable OOP rasterization.
attribs.enable_oop_rasterization = true;
+ attribs.enable_raster_interface = true;
+ attribs.enable_gles2_interface = false;
- // Add an OOP rasterization command line flag so that we set
- // |chromium_raster_transport| features flag.
- // TODO(vmpstr): Is there a better way to do this?
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableOOPRasterization)) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableOOPRasterization);
- }
-
- context_ = gpu::GLInProcessContext::CreateWithoutInit();
+ context_ = std::make_unique<gpu::RasterInProcessContext>();
auto result = context_->Initialize(
- nullptr, nullptr, is_offscreen, gpu::kNullSurfaceHandle, nullptr,
- attribs, gpu::SharedMemoryLimits(), &gpu_memory_buffer_manager_,
- &image_factory_, nullptr, base::ThreadTaskRunnerHandle::Get());
+ /*service=*/nullptr, attribs, gpu::SharedMemoryLimits(),
+ &gpu_memory_buffer_manager_, &image_factory_,
+ /*gpu_channel_manager_delegate=*/nullptr,
+ base::ThreadTaskRunnerHandle::Get());
ASSERT_EQ(result, gpu::ContextResult::kSuccess);
ASSERT_TRUE(context_->GetCapabilities().supports_oop_raster);
@@ -69,12 +62,10 @@ class TransferCacheTest : public testing::Test {
return context_->GetTransferCacheForTest();
}
- gpu::gles2::GLES2Implementation* Gl() {
- return context_->GetImplementation();
- }
+ gpu::raster::RasterInterface* ri() { return context_->GetImplementation(); }
gpu::ContextSupport* ContextSupport() {
- return context_->GetImplementation();
+ return context_->GetContextSupport();
}
const ClientRawMemoryTransferCacheEntry& test_client_entry() const {
@@ -93,20 +84,19 @@ class TransferCacheTest : public testing::Test {
private:
viz::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
TestImageFactory image_factory_;
- std::unique_ptr<gpu::GLInProcessContext> context_;
+ std::unique_ptr<gpu::RasterInProcessContext> context_;
gl::DisableNullDrawGLBindings enable_pixel_output_;
ClientRawMemoryTransferCacheEntry test_client_entry_;
};
TEST_F(TransferCacheTest, Basic) {
auto* service_cache = ServiceTransferCache();
- auto* gl = Gl();
auto* context_support = ContextSupport();
// Create an entry.
const auto& entry = test_client_entry();
CreateEntry(entry);
- gl->Finish();
+ ri()->Finish();
// Validate service-side state.
EXPECT_NE(nullptr, service_cache->GetEntry(entry.Type(), entry.Id()));
@@ -114,7 +104,7 @@ TEST_F(TransferCacheTest, Basic) {
// Unlock on client side and flush to service.
context_support->UnlockTransferCacheEntries(
{{entry.UnsafeType(), entry.Id()}});
- gl->Finish();
+ ri()->Finish();
// Re-lock on client side and validate state. No need to flush as lock is
// local.
@@ -123,19 +113,18 @@ TEST_F(TransferCacheTest, Basic) {
// Delete on client side, flush, and validate that deletion reaches service.
context_support->DeleteTransferCacheEntry(entry.UnsafeType(), entry.Id());
- gl->Finish();
+ ri()->Finish();
EXPECT_EQ(nullptr, service_cache->GetEntry(entry.Type(), entry.Id()));
}
TEST_F(TransferCacheTest, Eviction) {
auto* service_cache = ServiceTransferCache();
- auto* gl = Gl();
auto* context_support = ContextSupport();
const auto& entry = test_client_entry();
// Create an entry.
CreateEntry(entry);
- gl->Finish();
+ ri()->Finish();
// Validate service-side state.
EXPECT_NE(nullptr, service_cache->GetEntry(entry.Type(), entry.Id()));
@@ -143,7 +132,7 @@ TEST_F(TransferCacheTest, Eviction) {
// Unlock on client side and flush to service.
context_support->UnlockTransferCacheEntries(
{{entry.UnsafeType(), entry.Id()}});
- gl->Finish();
+ ri()->Finish();
// Evict on the service side.
service_cache->SetCacheSizeLimitForTesting(0);
@@ -156,7 +145,6 @@ TEST_F(TransferCacheTest, Eviction) {
TEST_F(TransferCacheTest, RawMemoryTransfer) {
auto* service_cache = ServiceTransferCache();
- auto* gl = Gl();
// Create an entry with some initialized data.
std::vector<uint8_t> data;
@@ -168,7 +156,7 @@ TEST_F(TransferCacheTest, RawMemoryTransfer) {
// Add the entry to the transfer cache
ClientRawMemoryTransferCacheEntry client_entry(data);
CreateEntry(client_entry);
- gl->Finish();
+ ri()->Finish();
// Validate service-side data matches.
ServiceTransferCacheEntry* service_entry =
@@ -186,7 +174,6 @@ TEST_F(TransferCacheTest, ImageMemoryTransfer) {
#endif
auto* service_cache = ServiceTransferCache();
- auto* gl = Gl();
// Create a 10x10 image.
SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
@@ -200,7 +187,7 @@ TEST_F(TransferCacheTest, ImageMemoryTransfer) {
// Add the entry to the transfer cache
ClientImageTransferCacheEntry client_entry(&pixmap, nullptr);
CreateEntry(client_entry);
- gl->Finish();
+ ri()->Finish();
// Validate service-side data matches.
ServiceTransferCacheEntry* service_entry =
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index ae5744092af..c801facce0e 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -14,7 +14,6 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/raster/raster_source.h"
-#include "cc/resources/resource.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/platform_color.h"
@@ -70,7 +69,7 @@ class BitmapRasterBufferImpl : public RasterBuffer {
RasterBufferProvider::PlaybackToMemory(
pixels_, viz::RGBA_8888, resource_size_, stride, raster_source,
raster_full_rect, playback_rect, transform, color_space_,
- playback_settings);
+ /*gpu_compositing=*/false, playback_settings);
}
private:
@@ -124,19 +123,18 @@ BitmapRasterBufferProvider::AcquireBufferForRaster(
void BitmapRasterBufferProvider::Flush() {}
-viz::ResourceFormat BitmapRasterBufferProvider::GetResourceFormat(
- bool must_support_alpha) const {
+viz::ResourceFormat BitmapRasterBufferProvider::GetResourceFormat() const {
return viz::RGBA_8888;
}
-bool BitmapRasterBufferProvider::IsResourceSwizzleRequired(
- bool must_support_alpha) const {
- // GetResourceFormat() returns a constant so use it directly.
- return ResourceFormatRequiresSwizzle(viz::RGBA_8888);
+bool BitmapRasterBufferProvider::IsResourceSwizzleRequired() const {
+ // This value only used by gpu compositing. Software compositing resources
+ // are all in the native skia byte ordering, and the display compositor will
+ // do its drawing in the same order.
+ return false;
}
-bool BitmapRasterBufferProvider::IsResourcePremultiplied(
- bool must_support_alpha) const {
+bool BitmapRasterBufferProvider::IsResourcePremultiplied() const {
return true;
}
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.h b/chromium/cc/raster/bitmap_raster_buffer_provider.h
index 1f33b863b5b..5174176fd11 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.h
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.h
@@ -32,9 +32,9 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider {
uint64_t resource_content_id,
uint64_t previous_content_id) override;
void Flush() override;
- viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
- bool IsResourceSwizzleRequired(bool must_support_alpha) const override;
- bool IsResourcePremultiplied(bool must_support_alpha) const override;
+ viz::ResourceFormat GetResourceFormat() const override;
+ bool IsResourceSwizzleRequired() const override;
+ bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
const ResourcePool::InUsePoolResource& resource) const override;
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index ba2abde1adc..f449095504c 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -17,7 +17,7 @@
#include "cc/paint/paint_recorder.h"
#include "cc/raster/raster_source.h"
#include "cc/raster/scoped_gpu_raster.h"
-#include "cc/resources/resource.h"
+#include "cc/resources/layer_tree_resource_provider.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/gpu/texture_allocation.h"
@@ -27,7 +27,6 @@
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
-#include "skia/ext/texture_handle.h"
#include "third_party/skia/include/core/SkMultiPictureDraw.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -85,12 +84,17 @@ class ScopedSkSurfaceForUnpremultiplyAndDither {
if (!surface_)
return;
- GrBackendObject handle =
- surface_->getTextureHandle(SkSurface::kFlushRead_BackendHandleAccess);
- const GrGLTextureInfo* info =
- skia::GrBackendObjectToGrGLTextureInfo(handle);
+ GrBackendTexture backend_texture =
+ surface_->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
+ if (!backend_texture.isValid()) {
+ return;
+ }
+ GrGLTextureInfo info;
+ if (!backend_texture.getGLTextureInfo(&info)) {
+ return;
+ }
context_provider_->ContextGL()->UnpremultiplyAndDitherCopyCHROMIUM(
- info->fID, texture_id_, offset_.x(), offset_.y(), size_.width(),
+ info.fID, texture_id_, offset_.x(), offset_.y(), size_.width(),
size_.height());
}
@@ -134,11 +138,11 @@ static void RasterizeSourceOOP(
// TODO(enne): Use the |texture_target|? GpuMemoryBuffer backed textures don't
// use GL_TEXTURE_2D.
- ri->BeginRasterCHROMIUM(
- texture_id, raster_source->background_color(), msaa_sample_count,
- playback_settings.use_lcd_text,
- viz::ResourceFormatToClosestSkColorType(resource_format),
- playback_settings.raster_color_space);
+ ri->BeginRasterCHROMIUM(texture_id, raster_source->background_color(),
+ msaa_sample_count, playback_settings.use_lcd_text,
+ viz::ResourceFormatToClosestSkColorType(
+ /*gpu_compositing=*/true, resource_format),
+ playback_settings.raster_color_space);
float recording_to_raster_scale =
transform.scale() / raster_source->recording_scale_factor();
gfx::Size content_size = raster_source->GetContentSize(transform.scale());
@@ -336,19 +340,17 @@ void GpuRasterBufferProvider::RasterBufferImpl::Playback(
GpuRasterBufferProvider::GpuRasterBufferProvider(
viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
bool use_gpu_memory_buffer_resources,
int gpu_rasterization_msaa_sample_count,
- viz::ResourceFormat preferred_tile_format,
+ viz::ResourceFormat tile_format,
const gfx::Size& max_tile_size,
bool unpremultiply_and_dither_low_bit_depth_tiles,
bool enable_oop_rasterization)
: compositor_context_provider_(compositor_context_provider),
worker_context_provider_(worker_context_provider),
- resource_provider_(resource_provider),
use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
msaa_sample_count_(gpu_rasterization_msaa_sample_count),
- preferred_tile_format_(preferred_tile_format),
+ tile_format_(tile_format),
max_tile_size_(max_tile_size),
unpremultiply_and_dither_low_bit_depth_tiles_(
unpremultiply_and_dither_low_bit_depth_tiles),
@@ -399,28 +401,17 @@ void GpuRasterBufferProvider::Flush() {
compositor_context_provider_->ContextSupport()->FlushPendingWork();
}
-viz::ResourceFormat GpuRasterBufferProvider::GetResourceFormat(
- bool must_support_alpha) const {
- if (resource_provider_->IsRenderBufferFormatSupported(
- preferred_tile_format_) &&
- (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
- !must_support_alpha)) {
- return preferred_tile_format_;
- }
-
- return resource_provider_->best_render_buffer_format();
+viz::ResourceFormat GpuRasterBufferProvider::GetResourceFormat() const {
+ return tile_format_;
}
-bool GpuRasterBufferProvider::IsResourceSwizzleRequired(
- bool must_support_alpha) const {
+bool GpuRasterBufferProvider::IsResourceSwizzleRequired() const {
// This doesn't require a swizzle because we rasterize to the correct format.
return false;
}
-bool GpuRasterBufferProvider::IsResourcePremultiplied(
- bool must_support_alpha) const {
- return !ShouldUnpremultiplyAndDitherResource(
- GetResourceFormat(must_support_alpha));
+bool GpuRasterBufferProvider::IsResourcePremultiplied() const {
+ return !ShouldUnpremultiplyAndDitherResource(GetResourceFormat());
}
bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h
index c019d77fa07..67881acd682 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.h
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.h
@@ -9,7 +9,6 @@
#include "base/macros.h"
#include "cc/raster/raster_buffer_provider.h"
-#include "cc/resources/layer_tree_resource_provider.h"
#include "gpu/command_buffer/common/sync_token.h"
namespace viz {
@@ -23,10 +22,9 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
public:
GpuRasterBufferProvider(viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
bool use_gpu_memory_buffer_resources,
int gpu_rasterization_msaa_sample_count,
- viz::ResourceFormat preferred_tile_format,
+ viz::ResourceFormat tile_format,
const gfx::Size& max_tile_size,
bool unpremultiply_and_dither_low_bit_depth_tiles,
bool enable_oop_rasterization);
@@ -38,9 +36,9 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
uint64_t resource_content_id,
uint64_t previous_content_id) override;
void Flush() override;
- viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
- bool IsResourceSwizzleRequired(bool must_support_alpha) const override;
- bool IsResourcePremultiplied(bool must_support_alpha) const override;
+ viz::ResourceFormat GetResourceFormat() const override;
+ bool IsResourceSwizzleRequired() const override;
+ bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
const ResourcePool::InUsePoolResource& resource) const override;
@@ -114,10 +112,9 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
viz::ContextProvider* const compositor_context_provider_;
viz::RasterContextProvider* const worker_context_provider_;
- LayerTreeResourceProvider* const resource_provider_;
const bool use_gpu_memory_buffer_resources_;
const int msaa_sample_count_;
- const viz::ResourceFormat preferred_tile_format_;
+ const viz::ResourceFormat tile_format_;
const gfx::Size max_tile_size_;
const bool unpremultiply_and_dither_low_bit_depth_tiles_;
const bool enable_oop_rasterization_;
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index fdf03d5db1d..90f94f65055 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -74,7 +74,7 @@ class OneCopyRasterBufferProvider::OneCopyGpuBacking
OneCopyRasterBufferProvider::RasterBufferImpl::RasterBufferImpl(
OneCopyRasterBufferProvider* client,
- LayerTreeResourceProvider* resource_provider,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const ResourcePool::InUsePoolResource& in_use_resource,
OneCopyGpuBacking* backing,
uint64_t previous_content_id)
@@ -127,15 +127,15 @@ OneCopyRasterBufferProvider::OneCopyRasterBufferProvider(
scoped_refptr<base::SequencedTaskRunner> task_runner,
viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
int max_copy_texture_chromium_size,
bool use_partial_raster,
bool use_gpu_memory_buffer_resources,
int max_staging_buffer_usage_in_bytes,
- viz::ResourceFormat preferred_tile_format)
+ viz::ResourceFormat tile_format)
: compositor_context_provider_(compositor_context_provider),
worker_context_provider_(worker_context_provider),
- resource_provider_(resource_provider),
+ gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
max_bytes_per_copy_operation_(
max_copy_texture_chromium_size
? std::min(kMaxBytesPerCopyOperation,
@@ -144,10 +144,9 @@ OneCopyRasterBufferProvider::OneCopyRasterBufferProvider(
use_partial_raster_(use_partial_raster),
use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
bytes_scheduled_since_last_flush_(0),
- preferred_tile_format_(preferred_tile_format),
+ tile_format_(tile_format),
staging_pool_(std::move(task_runner),
worker_context_provider,
- resource_provider,
use_partial_raster,
max_staging_buffer_usage_in_bytes) {
DCHECK(compositor_context_provider);
@@ -188,8 +187,8 @@ OneCopyRasterBufferProvider::AcquireBufferForRaster(
static_cast<OneCopyGpuBacking*>(resource.gpu_backing());
// TODO(danakj): If resource_content_id != 0, we only need to copy/upload
// the dirty rect.
- return std::make_unique<RasterBufferImpl>(this, resource_provider_, resource,
- backing, previous_content_id);
+ return std::make_unique<RasterBufferImpl>(
+ this, gpu_memory_buffer_manager_, resource, backing, previous_content_id);
}
void OneCopyRasterBufferProvider::Flush() {
@@ -201,24 +200,15 @@ void OneCopyRasterBufferProvider::Flush() {
compositor_context_provider_->ContextSupport()->FlushPendingWork();
}
-viz::ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat(
- bool must_support_alpha) const {
- if (resource_provider_->IsTextureFormatSupported(preferred_tile_format_) &&
- (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
- !must_support_alpha)) {
- return preferred_tile_format_;
- }
-
- return resource_provider_->best_texture_format();
+viz::ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat() const {
+ return tile_format_;
}
-bool OneCopyRasterBufferProvider::IsResourceSwizzleRequired(
- bool must_support_alpha) const {
- return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+bool OneCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
+ return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
}
-bool OneCopyRasterBufferProvider::IsResourcePremultiplied(
- bool must_support_alpha) const {
+bool OneCopyRasterBufferProvider::IsResourcePremultiplied() const {
// TODO(ericrk): Handle unpremultiply/dither in one-copy case as well.
// https://crbug.com/789153
return true;
@@ -323,7 +313,7 @@ void OneCopyRasterBufferProvider::PlaybackToStagingBuffer(
// must allocate a buffer with BufferUsage CPU_READ_WRITE_PERSISTENT.
if (!staging_buffer->gpu_memory_buffer) {
staging_buffer->gpu_memory_buffer =
- resource_provider_->gpu_memory_buffer_manager()->CreateGpuMemoryBuffer(
+ gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
staging_buffer->size, BufferFormat(format), StagingBufferUsage(),
gpu::kNullSurfaceHandle);
}
@@ -364,7 +354,7 @@ void OneCopyRasterBufferProvider::PlaybackToStagingBuffer(
RasterBufferProvider::PlaybackToMemory(
buffer->memory(0), format, staging_buffer->size, buffer->stride(0),
raster_source, raster_full_rect, playback_rect, transform,
- dst_color_space, playback_settings);
+ dst_color_space, /*gpu_compositing=*/true, playback_settings);
buffer->Unmap();
staging_buffer->content_id = new_content_id;
}
@@ -438,7 +428,7 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
// TODO(vmiura): Need a way to ensure we don't hold onto bindings?
// ri->BindTexture(image_target, 0);
- if (resource_provider_->use_sync_query()) {
+ if (worker_context_provider_->ContextCapabilities().sync_query) {
if (!staging_buffer->query_id)
ri->GenQueriesEXT(1, &staging_buffer->query_id);
@@ -485,7 +475,7 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
}
}
- if (resource_provider_->use_sync_query()) {
+ if (worker_context_provider_->ContextCapabilities().sync_query) {
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
ri->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
#else
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h
index 7e1fac1bab7..3c823596cba 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h
@@ -8,11 +8,16 @@
#include <stdint.h>
#include "base/macros.h"
+#include "base/sequenced_task_runner.h"
#include "cc/raster/raster_buffer_provider.h"
#include "cc/raster/staging_buffer_pool.h"
#include "cc/resources/layer_tree_resource_provider.h"
#include "gpu/command_buffer/common/sync_token.h"
+namespace gpu {
+class GpuMemoryBufferManager;
+}
+
namespace viz {
class ContextProvider;
class RasterContextProvider;
@@ -28,12 +33,12 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
scoped_refptr<base::SequencedTaskRunner> task_runner,
viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
int max_copy_texture_chromium_size,
bool use_partial_raster,
bool use_gpu_memory_buffer_resources,
int max_staging_buffer_usage_in_bytes,
- viz::ResourceFormat preferred_tile_format);
+ viz::ResourceFormat tile_format);
~OneCopyRasterBufferProvider() override;
// Overridden from RasterBufferProvider:
@@ -42,9 +47,9 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
uint64_t resource_content_id,
uint64_t previous_content_id) override;
void Flush() override;
- viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
- bool IsResourceSwizzleRequired(bool must_support_alpha) const override;
- bool IsResourcePremultiplied(bool must_support_alpha) const override;
+ viz::ResourceFormat GetResourceFormat() const override;
+ bool IsResourceSwizzleRequired() const override;
+ bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
const ResourcePool::InUsePoolResource& resource) const override;
@@ -78,7 +83,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
class RasterBufferImpl : public RasterBuffer {
public:
RasterBufferImpl(OneCopyRasterBufferProvider* client,
- LayerTreeResourceProvider* resource_provider,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const ResourcePool::InUsePoolResource& in_use_resource,
OneCopyGpuBacking* backing,
uint64_t previous_content_id);
@@ -142,7 +147,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
viz::ContextProvider* const compositor_context_provider_;
viz::RasterContextProvider* const worker_context_provider_;
- LayerTreeResourceProvider* const resource_provider_;
+ gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_;
const int max_bytes_per_copy_operation_;
const bool use_partial_raster_;
const bool use_gpu_memory_buffer_resources_;
@@ -150,7 +155,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
// Context lock must be acquired when accessing this member.
int bytes_scheduled_since_last_flush_;
- const viz::ResourceFormat preferred_tile_format_;
+ const viz::ResourceFormat tile_format_;
StagingBufferPool staging_pool_;
DISALLOW_COPY_AND_ASSIGN(OneCopyRasterBufferProvider);
diff --git a/chromium/cc/raster/raster_buffer_provider.cc b/chromium/cc/raster/raster_buffer_provider.cc
index 1cef94610f9..873a432e0ef 100644
--- a/chromium/cc/raster/raster_buffer_provider.cc
+++ b/chromium/cc/raster/raster_buffer_provider.cc
@@ -57,6 +57,7 @@ void RasterBufferProvider::PlaybackToMemory(
const gfx::Rect& canvas_playback_rect,
const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& target_color_space,
+ bool gpu_compositing,
const RasterSource::PlaybackSettings& playback_settings) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"RasterBufferProvider::PlaybackToMemory");
@@ -97,8 +98,7 @@ void RasterBufferProvider::PlaybackToMemory(
playback_settings);
return;
}
- case viz::RGBA_4444:
- case viz::ETC1: {
+ case viz::RGBA_4444: {
sk_sp<SkSurface> surface = SkSurface::MakeRaster(info, &surface_props);
// TODO(reveman): Improve partial raster support by reducing the size of
// playback rect passed to PlaybackToCanvas. crbug.com/519070
@@ -122,13 +122,14 @@ void RasterBufferProvider::PlaybackToMemory(
} else {
TRACE_EVENT0("cc",
"RasterBufferProvider::PlaybackToMemory::ConvertRGBA4444");
- SkImageInfo dst_info =
- info.makeColorType(ResourceFormatToClosestSkColorType(format));
+ SkImageInfo dst_info = info.makeColorType(
+ ResourceFormatToClosestSkColorType(gpu_compositing, format));
bool rv = surface->readPixels(dst_info, memory, stride, 0, 0);
DCHECK(rv);
}
return;
}
+ case viz::ETC1:
case viz::ALPHA_8:
case viz::LUMINANCE_8:
case viz::RGB_565:
@@ -142,27 +143,4 @@ void RasterBufferProvider::PlaybackToMemory(
NOTREACHED();
}
-bool RasterBufferProvider::ResourceFormatRequiresSwizzle(
- viz::ResourceFormat format) {
- switch (format) {
- case viz::RGBA_8888:
- case viz::BGRA_8888:
- // Initialize resource using the preferred viz::PlatformColor component
- // order and swizzle in the shader instead of in software.
- return !viz::PlatformColor::SameComponentOrder(format);
- case viz::RGBA_4444:
- case viz::ETC1:
- case viz::ALPHA_8:
- case viz::LUMINANCE_8:
- case viz::RGB_565:
- case viz::RED_8:
- case viz::LUMINANCE_F16:
- case viz::RGBA_F16:
- case viz::R16_EXT:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
} // namespace cc
diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h
index 12b7e0d80da..3e2b1aaeb50 100644
--- a/chromium/cc/raster/raster_buffer_provider.h
+++ b/chromium/cc/raster/raster_buffer_provider.h
@@ -12,7 +12,6 @@
#include "cc/raster/task_graph_runner.h"
#include "cc/raster/tile_task.h"
#include "cc/resources/resource_pool.h"
-#include "cc/resources/resource_provider.h"
#include "components/viz/common/resources/resource_format.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -31,6 +30,9 @@ class CC_EXPORT RasterBufferProvider {
// that will cover the resulting |memory|. The |canvas_playback_rect| can be a
// smaller contained rect inside the |canvas_bitmap_rect| if the |memory| is
// already partially complete, and only the subrect needs to be played back.
+ // Set |gpu_compositing| to true if the compositor is using gpu, as we respect
+ // the format more accurately, vs in software compositing where the format is
+ // a placeholder for the skia native format.
static void PlaybackToMemory(
void* memory,
viz::ResourceFormat format,
@@ -41,6 +43,7 @@ class CC_EXPORT RasterBufferProvider {
const gfx::Rect& canvas_playback_rect,
const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& target_color_space,
+ bool gpu_compositing,
const RasterSource::PlaybackSettings& playback_settings);
// Acquire raster buffer.
@@ -56,14 +59,13 @@ class CC_EXPORT RasterBufferProvider {
virtual void Flush() = 0;
// Returns the format to use for the tiles.
- virtual viz::ResourceFormat GetResourceFormat(
- bool must_support_alpha) const = 0;
+ virtual viz::ResourceFormat GetResourceFormat() const = 0;
// Determine if the resource requires swizzling.
- virtual bool IsResourceSwizzleRequired(bool must_support_alpha) const = 0;
+ virtual bool IsResourceSwizzleRequired() const = 0;
// Determines if the resource is premultiplied.
- virtual bool IsResourcePremultiplied(bool must_support_alpha) const = 0;
+ virtual bool IsResourcePremultiplied() const = 0;
// Determine if the RasterBufferProvider can handle partial raster into
// the Resource provided in AcquireBufferForRaster.
@@ -86,10 +88,6 @@ class CC_EXPORT RasterBufferProvider {
// Shutdown for doing cleanup.
virtual void Shutdown() = 0;
-
- protected:
- // Check if resource format matches output format.
- static bool ResourceFormatRequiresSwizzle(viz::ResourceFormat format);
};
} // namespace cc
diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc
index 4d96efeb552..a91d3bef29d 100644
--- a/chromium/cc/raster/raster_buffer_provider_perftest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc
@@ -16,8 +16,8 @@
#include "cc/raster/raster_buffer_provider.h"
#include "cc/raster/synchronous_task_graph_runner.h"
#include "cc/raster/zero_copy_raster_buffer_provider.h"
+#include "cc/resources/layer_tree_resource_provider.h"
#include "cc/resources/resource_pool.h"
-#include "cc/resources/resource_provider.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
#include "cc/test/fake_resource_provider.h"
#include "cc/tiles/tile_task_manager.h"
@@ -87,7 +87,7 @@ class PerfContextProvider
capabilities_.sync_query = true;
raster_context_ = std::make_unique<gpu::raster::RasterImplementationGLES>(
- context_gl_.get(), &support_, capabilities_);
+ context_gl_.get(), nullptr, capabilities_);
}
// viz::ContextProvider implementation.
@@ -350,51 +350,34 @@ class RasterBufferProviderPerfTest
Create3dResourceProvider();
raster_buffer_provider_ =
std::make_unique<ZeroCopyRasterBufferProvider>(
- resource_provider_.get(), &gpu_memory_buffer_manager_,
- compositor_context_provider_.get(),
- viz::PlatformColor::BestTextureFormat());
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- false);
+ &gpu_memory_buffer_manager_, compositor_context_provider_.get(),
+ viz::RGBA_8888);
break;
case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<OneCopyRasterBufferProvider>(
task_runner_.get(), compositor_context_provider_.get(),
- worker_context_provider_.get(), resource_provider_.get(),
+ worker_context_provider_.get(), &gpu_memory_buffer_manager_,
std::numeric_limits<int>::max(), false, false,
- std::numeric_limits<int>::max(),
- viz::PlatformColor::BestTextureFormat());
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- false);
+ std::numeric_limits<int>::max(), viz::RGBA_8888);
break;
case RASTER_BUFFER_PROVIDER_TYPE_GPU:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
compositor_context_provider_.get(), worker_context_provider_.get(),
- resource_provider_.get(), false, 0,
- viz::PlatformColor::BestTextureFormat(), gfx::Size(), true, false);
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- false);
+ false, 0, viz::RGBA_8888, gfx::Size(), true, false);
break;
case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
CreateSoftwareResourceProvider();
raster_buffer_provider_ = std::make_unique<BitmapRasterBufferProvider>(
layer_tree_frame_sink_.get());
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay,
- ResourcePool::Mode::kSoftware, false);
break;
}
-
DCHECK(raster_buffer_provider_);
+ resource_pool_ = std::make_unique<ResourcePool>(
+ resource_provider_.get(), compositor_context_provider_.get(),
+ task_runner_, ResourcePool::kDefaultExpirationDelay, false);
tile_task_manager_ = TileTaskManagerImpl::Create(task_graph_runner_.get());
}
void TearDown() override {
@@ -519,14 +502,13 @@ class RasterBufferProviderPerfTest
private:
void Create3dResourceProvider() {
resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- compositor_context_provider_.get(), nullptr,
- &gpu_memory_buffer_manager_);
+ compositor_context_provider_.get());
}
void CreateSoftwareResourceProvider() {
layer_tree_frame_sink_ = FakeLayerTreeFrameSink::CreateSoftware();
- resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- nullptr, layer_tree_frame_sink_->shared_bitmap_manager(), nullptr);
+ resource_provider_ =
+ FakeResourceProvider::CreateLayerTreeResourceProvider(nullptr);
}
std::string TestModifierString() const {
@@ -590,10 +572,10 @@ class RasterBufferProviderCommonPerfTest
// Overridden from testing::Test:
void SetUp() override {
resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- compositor_context_provider_.get(), nullptr);
+ compositor_context_provider_.get());
resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu, false);
+ resource_provider_.get(), compositor_context_provider_.get(),
+ task_runner_, ResourcePool::kDefaultExpirationDelay, false);
}
void RunBuildTileTaskGraphTest(const std::string& test_name,
diff --git a/chromium/cc/raster/raster_buffer_provider_unittest.cc b/chromium/cc/raster/raster_buffer_provider_unittest.cc
index 4bc78099834..c50e739199c 100644
--- a/chromium/cc/raster/raster_buffer_provider_unittest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_unittest.cc
@@ -14,7 +14,6 @@
#include "base/cancelable_callback.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -25,8 +24,8 @@
#include "cc/raster/one_copy_raster_buffer_provider.h"
#include "cc/raster/synchronous_task_graph_runner.h"
#include "cc/raster/zero_copy_raster_buffer_provider.h"
+#include "cc/resources/layer_tree_resource_provider.h"
#include "cc/resources/resource_pool.h"
-#include "cc/resources/resource_provider.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
#include "cc/test/fake_raster_source.h"
#include "cc/test/fake_resource_provider.h"
@@ -34,7 +33,6 @@
#include "components/viz/common/resources/platform_color.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gpu_memory_buffer_manager.h"
-#include "components/viz/test/test_shared_bitmap_manager.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
@@ -158,46 +156,35 @@ class RasterBufferProviderTest
Create3dResourceProvider();
raster_buffer_provider_ =
std::make_unique<ZeroCopyRasterBufferProvider>(
- resource_provider_.get(), &gpu_memory_buffer_manager_,
- context_provider_.get(),
- viz::PlatformColor::BestTextureFormat());
- pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::TimeDelta(), ResourcePool::Mode::kGpu, true);
+ &gpu_memory_buffer_manager_, context_provider_.get(),
+ viz::RGBA_8888);
break;
case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<OneCopyRasterBufferProvider>(
base::ThreadTaskRunnerHandle::Get().get(), context_provider_.get(),
- worker_context_provider_.get(), resource_provider_.get(),
+ worker_context_provider_.get(), &gpu_memory_buffer_manager_,
kMaxBytesPerCopyOperation, false, false, kMaxStagingBuffers,
- viz::PlatformColor::BestTextureFormat());
- pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::TimeDelta(), ResourcePool::Mode::kGpu, true);
+ viz::RGBA_8888);
break;
case RASTER_BUFFER_PROVIDER_TYPE_GPU:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
- context_provider_.get(), worker_context_provider_.get(),
- resource_provider_.get(), false, 0,
- viz::PlatformColor::BestTextureFormat(), gfx::Size(), true, false);
- pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::TimeDelta(), ResourcePool::Mode::kGpu, true);
+ context_provider_.get(), worker_context_provider_.get(), false, 0,
+ viz::RGBA_8888, gfx::Size(), true, false);
break;
case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
CreateSoftwareResourceProvider();
raster_buffer_provider_ = std::make_unique<BitmapRasterBufferProvider>(
layer_tree_frame_sink_.get());
- pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::TimeDelta(), ResourcePool::Mode::kSoftware, true);
break;
}
DCHECK(raster_buffer_provider_);
+ pool_ = std::make_unique<ResourcePool>(
+ resource_provider_.get(), context_provider_.get(),
+ base::ThreadTaskRunnerHandle::Get(), base::TimeDelta(), true);
tile_task_manager_ = TileTaskManagerImpl::Create(&task_graph_runner_);
}
@@ -305,22 +292,20 @@ class RasterBufferProviderTest
private:
void Create3dResourceProvider() {
- context_provider_ = viz::TestContextProvider::Create();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_support_sync_query(true);
+ context_provider_ = viz::TestContextProvider::Create(std::move(gl_owned));
context_provider_->BindToCurrentThread();
worker_context_provider_ = viz::TestContextProvider::CreateWorker();
- viz::TestWebGraphicsContext3D* context3d =
- context_provider_->TestContext3d();
- context3d->set_support_sync_query(true);
layer_tree_frame_sink_ = FakeLayerTreeFrameSink::Create3d();
resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- context_provider_.get(), &shared_bitmap_manager_,
- &gpu_memory_buffer_manager_);
+ context_provider_.get());
}
void CreateSoftwareResourceProvider() {
layer_tree_frame_sink_ = FakeLayerTreeFrameSink::CreateSoftware();
- resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- nullptr, &shared_bitmap_manager_, &gpu_memory_buffer_manager_);
+ resource_provider_ =
+ FakeResourceProvider::CreateLayerTreeResourceProvider(nullptr);
}
void OnTimeout() {
@@ -337,7 +322,6 @@ class RasterBufferProviderTest
std::unique_ptr<TileTaskManager> tile_task_manager_;
std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
viz::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
- viz::TestSharedBitmapManager shared_bitmap_manager_;
SynchronousTaskGraphRunner task_graph_runner_;
base::CancelableClosure timeout_;
UniqueNotifier all_tile_tasks_finished_;
diff --git a/chromium/cc/raster/staging_buffer_pool.cc b/chromium/cc/raster/staging_buffer_pool.cc
index 37c39fc4102..0ac04f79693 100644
--- a/chromium/cc/raster/staging_buffer_pool.cc
+++ b/chromium/cc/raster/staging_buffer_pool.cc
@@ -14,6 +14,8 @@
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "gpu/command_buffer/client/raster_interface.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/gpu_memory_buffer.h"
using base::trace_event::MemoryAllocatorDump;
@@ -129,12 +131,10 @@ void StagingBuffer::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
StagingBufferPool::StagingBufferPool(
scoped_refptr<base::SequencedTaskRunner> task_runner,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
bool use_partial_raster,
int max_staging_buffer_usage_in_bytes)
: task_runner_(std::move(task_runner)),
worker_context_provider_(worker_context_provider),
- resource_provider_(resource_provider),
use_partial_raster_(use_partial_raster),
max_staging_buffer_usage_in_bytes_(max_staging_buffer_usage_in_bytes),
staging_buffer_usage_in_bytes_(0),
@@ -260,7 +260,7 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
DCHECK(ri);
// Check if any busy buffers have become available.
- if (resource_provider_->use_sync_query()) {
+ if (worker_context_provider_->ContextCapabilities().sync_query) {
while (!busy_buffers_.empty()) {
if (!CheckForQueryResult(ri, busy_buffers_.front()->query_id))
break;
@@ -278,7 +278,7 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
if (busy_buffers_.empty())
break;
- if (resource_provider_->use_sync_query()) {
+ if (worker_context_provider_->ContextCapabilities().sync_query) {
WaitForQueryResult(ri, busy_buffers_.front()->query_id);
MarkStagingBufferAsFree(busy_buffers_.front().get());
free_buffers_.push_back(PopFront(&busy_buffers_));
diff --git a/chromium/cc/raster/staging_buffer_pool.h b/chromium/cc/raster/staging_buffer_pool.h
index 559657f8aaa..460a3bbe843 100644
--- a/chromium/cc/raster/staging_buffer_pool.h
+++ b/chromium/cc/raster/staging_buffer_pool.h
@@ -14,12 +14,19 @@
#include "base/macros.h"
#include "base/memory/memory_coordinator_client.h"
#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/trace_event.h"
-#include "cc/resources/layer_tree_resource_provider.h"
+#include "cc/cc_export.h"
+#include "components/viz/common/resources/resource_format.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+namespace gfx {
+class GpuMemoryBuffer;
+}
namespace gpu {
namespace raster {
class RasterInterface;
@@ -59,7 +66,6 @@ class CC_EXPORT StagingBufferPool
StagingBufferPool(scoped_refptr<base::SequencedTaskRunner> task_runner,
viz::RasterContextProvider* worker_context_provider,
- LayerTreeResourceProvider* resource_provider,
bool use_partial_raster,
int max_staging_buffer_usage_in_bytes);
void Shutdown();
@@ -96,7 +102,6 @@ class CC_EXPORT StagingBufferPool
scoped_refptr<base::SequencedTaskRunner> task_runner_;
viz::RasterContextProvider* const worker_context_provider_;
- LayerTreeResourceProvider* const resource_provider_;
const bool use_partial_raster_;
mutable base::Lock lock_;
diff --git a/chromium/cc/raster/staging_buffer_pool_unittest.cc b/chromium/cc/raster/staging_buffer_pool_unittest.cc
index 51e3f7c56fa..7c7c79aec61 100644
--- a/chromium/cc/raster/staging_buffer_pool_unittest.cc
+++ b/chromium/cc/raster/staging_buffer_pool_unittest.cc
@@ -16,14 +16,13 @@ namespace cc {
TEST(StagingBufferPoolTest, ShutdownImmediatelyAfterCreation) {
auto context_provider = viz::TestContextProvider::CreateWorker();
- LayerTreeResourceProvider* resource_provider = nullptr;
bool use_partial_raster = false;
int max_staging_buffer_usage_in_bytes = 1024;
auto task_runner = base::ThreadTaskRunnerHandle::Get();
// Create a StagingBufferPool and immediately shut it down.
auto pool = std::make_unique<StagingBufferPool>(
- task_runner.get(), context_provider.get(), resource_provider,
- use_partial_raster, max_staging_buffer_usage_in_bytes);
+ task_runner.get(), context_provider.get(), use_partial_raster,
+ max_staging_buffer_usage_in_bytes);
pool->Shutdown();
// Flush the message loop.
auto flush_message_loop = [] {
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
index 9cefe8af99b..fd2bb2118c8 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -183,7 +183,8 @@ class ZeroCopyRasterBufferImpl : public RasterBuffer {
RasterBufferProvider::PlaybackToMemory(
gpu_memory_buffer_->memory(0), resource_format_, resource_size_,
gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
- raster_full_rect, transform, resource_color_space_, playback_settings);
+ raster_full_rect, transform, resource_color_space_,
+ /*gpu_compositing=*/true, playback_settings);
gpu_memory_buffer_->Unmap();
}
@@ -204,14 +205,12 @@ class ZeroCopyRasterBufferImpl : public RasterBuffer {
} // namespace
ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
- LayerTreeResourceProvider* resource_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
viz::ContextProvider* compositor_context_provider,
- viz::ResourceFormat preferred_tile_format)
- : resource_provider_(resource_provider),
- gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
+ viz::ResourceFormat tile_format)
+ : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
compositor_context_provider_(compositor_context_provider),
- preferred_tile_format_(preferred_tile_format) {}
+ tile_format_(tile_format) {}
ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
@@ -235,24 +234,15 @@ ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
void ZeroCopyRasterBufferProvider::Flush() {}
-viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat(
- bool must_support_alpha) const {
- if (resource_provider_->IsTextureFormatSupported(preferred_tile_format_)) {
- if (!must_support_alpha)
- return preferred_tile_format_;
- if (DoesResourceFormatSupportAlpha(preferred_tile_format_))
- return preferred_tile_format_;
- }
- return resource_provider_->best_texture_format();
+viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat() const {
+ return tile_format_;
}
-bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired(
- bool must_support_alpha) const {
- return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
+ return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
}
-bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied(
- bool must_support_alpha) const {
+bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
return true;
}
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.h b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
index d7a118e2988..68f78bfb2c7 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
@@ -23,15 +23,13 @@ class GpuMemoryBufferManager;
}
namespace cc {
-class LayerTreeResourceProvider;
class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
public:
ZeroCopyRasterBufferProvider(
- LayerTreeResourceProvider* resource_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
viz::ContextProvider* compositor_context_provider,
- viz::ResourceFormat preferred_tile_format);
+ viz::ResourceFormat tile_format);
~ZeroCopyRasterBufferProvider() override;
// Overridden from RasterBufferProvider:
@@ -40,9 +38,9 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
uint64_t resource_content_id,
uint64_t previous_content_id) override;
void Flush() override;
- viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
- bool IsResourceSwizzleRequired(bool must_support_alpha) const override;
- bool IsResourcePremultiplied(bool must_support_alpha) const override;
+ viz::ResourceFormat GetResourceFormat() const override;
+ bool IsResourceSwizzleRequired() const override;
+ bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
const ResourcePool::InUsePoolResource& resource) const override;
@@ -56,10 +54,9 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
const;
- LayerTreeResourceProvider* resource_provider_;
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
viz::ContextProvider* compositor_context_provider_;
- viz::ResourceFormat preferred_tile_format_;
+ viz::ResourceFormat tile_format_;
DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferProvider);
};
diff --git a/chromium/cc/resources/display_resource_provider.cc b/chromium/cc/resources/display_resource_provider.cc
deleted file mode 100644
index c48d3ff6768..00000000000
--- a/chromium/cc/resources/display_resource_provider.cc
+++ /dev/null
@@ -1,829 +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/resources/display_resource_provider.h"
-
-#include "base/trace_event/trace_event.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/skia/include/gpu/GrBackendSurface.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-static GLint GetActiveTextureUnit(GLES2Interface* gl) {
- GLint active_unit = 0;
- gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
- return active_unit;
-}
-
-class ScopedSetActiveTexture {
- public:
- ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
- : gl_(gl), unit_(unit) {
- DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
-
- if (unit_ != GL_TEXTURE0)
- gl_->ActiveTexture(unit_);
- }
-
- ~ScopedSetActiveTexture() {
- // Active unit being GL_TEXTURE0 is effectively the ground state.
- if (unit_ != GL_TEXTURE0)
- gl_->ActiveTexture(GL_TEXTURE0);
- }
-
- private:
- GLES2Interface* gl_;
- GLenum unit_;
-};
-
-namespace {
-// The resource id in DisplayResourceProvider starts from 2 to avoid
-// conflicts with id from LayerTreeResourceProvider.
-const unsigned int kDisplayInitialResourceId = 2;
-} // namespace
-
-DisplayResourceProvider::DisplayResourceProvider(
- viz::ContextProvider* compositor_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager)
- : ResourceProvider(compositor_context_provider),
- next_id_(kDisplayInitialResourceId),
- shared_bitmap_manager_(shared_bitmap_manager) {}
-
-DisplayResourceProvider::~DisplayResourceProvider() {
- while (!children_.empty())
- DestroyChildInternal(children_.begin(), FOR_SHUTDOWN);
-
- GLES2Interface* gl = ContextGL();
- if (gl)
- gl->Finish();
-}
-
-#if defined(OS_ANDROID)
-void DisplayResourceProvider::SendPromotionHints(
- const OverlayCandidateList::PromotionHintInfoMap& promotion_hints) {
- GLES2Interface* gl = ContextGL();
- if (!gl)
- return;
-
- for (const auto& id : wants_promotion_hints_set_) {
- const ResourceMap::iterator it = resources_.find(id);
- if (it == resources_.end())
- continue;
-
- if (it->second.marked_for_deletion)
- continue;
-
- const viz::internal::Resource* resource = LockForRead(id);
- // TODO(ericrk): We should never fail LockForRead, but we appear to be
- // doing so on Android in rare cases. Handle this gracefully until a better
- // solution can be found. https://crbug.com/811858
- if (!resource)
- return;
-
- DCHECK(resource->wants_promotion_hint);
-
- // Insist that this is backed by a GPU texture.
- if (resource->is_gpu_resource_type()) {
- DCHECK(resource->gl_id);
- auto iter = promotion_hints.find(id);
- bool promotable = iter != promotion_hints.end();
- gl->OverlayPromotionHintCHROMIUM(resource->gl_id, promotable,
- promotable ? iter->second.x() : 0,
- promotable ? iter->second.y() : 0,
- promotable ? iter->second.width() : 0,
- promotable ? iter->second.height() : 0);
- }
- UnlockForRead(id);
- }
-}
-
-void DisplayResourceProvider::DeletePromotionHint(ResourceMap::iterator it,
- DeleteStyle style) {
- viz::internal::Resource* resource = &it->second;
- // If this resource was interested in promotion hints, then remove it from
- // the set of resources that we'll notify.
- if (resource->wants_promotion_hint)
- wants_promotion_hints_set_.erase(it->first);
-}
-
-bool DisplayResourceProvider::IsBackedBySurfaceTexture(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- return resource->is_backed_by_surface_texture;
-}
-
-bool DisplayResourceProvider::WantsPromotionHintForTesting(viz::ResourceId id) {
- return wants_promotion_hints_set_.count(id) > 0;
-}
-
-size_t DisplayResourceProvider::CountPromotionHintRequestsForTesting() {
- return wants_promotion_hints_set_.size();
-}
-
-#endif
-bool DisplayResourceProvider::IsOverlayCandidate(viz::ResourceId id) {
- viz::internal::Resource* resource = TryGetResource(id);
- // TODO(ericrk): We should never fail TryGetResource, but we appear to
- // be doing so on Android in rare cases. Handle this gracefully until a
- // better solution can be found. https://crbug.com/811858
- return resource && resource->is_overlay_candidate;
-}
-
-viz::ResourceType DisplayResourceProvider::GetResourceType(viz::ResourceId id) {
- return GetResource(id)->type;
-}
-
-gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- return resource->buffer_format;
-}
-
-void DisplayResourceProvider::WaitSyncToken(viz::ResourceId id) {
- viz::internal::Resource* resource = TryGetResource(id);
- // TODO(ericrk): We should never fail TryGetResource, but we appear to
- // be doing so on Android in rare cases. Handle this gracefully until a
- // better solution can be found. https://crbug.com/811858
- if (!resource)
- return;
- WaitSyncTokenInternal(resource);
-#if defined(OS_ANDROID)
- // Now that the resource is synced, we may send it a promotion hint. We could
- // sync all |wants_promotion_hint| resources elsewhere, and send 'no' to all
- // resources that weren't used. However, there's no real advantage.
- if (resource->wants_promotion_hint)
- wants_promotion_hints_set_.insert(id);
-#endif // OS_ANDROID
-}
-
-DisplayResourceProvider::ScopedBatchReturnResources::ScopedBatchReturnResources(
- DisplayResourceProvider* resource_provider)
- : resource_provider_(resource_provider) {
- resource_provider_->SetBatchReturnResources(true);
-}
-
-DisplayResourceProvider::ScopedBatchReturnResources::
- ~ScopedBatchReturnResources() {
- resource_provider_->SetBatchReturnResources(false);
-}
-
-void DisplayResourceProvider::SetBatchReturnResources(bool batch) {
- DCHECK_NE(batch_return_resources_, batch);
- batch_return_resources_ = batch;
- if (!batch) {
- for (const auto& resources : batched_returning_resources_) {
- ChildMap::iterator child_it = children_.find(resources.first);
- DCHECK(child_it != children_.end());
- DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, resources.second);
- }
- batched_returning_resources_.clear();
- }
-}
-
-DisplayResourceProvider::Child::Child()
- : marked_for_deletion(false), needs_sync_tokens(true) {}
-
-DisplayResourceProvider::Child::Child(const Child& other) = default;
-
-DisplayResourceProvider::Child::~Child() = default;
-
-int DisplayResourceProvider::CreateChild(
- const ReturnCallback& return_callback) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- Child child_info;
- child_info.return_callback = return_callback;
-
- int child = next_child_++;
- children_[child] = child_info;
- return child;
-}
-
-void DisplayResourceProvider::SetChildNeedsSyncTokens(int child_id,
- bool needs) {
- ChildMap::iterator it = children_.find(child_id);
- DCHECK(it != children_.end());
- it->second.needs_sync_tokens = needs;
-}
-
-void DisplayResourceProvider::DestroyChild(int child_id) {
- ChildMap::iterator it = children_.find(child_id);
- DCHECK(it != children_.end());
- DestroyChildInternal(it, NORMAL);
-}
-
-void DisplayResourceProvider::DestroyChildInternal(ChildMap::iterator it,
- DeleteStyle style) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- Child& child = it->second;
- DCHECK(style == FOR_SHUTDOWN || !child.marked_for_deletion);
-
- ResourceIdArray resources_for_child;
-
- for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin();
- child_it != child.child_to_parent_map.end(); ++child_it) {
- viz::ResourceId id = child_it->second;
- resources_for_child.push_back(id);
- }
-
- child.marked_for_deletion = true;
-
- DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
-}
-
-void DisplayResourceProvider::DeleteAndReturnUnusedResourcesToChild(
- ChildMap::iterator child_it,
- DeleteStyle style,
- const ResourceIdArray& unused) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(child_it != children_.end());
- Child* child_info = &child_it->second;
-
- if (unused.empty() && !child_info->marked_for_deletion)
- return;
-
- std::vector<viz::ReturnedResource> to_return;
- to_return.reserve(unused.size());
- std::vector<viz::ReturnedResource*> need_synchronization_resources;
- std::vector<GLbyte*> unverified_sync_tokens;
- std::vector<size_t> to_return_indices_unverified;
-
- GLES2Interface* gl = ContextGL();
-
- for (viz::ResourceId local_id : unused) {
- ResourceMap::iterator it = resources_.find(local_id);
- CHECK(it != resources_.end());
- viz::internal::Resource& resource = it->second;
-
- // TODO(xing.xu): remove locked_for_write.
- DCHECK(!resource.locked_for_write);
-
- viz::ResourceId child_id = resource.id_in_child;
- DCHECK(child_info->child_to_parent_map.count(child_id));
-
- bool is_lost = resource.lost ||
- (resource.is_gpu_resource_type() && lost_context_provider_);
- if (resource.exported_count > 0 || resource.lock_for_read_count > 0 ||
- resource.locked_for_external_use) {
- if (style != FOR_SHUTDOWN) {
- // Defer this resource deletion.
- resource.marked_for_deletion = true;
- continue;
- }
- // We can't postpone the deletion, so we'll have to lose it.
- is_lost = true;
- } else if (!ReadLockFenceHasPassed(&resource)) {
- // TODO(dcastagna): see if it's possible to use this logic for
- // the branch above too, where the resource is locked or still exported.
- if (style != FOR_SHUTDOWN && !child_info->marked_for_deletion) {
- // Defer this resource deletion.
- resource.marked_for_deletion = true;
- continue;
- }
- // We can't postpone the deletion, so we'll have to lose it.
- is_lost = true;
- }
-
- if (resource.is_gpu_resource_type() &&
- resource.filter != resource.original_filter) {
- DCHECK(resource.target);
- DCHECK(resource.gl_id);
- DCHECK(gl);
- gl->BindTexture(resource.target, resource.gl_id);
- gl->TexParameteri(resource.target, GL_TEXTURE_MIN_FILTER,
- resource.original_filter);
- gl->TexParameteri(resource.target, GL_TEXTURE_MAG_FILTER,
- resource.original_filter);
- resource.SetLocallyUsed();
- }
-
- viz::ReturnedResource returned;
- returned.id = child_id;
- returned.sync_token = resource.sync_token();
- returned.count = resource.imported_count;
- returned.lost = is_lost;
- to_return.push_back(returned);
-
- if (resource.is_gpu_resource_type() && child_info->needs_sync_tokens) {
- if (resource.needs_sync_token()) {
- need_synchronization_resources.push_back(&to_return.back());
- } else if (returned.sync_token.HasData() &&
- !returned.sync_token.verified_flush()) {
- // Before returning any sync tokens, they must be verified. Store an
- // index into |to_return| instead of a pointer as vectors may realloc
- // and move their data.
- to_return_indices_unverified.push_back(to_return.size() - 1);
- }
- }
-
- child_info->child_to_parent_map.erase(child_id);
- resource.imported_count = 0;
-#if defined(OS_ANDROID)
- DeletePromotionHint(it, style);
-#endif
- DeleteResourceInternal(it, style);
- }
-
- for (size_t i : to_return_indices_unverified)
- unverified_sync_tokens.push_back(to_return[i].sync_token.GetData());
-
- gpu::SyncToken new_sync_token;
- if (!need_synchronization_resources.empty()) {
- DCHECK(child_info->needs_sync_tokens);
- DCHECK(gl);
- gl->GenUnverifiedSyncTokenCHROMIUM(new_sync_token.GetData());
- unverified_sync_tokens.push_back(new_sync_token.GetData());
- }
-
- if (!unverified_sync_tokens.empty()) {
- DCHECK(child_info->needs_sync_tokens);
- DCHECK(gl);
- gl->VerifySyncTokensCHROMIUM(unverified_sync_tokens.data(),
- unverified_sync_tokens.size());
- }
-
- // Set sync token after verification.
- for (viz::ReturnedResource* returned : need_synchronization_resources)
- returned->sync_token = new_sync_token;
-
- if (!to_return.empty())
- child_info->return_callback.Run(to_return);
-
- if (child_info->marked_for_deletion &&
- child_info->child_to_parent_map.empty()) {
- children_.erase(child_it);
- }
-}
-
-void DisplayResourceProvider::ReceiveFromChild(
- int child,
- const std::vector<viz::TransferableResource>& resources) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- GLES2Interface* gl = ContextGL();
- Child& child_info = children_.find(child)->second;
- DCHECK(!child_info.marked_for_deletion);
- for (std::vector<viz::TransferableResource>::const_iterator it =
- resources.begin();
- it != resources.end(); ++it) {
- ResourceIdMap::iterator resource_in_map_it =
- child_info.child_to_parent_map.find(it->id);
- if (resource_in_map_it != child_info.child_to_parent_map.end()) {
- viz::internal::Resource* resource =
- GetResource(resource_in_map_it->second);
- resource->marked_for_deletion = false;
- resource->imported_count++;
- continue;
- }
-
- if ((!it->is_software && !gl) ||
- (it->is_software && !shared_bitmap_manager_)) {
- TRACE_EVENT0(
- "cc", "DisplayResourceProvider::ReceiveFromChild dropping invalid");
- std::vector<viz::ReturnedResource> to_return;
- to_return.push_back(it->ToReturnedResource());
- child_info.return_callback.Run(to_return);
- continue;
- }
-
- viz::ResourceId local_id = next_id_++;
- viz::internal::Resource* resource = nullptr;
- if (it->is_software) {
- DCHECK(IsBitmapFormatSupported(it->format));
- resource = InsertResource(
- local_id,
- viz::internal::Resource(it->size, viz::internal::Resource::DELEGATED,
- viz::ResourceTextureHint::kDefault,
- viz::ResourceType::kBitmap, it->format,
- it->color_space));
- resource->has_shared_bitmap_id = true;
- resource->shared_bitmap_id = it->mailbox_holder.mailbox;
- } else {
- resource = InsertResource(
- local_id,
- viz::internal::Resource(it->size, viz::internal::Resource::DELEGATED,
- viz::ResourceTextureHint::kDefault,
- viz::ResourceType::kTexture, it->format,
- it->color_space));
- resource->target = it->mailbox_holder.texture_target;
- resource->filter = it->filter;
- resource->original_filter = it->filter;
- resource->min_filter = it->filter;
- resource->buffer_format = it->buffer_format;
- resource->mailbox = it->mailbox_holder.mailbox;
- resource->UpdateSyncToken(it->mailbox_holder.sync_token);
- resource->read_lock_fences_enabled = it->read_lock_fences_enabled;
- resource->is_overlay_candidate = it->is_overlay_candidate;
-#if defined(OS_ANDROID)
- resource->is_backed_by_surface_texture = it->is_backed_by_surface_texture;
- resource->wants_promotion_hint = it->wants_promotion_hint;
-#endif
- }
- resource->child_id = child;
- // Don't allocate a texture for a child.
- resource->allocated = true;
- resource->imported_count = 1;
- resource->id_in_child = it->id;
- child_info.child_to_parent_map[it->id] = local_id;
- }
-}
-
-void DisplayResourceProvider::DeclareUsedResourcesFromChild(
- int child,
- const viz::ResourceIdSet& resources_from_child) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- ChildMap::iterator child_it = children_.find(child);
- DCHECK(child_it != children_.end());
- Child& child_info = child_it->second;
- DCHECK(!child_info.marked_for_deletion);
-
- ResourceIdArray unused;
- for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
- it != child_info.child_to_parent_map.end(); ++it) {
- viz::ResourceId local_id = it->second;
- bool resource_is_in_use = resources_from_child.count(it->first) > 0;
- if (!resource_is_in_use)
- unused.push_back(local_id);
- }
- DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
-}
-
-const ResourceProvider::ResourceIdMap&
-DisplayResourceProvider::GetChildToParentMap(int child) const {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- ChildMap::const_iterator it = children_.find(child);
- DCHECK(it != children_.end());
- DCHECK(!it->second.marked_for_deletion);
- return it->second.child_to_parent_map;
-}
-
-GLenum DisplayResourceProvider::BindForSampling(viz::ResourceId resource_id,
- GLenum unit,
- GLenum filter) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- GLES2Interface* gl = ContextGL();
- ResourceMap::iterator it = resources_.find(resource_id);
- // TODO(ericrk): We should never fail to find resource_id, but we appear to
- // be doing so on Android in rare cases. Handle this gracefully until a
- // better solution can be found. https://crbug.com/811858
- if (it == resources_.end())
- return GL_TEXTURE_2D;
-
- viz::internal::Resource* resource = &it->second;
- DCHECK(resource->lock_for_read_count);
- // TODO(xing.xu): remove locked_for_write.
- DCHECK(!resource->locked_for_write);
-
- ScopedSetActiveTexture scoped_active_tex(gl, unit);
- GLenum target = resource->target;
- gl->BindTexture(target, resource->gl_id);
- GLenum min_filter = filter;
- if (filter == GL_LINEAR) {
- switch (resource->mipmap_state) {
- case viz::internal::Resource::INVALID:
- break;
- case viz::internal::Resource::GENERATE:
- DCHECK(compositor_context_provider_);
- DCHECK(
- compositor_context_provider_->ContextCapabilities().texture_npot);
- gl->GenerateMipmap(target);
- resource->mipmap_state = viz::internal::Resource::VALID;
- FALLTHROUGH;
- case viz::internal::Resource::VALID:
- min_filter = GL_LINEAR_MIPMAP_LINEAR;
- break;
- }
- }
- if (min_filter != resource->min_filter) {
- gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter);
- resource->min_filter = min_filter;
- }
- if (filter != resource->filter) {
- gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
- resource->filter = filter;
- }
-
- return target;
-}
-
-bool DisplayResourceProvider::InUse(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- return resource->lock_for_read_count > 0 || resource->lost ||
- resource->locked_for_external_use;
-}
-
-DisplayResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
- DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- const viz::internal::Resource* resource =
- resource_provider->LockForRead(resource_id);
- // TODO(ericrk): We should never fail LockForRead, but we appear to be
- // doing so on Android in rare cases. Handle this gracefully until a better
- // solution can be found. https://crbug.com/811858
- if (!resource)
- return;
-
- texture_id_ = resource->gl_id;
- target_ = resource->target;
- size_ = resource->size;
- color_space_ = resource->color_space;
-}
-
-const viz::internal::Resource* DisplayResourceProvider::LockForRead(
- viz::ResourceId id) {
- // TODO(ericrk): We should never fail TryGetResource, but we appear to be
- // doing so on Android in rare cases. Handle this gracefully until a better
- // solution can be found. https://crbug.com/811858
- viz::internal::Resource* resource = TryGetResource(id);
- if (!resource)
- return nullptr;
-
- // TODO(xing.xu): remove locked_for_write.
- DCHECK(!resource->locked_for_write)
- << "locked for write: " << resource->locked_for_write;
- DCHECK_EQ(resource->exported_count, 0);
- // Uninitialized! Call SetPixels or LockForWrite first.
- DCHECK(resource->allocated);
-
- // Mailbox sync_tokens must be processed by a call to WaitSyncToken() prior to
- // calling LockForRead().
- DCHECK_NE(viz::internal::Resource::NEEDS_WAIT,
- resource->synchronization_state());
-
- if (resource->is_gpu_resource_type() && !resource->gl_id) {
- DCHECK(resource->origin != viz::internal::Resource::INTERNAL);
- DCHECK(!resource->mailbox.IsZero());
-
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- resource->gl_id =
- gl->CreateAndConsumeTextureCHROMIUM(resource->mailbox.name);
- resource->SetLocallyUsed();
- }
-
- if (!resource->pixels && resource->has_shared_bitmap_id &&
- shared_bitmap_manager_) {
- std::unique_ptr<viz::SharedBitmap> bitmap =
- shared_bitmap_manager_->GetSharedBitmapFromId(
- resource->size, resource->format, resource->shared_bitmap_id);
- if (bitmap) {
- resource->SetSharedBitmap(bitmap.get());
- resource->owned_shared_bitmap = std::move(bitmap);
- }
- }
-
- resource->lock_for_read_count++;
- if (resource->read_lock_fences_enabled) {
- if (current_read_lock_fence_.get())
- current_read_lock_fence_->Set();
- resource->read_lock_fence = current_read_lock_fence_;
- }
-
- return resource;
-}
-
-void DisplayResourceProvider::UnlockForRead(viz::ResourceId id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- ResourceMap::iterator it = resources_.find(id);
- // TODO(ericrk): We should never fail to find id, but we appear to be
- // doing so on Android in rare cases. Handle this gracefully until a better
- // solution can be found. https://crbug.com/811858
- if (it == resources_.end())
- return;
-
- viz::internal::Resource* resource = &it->second;
- DCHECK_GT(resource->lock_for_read_count, 0);
- DCHECK_EQ(resource->exported_count, 0);
- resource->lock_for_read_count--;
- TryReleaseResource(it);
-}
-
-viz::ResourceMetadata DisplayResourceProvider::LockForExternalUse(
- viz::ResourceId id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- ResourceMap::iterator it = resources_.find(id);
- DCHECK(it != resources_.end());
-
- viz::internal::Resource* resource = &it->second;
- viz::ResourceMetadata metadata;
- // TODO(xing.xu): remove locked_for_write.
- DCHECK(!resource->locked_for_write)
- << "locked for write: " << resource->locked_for_write;
- DCHECK_EQ(resource->exported_count, 0);
- // Uninitialized! Call SetPixels or LockForWrite first.
- DCHECK(resource->allocated);
- // Make sure there is no outstanding LockForExternalUse without calling
- // UnlockForExternalUse.
- DCHECK(!resource->locked_for_external_use);
- // TODO(penghuang): support software resource.
- DCHECK(resource->is_gpu_resource_type());
-
- metadata.mailbox = resource->mailbox;
- metadata.backend_format = GrBackendFormat::MakeGL(
- TextureStorageFormat(resource->format), resource->target);
- metadata.size = resource->size;
- metadata.mip_mapped = GrMipMapped::kNo;
- metadata.origin = kTopLeft_GrSurfaceOrigin;
- metadata.color_type = ResourceFormatToClosestSkColorType(resource->format);
- metadata.alpha_type = kPremul_SkAlphaType;
- metadata.color_space = nullptr;
- metadata.sync_token = resource->sync_token();
-
- resource->locked_for_external_use = true;
- return metadata;
-}
-
-void DisplayResourceProvider::UnlockForExternalUse(
- viz::ResourceId id,
- const gpu::SyncToken& sync_token) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- ResourceMap::iterator it = resources_.find(id);
- DCHECK(it != resources_.end());
- DCHECK(sync_token.verified_flush());
-
- viz::internal::Resource* resource = &it->second;
- DCHECK(resource->locked_for_external_use);
- // TODO(penghuang): support software resource.
- DCHECK(resource->is_gpu_resource_type());
-
- // Update the resource sync token to |sync_token|. When the next frame is
- // being composited, the DeclareUsedResourcesFromChild() will be called with
- // resources belong to every child for the next frame. If the resource is not
- // used by the next frame, the resource will be returned to a child which
- // owns it with the |sync_token|. The child is responsible for issuing a
- // WaitSyncToken GL command with the |sync_token| before reusing it.
- resource->UpdateSyncToken(sync_token);
- resource->locked_for_external_use = false;
-
- TryReleaseResource(it);
-}
-
-void DisplayResourceProvider::TryReleaseResource(ResourceMap::iterator it) {
- viz::ResourceId id = it->first;
- viz::internal::Resource* resource = &it->second;
- if (resource->marked_for_deletion && !resource->lock_for_read_count &&
- !resource->locked_for_external_use) {
- if (!resource->child_id) {
- // The resource belongs to this ResourceProvider, so it can be destroyed.
-#if defined(OS_ANDROID)
- DeletePromotionHint(it, NORMAL);
-#endif
- DeleteResourceInternal(it, NORMAL);
- } else {
- if (batch_return_resources_) {
- batched_returning_resources_[resource->child_id].push_back(id);
- } else {
- ChildMap::iterator child_it = children_.find(resource->child_id);
- ResourceIdArray unused;
- unused.push_back(id);
- DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
- }
- }
- }
-}
-
-bool DisplayResourceProvider::ReadLockFenceHasPassed(
- const viz::internal::Resource* resource) {
- return !resource->read_lock_fence || resource->read_lock_fence->HasPassed();
-}
-
-DisplayResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
- resource_provider_->UnlockForRead(resource_id_);
-}
-
-DisplayResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
- DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id,
- GLenum filter)
- : resource_lock_(resource_provider, resource_id),
- unit_(GL_TEXTURE0),
- target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {}
-
-DisplayResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
- DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id,
- GLenum unit,
- GLenum filter)
- : resource_lock_(resource_provider, resource_id),
- unit_(unit),
- target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {}
-
-DisplayResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() = default;
-
-DisplayResourceProvider::ScopedReadLockSkImage::ScopedReadLockSkImage(
- DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- const viz::internal::Resource* resource =
- resource_provider->LockForRead(resource_id);
- DCHECK(resource);
- if (resource_provider_->resource_sk_image_.find(resource_id) !=
- resource_provider_->resource_sk_image_.end()) {
- // Use cached sk_image.
- sk_image_ =
- resource_provider_->resource_sk_image_.find(resource_id)->second;
- } else if (resource->gl_id) {
- GrGLTextureInfo texture_info;
- texture_info.fID = resource->gl_id;
- texture_info.fTarget = resource->target;
- texture_info.fFormat = TextureStorageFormat(resource->format);
- GrBackendTexture backend_texture(resource->size.width(),
- resource->size.height(), GrMipMapped::kNo,
- texture_info);
- sk_image_ = SkImage::MakeFromTexture(
- resource_provider->compositor_context_provider_->GrContext(),
- backend_texture, kTopLeft_GrSurfaceOrigin,
- ResourceFormatToClosestSkColorType(resource->format),
- kPremul_SkAlphaType, nullptr);
- } else if (resource->pixels) {
- SkBitmap sk_bitmap;
- resource_provider->PopulateSkBitmapWithResource(&sk_bitmap, resource);
- sk_bitmap.setImmutable();
- sk_image_ = SkImage::MakeFromBitmap(sk_bitmap);
- } else {
- // During render process shutdown, ~RenderMessageFilter which calls
- // ~HostSharedBitmapClient (which deletes shared bitmaps from child)
- // can race with OnBeginFrameDeadline which draws a frame.
- // In these cases, shared bitmaps (and this read lock) won't be valid.
- // Renderers need to silently handle locks failing until this race
- // is fixed. DCHECK that this is the only case where there are no pixels.
- DCHECK(!resource->shared_bitmap_id.IsZero());
- }
-}
-
-DisplayResourceProvider::ScopedReadLockSkImage::~ScopedReadLockSkImage() {
- resource_provider_->UnlockForRead(resource_id_);
-}
-
-DisplayResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
- DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- const viz::internal::Resource* resource =
- resource_provider->LockForRead(resource_id);
- DCHECK(resource);
- resource_provider->PopulateSkBitmapWithResource(&sk_bitmap_, resource);
-}
-
-DisplayResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
- resource_provider_->UnlockForRead(resource_id_);
-}
-
-DisplayResourceProvider::LockSetForExternalUse::LockSetForExternalUse(
- DisplayResourceProvider* resource_provider)
- : resource_provider_(resource_provider) {}
-
-DisplayResourceProvider::LockSetForExternalUse::~LockSetForExternalUse() {
- DCHECK(resources_.empty());
-}
-
-viz::ResourceMetadata
-DisplayResourceProvider::LockSetForExternalUse::LockResource(
- viz::ResourceId id) {
- DCHECK(std::find(resources_.begin(), resources_.end(), id) ==
- resources_.end());
- resources_.push_back(id);
- return resource_provider_->LockForExternalUse(id);
-}
-
-void DisplayResourceProvider::LockSetForExternalUse::UnlockResources(
- const gpu::SyncToken& sync_token) {
- for (const auto& id : resources_)
- resource_provider_->UnlockForExternalUse(id, sync_token);
- resources_.clear();
-}
-
-DisplayResourceProvider::SynchronousFence::SynchronousFence(
- gpu::gles2::GLES2Interface* gl)
- : gl_(gl), has_synchronized_(true) {}
-
-DisplayResourceProvider::SynchronousFence::~SynchronousFence() = default;
-
-void DisplayResourceProvider::SynchronousFence::Set() {
- has_synchronized_ = false;
-}
-
-bool DisplayResourceProvider::SynchronousFence::HasPassed() {
- if (!has_synchronized_) {
- has_synchronized_ = true;
- Synchronize();
- }
- return true;
-}
-
-void DisplayResourceProvider::SynchronousFence::Wait() {
- HasPassed();
-}
-
-void DisplayResourceProvider::SynchronousFence::Synchronize() {
- TRACE_EVENT0("cc", "DisplayResourceProvider::SynchronousFence::Synchronize");
- gl_->Finish();
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/display_resource_provider.h b/chromium/cc/resources/display_resource_provider.h
deleted file mode 100644
index 5c6baef797e..00000000000
--- a/chromium/cc/resources/display_resource_provider.h
+++ /dev/null
@@ -1,315 +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_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_
-#define CC_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_
-
-#include "build/build_config.h"
-#include "cc/output/overlay_candidate.h"
-#include "cc/resources/resource_provider.h"
-#include "components/viz/common/resources/resource_fence.h"
-#include "components/viz/common/resources/resource_metadata.h"
-
-namespace viz {
-class SharedBitmapManager;
-} // namespace viz
-
-namespace cc {
-
-// This class is not thread-safe and can only be called from the thread it was
-// created on.
-class CC_EXPORT DisplayResourceProvider : public ResourceProvider {
- public:
- DisplayResourceProvider(viz::ContextProvider* compositor_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager);
- ~DisplayResourceProvider() override;
-
-#if defined(OS_ANDROID)
- // Send an overlay promotion hint to all resources that requested it via
- // |wants_promotion_hints_set_|. |promotable_hints| contains all the
- // resources that should be told that they're promotable. Others will be told
- // that they're not promotable right now.
- void SendPromotionHints(
- const OverlayCandidateList::PromotionHintInfoMap& promotion_hints);
-
- // Indicates if this resource is backed by an Android SurfaceTexture, and thus
- // can't really be promoted to an overlay.
- bool IsBackedBySurfaceTexture(viz::ResourceId id);
-
- // Indicates if this resource wants to receive promotion hints.
- bool WantsPromotionHintForTesting(viz::ResourceId id);
-
- // Return the number of resources that request promotion hints.
- size_t CountPromotionHintRequestsForTesting();
-#endif
-
- viz::ResourceType GetResourceType(viz::ResourceId id);
-
- // Return the format of the underlying buffer that can be used for scanout.
- gfx::BufferFormat GetBufferFormat(viz::ResourceId id);
-
- // Indicates if this resource may be used for a hardware overlay plane.
- bool IsOverlayCandidate(viz::ResourceId id);
-
- void WaitSyncToken(viz::ResourceId id);
-
- // Checks whether a resource is in use.
- bool InUse(viz::ResourceId id);
-
- // The following lock classes are part of the DisplayResourceProvider API and
- // are needed to read the resource contents. The user must ensure that they
- // only use GL locks on GL resources, etc, and this is enforced by assertions.
- class CC_EXPORT ScopedReadLockGL {
- public:
- ScopedReadLockGL(DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedReadLockGL();
-
- GLuint texture_id() const { return texture_id_; }
- GLenum target() const { return target_; }
- const gfx::Size& size() const { return size_; }
- const gfx::ColorSpace& color_space() const { return color_space_; }
-
- private:
- DisplayResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
-
- GLuint texture_id_ = 0;
- GLenum target_ = GL_TEXTURE_2D;
- gfx::Size size_;
- gfx::ColorSpace color_space_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL);
- };
-
- class CC_EXPORT ScopedSamplerGL {
- public:
- ScopedSamplerGL(DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id,
- GLenum filter);
- ScopedSamplerGL(DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id,
- GLenum unit,
- GLenum filter);
- ~ScopedSamplerGL();
-
- GLuint texture_id() const { return resource_lock_.texture_id(); }
- GLenum target() const { return target_; }
- const gfx::ColorSpace& color_space() const {
- return resource_lock_.color_space();
- }
-
- private:
- const ScopedReadLockGL resource_lock_;
- const GLenum unit_;
- const GLenum target_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL);
- };
-
- class CC_EXPORT ScopedReadLockSkImage {
- public:
- ScopedReadLockSkImage(DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedReadLockSkImage();
-
- const SkImage* sk_image() const { return sk_image_.get(); }
-
- bool valid() const { return !!sk_image_; }
-
- private:
- DisplayResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
- sk_sp<SkImage> sk_image_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSkImage);
- };
-
- class CC_EXPORT ScopedReadLockSoftware {
- public:
- ScopedReadLockSoftware(DisplayResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedReadLockSoftware();
-
- const SkBitmap* sk_bitmap() const {
- DCHECK(valid());
- return &sk_bitmap_;
- }
-
- bool valid() const { return !!sk_bitmap_.getPixels(); }
-
- private:
- DisplayResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
- SkBitmap sk_bitmap_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware);
- };
-
- // Maintains set of lock for external use.
- class CC_EXPORT LockSetForExternalUse {
- public:
- explicit LockSetForExternalUse(DisplayResourceProvider* resource_provider);
- ~LockSetForExternalUse();
-
- // Lock a resource for external use.
- viz::ResourceMetadata LockResource(viz::ResourceId resource_id);
-
- // Unlock all locked resources with a |sync_token|.
- // See UnlockForExternalUse for the detail. All resources must be unlocked
- // before destroying this class.
- void UnlockResources(const gpu::SyncToken& sync_token);
-
- private:
- DisplayResourceProvider* const resource_provider_;
- std::vector<viz::ResourceId> resources_;
-
- DISALLOW_COPY_AND_ASSIGN(LockSetForExternalUse);
- };
-
- // All resources that are returned to children while an instance of this
- // class exists will be stored and returned when the instance is destroyed.
- class CC_EXPORT ScopedBatchReturnResources {
- public:
- explicit ScopedBatchReturnResources(
- DisplayResourceProvider* resource_provider);
- ~ScopedBatchReturnResources();
-
- private:
- DisplayResourceProvider* const resource_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedBatchReturnResources);
- };
-
- class CC_EXPORT SynchronousFence : public viz::ResourceFence {
- public:
- explicit SynchronousFence(gpu::gles2::GLES2Interface* gl);
-
- // viz::ResourceFence implementation.
- void Set() override;
- bool HasPassed() override;
- void Wait() override;
-
- // Returns true if fence has been set but not yet synchornized.
- bool has_synchronized() const { return has_synchronized_; }
-
- private:
- ~SynchronousFence() override;
-
- void Synchronize();
-
- gpu::gles2::GLES2Interface* gl_;
- bool has_synchronized_;
-
- DISALLOW_COPY_AND_ASSIGN(SynchronousFence);
- };
-
- // Sets the current read fence. If a resource is locked for read
- // and has read fences enabled, the resource will not allow writes
- // until this fence has passed.
- void SetReadLockFence(viz::ResourceFence* fence) {
- current_read_lock_fence_ = fence;
- }
-
- // Creates accounting for a child. Returns a child ID.
- int CreateChild(const ReturnCallback& return_callback);
-
- // Destroys accounting for the child, deleting all accounted resources.
- void DestroyChild(int child);
-
- // Sets whether resources need sync points set on them when returned to this
- // child. Defaults to true.
- void SetChildNeedsSyncTokens(int child, bool needs_sync_tokens);
-
- // Gets the child->parent resource ID map.
- const ResourceIdMap& GetChildToParentMap(int child) const;
-
- // Receives resources from a child, moving them from mailboxes. ResourceIds
- // passed are in the child namespace, and will be translated to the parent
- // namespace, added to the child->parent map.
- // This adds the resources to the working set in the ResourceProvider without
- // declaring which resources are in use. Use DeclareUsedResourcesFromChild
- // after calling this method to do that. All calls to ReceiveFromChild should
- // be followed by a DeclareUsedResourcesFromChild.
- // NOTE: if the sync_token is set on any viz::TransferableResource, this will
- // wait on it.
- void ReceiveFromChild(
- int child,
- const std::vector<viz::TransferableResource>& transferable_resources);
-
- // Once a set of resources have been received, they may or may not be used.
- // This declares what set of resources are currently in use from the child,
- // releasing any other resources back to the child.
- void DeclareUsedResourcesFromChild(
- int child,
- const viz::ResourceIdSet& resources_from_child);
-
- private:
- const viz::internal::Resource* LockForRead(viz::ResourceId id);
- void UnlockForRead(viz::ResourceId id);
-
- // Lock a resource for external use.
- viz::ResourceMetadata LockForExternalUse(viz::ResourceId id);
-
- // Unlock a resource which locked by LockForExternalUse.
- // The |sync_token| should be waited on before reusing the resouce's backing
- // to ensure that any external use of it is completed. This |sync_token|
- // should have been verified.
- void UnlockForExternalUse(viz::ResourceId id,
- const gpu::SyncToken& sync_token);
-
- void TryReleaseResource(ResourceMap::iterator it);
- // Binds the given GL resource to a texture target for sampling using the
- // specified filter for both minification and magnification. Returns the
- // texture target used. The resource must be locked for reading.
- GLenum BindForSampling(viz::ResourceId resource_id,
- GLenum unit,
- GLenum filter);
- bool ReadLockFenceHasPassed(const viz::internal::Resource* resource);
-#if defined(OS_ANDROID)
- void DeletePromotionHint(ResourceMap::iterator it, DeleteStyle style);
-#endif
-
- struct Child {
- Child();
- Child(const Child& other);
- ~Child();
-
- ResourceIdMap child_to_parent_map;
- ReturnCallback return_callback;
- bool marked_for_deletion;
- bool needs_sync_tokens;
- };
- using ChildMap = std::unordered_map<int, Child>;
-
- void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it,
- DeleteStyle style,
- const ResourceIdArray& unused);
- void DestroyChildInternal(ChildMap::iterator it, DeleteStyle style);
-
- void SetBatchReturnResources(bool aggregate);
-
- scoped_refptr<viz::ResourceFence> current_read_lock_fence_;
- ChildMap children_;
- // Used as child id when creating a child.
- int next_child_ = 1;
- base::flat_map<viz::ResourceId, sk_sp<SkImage>> resource_sk_image_;
- viz::ResourceId next_id_;
- viz::SharedBitmapManager* shared_bitmap_manager_;
- // Keep track of whether deleted resources should be batched up or returned
- // immediately.
- bool batch_return_resources_ = false;
- // Maps from a child id to the set of resources to be returned to it.
- base::small_map<std::map<int, ResourceIdArray>> batched_returning_resources_;
-#if defined(OS_ANDROID)
- // Set of ResourceIds that would like to be notified about promotion hints.
- viz::ResourceIdSet wants_promotion_hints_set_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(DisplayResourceProvider);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_
diff --git a/chromium/cc/resources/display_resource_provider_unittest.cc b/chromium/cc/resources/display_resource_provider_unittest.cc
deleted file mode 100644
index b8e3e5647bd..00000000000
--- a/chromium/cc/resources/display_resource_provider_unittest.cc
+++ /dev/null
@@ -1,548 +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/resources/display_resource_provider.h"
-#include "cc/resources/layer_tree_resource_provider.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/resource_provider_test_utils.h"
-#include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "components/viz/test/test_context_provider.h"
-#include "components/viz/test/test_gpu_memory_buffer_manager.h"
-#include "components/viz/test/test_shared_bitmap_manager.h"
-#include "components/viz/test/test_texture.h"
-#include "components/viz/test/test_web_graphics_context_3d.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace cc {
-namespace {
-
-static const bool kUseGpuMemoryBufferResources = false;
-
-MATCHER_P(MatchesSyncToken, sync_token, "") {
- gpu::SyncToken other;
- memcpy(&other, arg, sizeof(other));
- return other == sync_token;
-}
-
-static void ReleaseSharedBitmapCallback(
- std::unique_ptr<viz::SharedBitmap> shared_bitmap,
- bool* release_called,
- gpu::SyncToken* release_sync_token,
- bool* lost_resource_result,
- const gpu::SyncToken& sync_token,
- bool lost_resource) {
- *release_called = true;
- *release_sync_token = sync_token;
- *lost_resource_result = lost_resource;
-}
-
-static std::unique_ptr<viz::SharedBitmap> CreateAndFillSharedBitmap(
- viz::SharedBitmapManager* manager,
- const gfx::Size& size,
- viz::ResourceFormat format,
- uint32_t value) {
- std::unique_ptr<viz::SharedBitmap> shared_bitmap =
- manager->AllocateSharedBitmap(size, format);
- CHECK(shared_bitmap);
- uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels());
- CHECK(pixels);
- std::fill_n(pixels, size.GetArea(), value);
- return shared_bitmap;
-}
-
-static viz::ResourceSettings CreateResourceSettings() {
- viz::ResourceSettings resource_settings;
- resource_settings.use_gpu_memory_buffer_resources =
- kUseGpuMemoryBufferResources;
- return resource_settings;
-}
-
-// Shared data between multiple ResourceProviderContext. This contains mailbox
-// contents as well as information about sync points.
-class ContextSharedData {
- public:
- static std::unique_ptr<ContextSharedData> Create() {
- return base::WrapUnique(new ContextSharedData());
- }
-
- uint32_t InsertFenceSync() { return next_fence_sync_++; }
-
- void GenMailbox(GLbyte* mailbox) {
- memset(mailbox, 0, GL_MAILBOX_SIZE_CHROMIUM);
- memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
- ++next_mailbox_;
- }
-
- void ProduceTexture(const GLbyte* mailbox_name,
- const gpu::SyncToken& sync_token,
- scoped_refptr<viz::TestTexture> texture) {
- uint32_t sync_point = static_cast<uint32_t>(sync_token.release_count());
-
- unsigned mailbox = 0;
- memcpy(&mailbox, mailbox_name, sizeof(mailbox));
- ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
- textures_[mailbox] = texture;
- ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
- sync_point_for_mailbox_[mailbox] = sync_point;
- }
-
- scoped_refptr<viz::TestTexture> ConsumeTexture(
- const GLbyte* mailbox_name,
- const gpu::SyncToken& sync_token) {
- unsigned mailbox = 0;
- memcpy(&mailbox, mailbox_name, sizeof(mailbox));
- DCHECK(mailbox && mailbox < next_mailbox_);
-
- // If the latest sync point the context has waited on is before the sync
- // point for when the mailbox was set, pretend we never saw that
- // ProduceTexture.
- if (sync_point_for_mailbox_[mailbox] > sync_token.release_count()) {
- NOTREACHED();
- return scoped_refptr<viz::TestTexture>();
- }
- return textures_[mailbox];
- }
-
- private:
- ContextSharedData() : next_fence_sync_(1), next_mailbox_(1) {}
-
- uint64_t next_fence_sync_;
- unsigned next_mailbox_;
- using TextureMap =
- std::unordered_map<unsigned, scoped_refptr<viz::TestTexture>>;
- TextureMap textures_;
- std::unordered_map<unsigned, uint32_t> sync_point_for_mailbox_;
-};
-
-class ResourceProviderContext : public viz::TestWebGraphicsContext3D {
- public:
- static std::unique_ptr<ResourceProviderContext> Create(
- ContextSharedData* shared_data) {
- return base::WrapUnique(new ResourceProviderContext(shared_data));
- }
-
- void genSyncToken(GLbyte* sync_token) override {
- uint64_t fence_sync = shared_data_->InsertFenceSync();
- gpu::SyncToken sync_token_data(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x123),
- fence_sync);
- sync_token_data.SetVerifyFlush();
- // Commit the ProduceTextureDirectCHROMIUM calls at this point, so that
- // they're associated with the sync point.
- for (const std::unique_ptr<PendingProduceTexture>& pending_texture :
- pending_produce_textures_) {
- shared_data_->ProduceTexture(pending_texture->mailbox, sync_token_data,
- pending_texture->texture);
- }
- pending_produce_textures_.clear();
- memcpy(sync_token, &sync_token_data, sizeof(sync_token_data));
- }
-
- void waitSyncToken(const GLbyte* sync_token) override {
- gpu::SyncToken sync_token_data;
- if (sync_token)
- memcpy(&sync_token_data, sync_token, sizeof(sync_token_data));
-
- if (sync_token_data.release_count() >
- last_waited_sync_token_.release_count()) {
- last_waited_sync_token_ = sync_token_data;
- }
- }
-
- const gpu::SyncToken& last_waited_sync_token() const {
- return last_waited_sync_token_;
- }
-
- void texStorage2DEXT(GLenum target,
- GLint levels,
- GLuint internalformat,
- GLint width,
- GLint height) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_EQ(1, levels);
- GLenum format = GL_RGBA;
- switch (internalformat) {
- case GL_RGBA8_OES:
- break;
- case GL_BGRA8_EXT:
- format = GL_BGRA_EXT;
- break;
- default:
- NOTREACHED();
- }
- AllocateTexture(gfx::Size(width, height), format);
- }
-
- void texImage2D(GLenum target,
- GLint level,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const void* pixels) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_FALSE(level);
- ASSERT_EQ(internalformat, format);
- ASSERT_FALSE(border);
- ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- AllocateTexture(gfx::Size(width, height), format);
- if (pixels)
- SetPixels(0, 0, width, height, pixels);
- }
-
- void texSubImage2D(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_FALSE(level);
- ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- {
- base::AutoLock lock_for_texture_access(namespace_->lock);
- ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
- }
- ASSERT_TRUE(pixels);
- SetPixels(xoffset, yoffset, width, height, pixels);
- }
-
- void genMailboxCHROMIUM(GLbyte* mailbox) override {
- return shared_data_->GenMailbox(mailbox);
- }
-
- void produceTextureDirectCHROMIUM(GLuint texture,
- const GLbyte* mailbox) override {
- // Delay moving the texture into the mailbox until the next
- // sync token, so that it is not visible to other contexts that
- // haven't waited on that sync point.
- std::unique_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
- memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
- base::AutoLock lock_for_texture_access(namespace_->lock);
- pending->texture = UnboundTexture(texture);
- pending_produce_textures_.push_back(std::move(pending));
- }
-
- GLuint createAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override {
- GLuint texture_id = createTexture();
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture =
- shared_data_->ConsumeTexture(mailbox, last_waited_sync_token_);
- namespace_->textures.Replace(texture_id, texture);
- return texture_id;
- }
-
- void GetPixels(const gfx::Size& size,
- viz::ResourceFormat format,
- uint8_t* pixels) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
- ASSERT_EQ(texture->size, size);
- ASSERT_EQ(texture->format, format);
- memcpy(pixels, texture->data.get(), TextureSizeBytes(size, format));
- }
-
- protected:
- explicit ResourceProviderContext(ContextSharedData* shared_data)
- : shared_data_(shared_data) {}
-
- private:
- void AllocateTexture(const gfx::Size& size, GLenum format) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- viz::ResourceFormat texture_format = viz::RGBA_8888;
- switch (format) {
- case GL_RGBA:
- texture_format = viz::RGBA_8888;
- break;
- case GL_BGRA_EXT:
- texture_format = viz::BGRA_8888;
- break;
- }
- base::AutoLock lock_for_texture_access(namespace_->lock);
- BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
- }
-
- void SetPixels(int xoffset,
- int yoffset,
- int width,
- int height,
- const void* pixels) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
- ASSERT_TRUE(texture->data.get());
- ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
- ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
- ASSERT_TRUE(pixels);
- size_t in_pitch = TextureSizeBytes(gfx::Size(width, 1), texture->format);
- size_t out_pitch =
- TextureSizeBytes(gfx::Size(texture->size.width(), 1), texture->format);
- uint8_t* dest = texture->data.get() + yoffset * out_pitch +
- TextureSizeBytes(gfx::Size(xoffset, 1), texture->format);
- const uint8_t* src = static_cast<const uint8_t*>(pixels);
- for (int i = 0; i < height; ++i) {
- memcpy(dest, src, in_pitch);
- dest += out_pitch;
- src += in_pitch;
- }
- }
-
- struct PendingProduceTexture {
- GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
- scoped_refptr<viz::TestTexture> texture;
- };
- ContextSharedData* shared_data_;
- gpu::SyncToken last_waited_sync_token_;
- std::vector<std::unique_ptr<PendingProduceTexture>> pending_produce_textures_;
-};
-
-class DisplayResourceProviderTest : public testing::TestWithParam<bool> {
- public:
- explicit DisplayResourceProviderTest(bool child_needs_sync_token)
- : use_gpu_(GetParam()),
- child_needs_sync_token_(child_needs_sync_token),
- shared_data_(ContextSharedData::Create()) {
- if (use_gpu_) {
- auto context3d(ResourceProviderContext::Create(shared_data_.get()));
- context3d_ = context3d.get();
- context_provider_ =
- viz::TestContextProvider::Create(std::move(context3d));
- context_provider_->UnboundTestContext3d()
- ->set_support_texture_format_bgra8888(true);
- context_provider_->BindToCurrentThread();
-
- auto child_context_owned =
- ResourceProviderContext::Create(shared_data_.get());
- child_context_ = child_context_owned.get();
- child_context_provider_ =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider_->UnboundTestContext3d()
- ->set_support_texture_format_bgra8888(true);
- child_context_provider_->BindToCurrentThread();
- gpu_memory_buffer_manager_ =
- std::make_unique<viz::TestGpuMemoryBufferManager>();
- child_gpu_memory_buffer_manager_ =
- gpu_memory_buffer_manager_->CreateClientGpuMemoryBufferManager();
- } else {
- shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
- }
-
- resource_provider_ = std::make_unique<DisplayResourceProvider>(
- context_provider_.get(), shared_bitmap_manager_.get());
-
- MakeChildResourceProvider();
- }
-
- DisplayResourceProviderTest() : DisplayResourceProviderTest(true) {}
-
- bool use_gpu() const { return use_gpu_; }
-
- void MakeChildResourceProvider() {
- child_resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
- child_context_provider_.get(), shared_bitmap_manager_.get(),
- child_gpu_memory_buffer_manager_.get(), child_needs_sync_token_,
- CreateResourceSettings());
- }
-
- static void CollectResources(
- std::vector<viz::ReturnedResource>* array,
- const std::vector<viz::ReturnedResource>& returned) {
- array->insert(array->end(), returned.begin(), returned.end());
- }
-
- static ReturnCallback GetReturnCallback(
- std::vector<viz::ReturnedResource>* array) {
- return base::BindRepeating(&DisplayResourceProviderTest::CollectResources,
- array);
- }
-
- static void SetResourceFilter(DisplayResourceProvider* resource_provider,
- viz::ResourceId id,
- GLenum filter) {
- DisplayResourceProvider::ScopedSamplerGL sampler(resource_provider, id,
- GL_TEXTURE_2D, filter);
- }
-
- ResourceProviderContext* context() { return context3d_; }
-
- viz::ResourceId CreateChildMailbox(gpu::SyncToken* release_sync_token,
- bool* lost_resource,
- bool* release_called,
- gpu::SyncToken* sync_token,
- viz::ResourceFormat format) {
- if (use_gpu()) {
- unsigned texture = child_context_->createTexture();
- gpu::Mailbox gpu_mailbox;
- child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
- child_context_->produceTextureDirectCHROMIUM(texture, gpu_mailbox.name);
- child_context_->genSyncToken(sync_token->GetData());
- EXPECT_TRUE(sync_token->HasData());
-
- std::unique_ptr<viz::SharedBitmap> shared_bitmap;
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::BindRepeating(
- ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
- release_called, release_sync_token, lost_resource));
- viz::TransferableResource gl_resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, *sync_token);
- gl_resource.format = format;
- return child_resource_provider_->ImportResource(gl_resource,
- std::move(callback));
- } else {
- gfx::Size size(64, 64);
- std::unique_ptr<viz::SharedBitmap> shared_bitmap(
- CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, format,
- 0));
-
- viz::SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::BindRepeating(
- ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
- release_called, release_sync_token, lost_resource));
- return child_resource_provider_->ImportResource(
- viz::TransferableResource::MakeSoftware(
- shared_bitmap_ptr->id(), shared_bitmap_ptr->sequence_number(),
- size, format),
- std::move(callback));
- }
- }
-
- viz::ResourceId MakeGpuResourceAndSendToDisplay(
- char c,
- GLuint filter,
- GLuint target,
- const gpu::SyncToken& sync_token,
- DisplayResourceProvider* resource_provider) {
- ReturnCallback return_callback = base::DoNothing();
-
- int child = resource_provider->CreateChild(return_callback);
-
- gpu::Mailbox gpu_mailbox;
- gpu_mailbox.name[0] = c;
- gpu_mailbox.name[1] = 0;
- auto resource = viz::TransferableResource::MakeGL(gpu_mailbox, GL_LINEAR,
- target, sync_token);
- resource.id = 11;
- resource_provider->ReceiveFromChild(child, {resource});
- auto& map = resource_provider->GetChildToParentMap(child);
- return map.find(resource.id)->second;
- }
-
- protected:
- const bool use_gpu_;
- const bool child_needs_sync_token_;
- const std::unique_ptr<ContextSharedData> shared_data_;
- ResourceProviderContext* context3d_ = nullptr;
- ResourceProviderContext* child_context_ = nullptr;
- scoped_refptr<viz::TestContextProvider> context_provider_;
- scoped_refptr<viz::TestContextProvider> child_context_provider_;
- std::unique_ptr<viz::TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
- std::unique_ptr<DisplayResourceProvider> resource_provider_;
- std::unique_ptr<viz::TestGpuMemoryBufferManager>
- child_gpu_memory_buffer_manager_;
- std::unique_ptr<LayerTreeResourceProvider> child_resource_provider_;
- std::unique_ptr<viz::TestSharedBitmapManager> shared_bitmap_manager_;
-};
-
-INSTANTIATE_TEST_CASE_P(DisplayResourceProviderTests,
- DisplayResourceProviderTest,
- ::testing::Values(false, true));
-
-TEST_P(DisplayResourceProviderTest, LockForExternalUse) {
- // TODO(penghuang): consider supporting SW mode.
- if (!use_gpu())
- return;
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data1[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data1, size);
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
-
- unsigned parent_id = resource_map[list.front().id];
-
- DisplayResourceProvider::LockSetForExternalUse lock_set(
- resource_provider_.get());
-
- viz::ResourceMetadata metadata = lock_set.LockResource(parent_id);
- ASSERT_EQ(size, metadata.size);
- ASSERT_FALSE(metadata.mailbox.IsZero());
- ASSERT_TRUE(metadata.sync_token.HasData());
-
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- // The resource should not be returned due to the external use lock.
- EXPECT_EQ(0u, returned_to_child.size());
-
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x234),
- 0x456);
- sync_token.SetVerifyFlush();
- lock_set.UnlockResources(sync_token);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- // The resource should be returned after the lock is released.
- EXPECT_EQ(1u, returned_to_child.size());
- EXPECT_EQ(sync_token, returned_to_child[0].sync_token);
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- child_resource_provider_->DeleteResource(id1);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/layer_tree_resource_provider.cc b/chromium/cc/resources/layer_tree_resource_provider.cc
index 44720a3ffcb..df7c76ca592 100644
--- a/chromium/cc/resources/layer_tree_resource_provider.cc
+++ b/chromium/cc/resources/layer_tree_resource_provider.cc
@@ -8,73 +8,20 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.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 "components/viz/common/resources/resource_sizes.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "components/viz/common/resources/returned_resource.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
-#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "third_party/skia/include/core/SkCanvas.h"
using gpu::gles2::GLES2Interface;
namespace cc {
-LayerTreeResourceProvider::Settings::Settings(
- viz::ContextProvider* compositor_context_provider,
- bool delegated_sync_points_required,
- const viz::ResourceSettings& resource_settings)
- : yuv_highbit_resource_format(resource_settings.high_bit_for_testing
- ? viz::R16_EXT
- : viz::LUMINANCE_8),
- use_gpu_memory_buffer_resources(
- resource_settings.use_gpu_memory_buffer_resources),
- delegated_sync_points_required(delegated_sync_points_required) {
- if (!compositor_context_provider) {
- // Pick an arbitrary limit here similar to what hardware might.
- max_texture_size = 16 * 1024;
- best_texture_format = viz::RGBA_8888;
- return;
- }
-
- const auto& caps = compositor_context_provider->ContextCapabilities();
- use_texture_storage = caps.texture_storage;
- use_texture_format_bgra = caps.texture_format_bgra8888;
- use_texture_usage_hint = caps.texture_usage;
- use_texture_npot = caps.texture_npot;
- use_sync_query = caps.sync_query;
- use_texture_storage_image = caps.texture_storage_image;
-
- if (caps.disable_one_component_textures) {
- yuv_resource_format = yuv_highbit_resource_format = viz::RGBA_8888;
- } else {
- yuv_resource_format = caps.texture_rg ? viz::RED_8 : viz::LUMINANCE_8;
- if (resource_settings.use_r16_texture && caps.texture_norm16)
- yuv_highbit_resource_format = viz::R16_EXT;
- else if (caps.texture_half_float_linear)
- yuv_highbit_resource_format = viz::LUMINANCE_F16;
- }
-
- GLES2Interface* gl = compositor_context_provider->ContextGL();
- gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-
- best_texture_format =
- viz::PlatformColor::BestSupportedTextureFormat(use_texture_format_bgra);
- best_render_buffer_format = viz::PlatformColor::BestSupportedTextureFormat(
- caps.render_buffer_format_bgra8888);
-}
-
-namespace {
-// The resource id in LayerTreeResourceProvider starts from 1 to avoid
-// conflicts with id from DisplayResourceProvider.
-const unsigned int kLayerTreeInitialResourceId = 1;
-} // namespace
-
struct LayerTreeResourceProvider::ImportedResource {
viz::TransferableResource resource;
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
@@ -105,17 +52,10 @@ struct LayerTreeResourceProvider::ImportedResource {
LayerTreeResourceProvider::LayerTreeResourceProvider(
viz::ContextProvider* compositor_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- bool delegated_sync_points_required,
- const viz::ResourceSettings& resource_settings)
- : ResourceProvider(compositor_context_provider),
- settings_(compositor_context_provider,
- delegated_sync_points_required,
- resource_settings),
- shared_bitmap_manager_(shared_bitmap_manager),
- gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
- next_id_(kLayerTreeInitialResourceId) {
+ bool delegated_sync_points_required)
+ : delegated_sync_points_required_(delegated_sync_points_required),
+ compositor_context_provider_(compositor_context_provider) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
LayerTreeResourceProvider::~LayerTreeResourceProvider() {
@@ -126,9 +66,6 @@ LayerTreeResourceProvider::~LayerTreeResourceProvider() {
bool is_lost = imported.exported_count || imported.returned_lost;
imported.release_callback->Run(imported.returned_sync_token, is_lost);
}
- GLES2Interface* gl = ContextGL();
- if (gl)
- gl->Finish();
}
gpu::SyncToken LayerTreeResourceProvider::GenerateSyncTokenHelper(
@@ -151,64 +88,27 @@ gpu::SyncToken LayerTreeResourceProvider::GenerateSyncTokenHelper(
return sync_token;
}
-gpu::SyncToken LayerTreeResourceProvider::GetSyncTokenForResources(
- const ResourceIdArray& resource_ids) {
- gpu::SyncToken latest_sync_token;
- for (viz::ResourceId id : resource_ids) {
- const gpu::SyncToken& sync_token = GetResource(id)->sync_token();
- if (sync_token.release_count() > latest_sync_token.release_count())
- latest_sync_token = sync_token;
- }
- return latest_sync_token;
-}
-
-gfx::ColorSpace LayerTreeResourceProvider::GetResourceColorSpaceForRaster(
- const viz::internal::Resource* resource) const {
- return resource->color_space;
-}
-
void LayerTreeResourceProvider::PrepareSendToParent(
- const ResourceIdArray& export_ids,
- std::vector<viz::TransferableResource>* list) {
+ const std::vector<viz::ResourceId>& export_ids,
+ std::vector<viz::TransferableResource>* list,
+ viz::ContextProvider* context_provider) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- GLES2Interface* gl = ContextGL();
// This function goes through the array multiple times, store the resources
// as pointers so we don't have to look up the resource id multiple times.
// Make sure the maps do not change while these vectors are alive or they
// will become invalid.
- std::vector<std::pair<viz::internal::Resource*, viz::ResourceId>> resources;
std::vector<ImportedResource*> imports;
- resources.reserve(export_ids.size());
imports.reserve(export_ids.size());
for (const viz::ResourceId id : export_ids) {
auto it = imported_resources_.find(id);
- if (it != imported_resources_.end())
- imports.push_back(&it->second);
- else
- resources.push_back({GetResource(id), id});
+ DCHECK(it != imported_resources_.end());
+ imports.push_back(&it->second);
}
- DCHECK_EQ(resources.size() + imports.size(), export_ids.size());
// Lazily create any mailboxes and verify all unverified sync tokens.
std::vector<GLbyte*> unverified_sync_tokens;
- std::vector<viz::internal::Resource*> need_synchronization_resources;
- for (auto& pair : resources) {
- viz::internal::Resource* resource = pair.first;
- if (!resource->is_gpu_resource_type())
- continue;
-
- CreateMailbox(resource);
-
- if (settings_.delegated_sync_points_required) {
- if (resource->needs_sync_token()) {
- need_synchronization_resources.push_back(resource);
- } else if (!resource->sync_token().verified_flush()) {
- unverified_sync_tokens.push_back(resource->GetSyncTokenData());
- }
- }
- }
- if (settings_.delegated_sync_points_required) {
+ if (delegated_sync_points_required_) {
for (ImportedResource* imported : imports) {
if (!imported->resource.is_software &&
!imported->resource.mailbox_holder.sync_token.verified_flush()) {
@@ -218,49 +118,13 @@ void LayerTreeResourceProvider::PrepareSendToParent(
}
}
- // Insert sync point to synchronize the mailbox creation or bound textures.
- gpu::SyncToken new_sync_token;
- if (!need_synchronization_resources.empty()) {
- DCHECK(settings_.delegated_sync_points_required);
- DCHECK(gl);
- gl->GenUnverifiedSyncTokenCHROMIUM(new_sync_token.GetData());
- unverified_sync_tokens.push_back(new_sync_token.GetData());
- }
-
- if (compositor_context_provider_)
- compositor_context_provider_->ContextSupport()->FlushPendingWork();
-
if (!unverified_sync_tokens.empty()) {
- DCHECK(settings_.delegated_sync_points_required);
- DCHECK(gl);
- gl->VerifySyncTokensCHROMIUM(unverified_sync_tokens.data(),
- unverified_sync_tokens.size());
- }
-
- // Set sync token after verification.
- for (viz::internal::Resource* resource : need_synchronization_resources) {
- DCHECK(resource->is_gpu_resource_type());
- resource->UpdateSyncToken(new_sync_token);
- resource->SetSynchronized();
+ DCHECK(delegated_sync_points_required_);
+ DCHECK(context_provider);
+ context_provider->ContextGL()->VerifySyncTokensCHROMIUM(
+ unverified_sync_tokens.data(), unverified_sync_tokens.size());
}
- // Transfer Resources.
- for (size_t i = 0; i < resources.size(); ++i) {
- viz::internal::Resource* source = resources[i].first;
- const viz::ResourceId id = resources[i].second;
-
- DCHECK(!settings_.delegated_sync_points_required ||
- !source->needs_sync_token());
- DCHECK(!settings_.delegated_sync_points_required ||
- viz::internal::Resource::LOCALLY_USED !=
- source->synchronization_state());
-
- viz::TransferableResource resource;
- TransferResource(source, id, &resource);
-
- source->exported_count++;
- list->push_back(std::move(resource));
- }
for (ImportedResource* imported : imports) {
list->push_back(imported->resource);
imported->exported_count++;
@@ -270,177 +134,31 @@ void LayerTreeResourceProvider::PrepareSendToParent(
void LayerTreeResourceProvider::ReceiveReturnsFromParent(
const std::vector<viz::ReturnedResource>& resources) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- GLES2Interface* gl = ContextGL();
for (const viz::ReturnedResource& returned : resources) {
viz::ResourceId local_id = returned.id;
auto import_it = imported_resources_.find(local_id);
- if (import_it != imported_resources_.end()) {
- ImportedResource& imported = import_it->second;
-
- DCHECK_GE(imported.exported_count, returned.count);
- imported.exported_count -= returned.count;
- imported.returned_lost |= returned.lost;
-
- if (imported.exported_count)
- continue;
-
- if (returned.sync_token.HasData()) {
- DCHECK(!imported.resource.is_software);
- imported.returned_sync_token = returned.sync_token;
- }
-
- if (imported.marked_for_deletion) {
- imported.release_callback->Run(imported.returned_sync_token,
- imported.returned_lost);
- imported_resources_.erase(import_it);
- }
-
- continue;
- }
-
- auto map_iterator = resources_.find(local_id);
- DCHECK(map_iterator != resources_.end());
- // Resource was already lost (e.g. it belonged to a child that was
- // destroyed).
- // TODO(danakj): Remove this. There is no "child" here anymore, and
- // lost resources are still in the map until exported_count == 0.
- if (map_iterator == resources_.end())
- continue;
+ DCHECK(import_it != imported_resources_.end());
+ ImportedResource& imported = import_it->second;
- viz::internal::Resource* resource = &map_iterator->second;
+ DCHECK_GE(imported.exported_count, returned.count);
+ imported.exported_count -= returned.count;
+ imported.returned_lost |= returned.lost;
- DCHECK_GE(resource->exported_count, returned.count);
- resource->exported_count -= returned.count;
- resource->lost |= returned.lost;
- if (resource->exported_count)
+ if (imported.exported_count)
continue;
if (returned.sync_token.HasData()) {
- DCHECK(!resource->has_shared_bitmap_id);
- if (resource->origin == viz::internal::Resource::INTERNAL) {
- DCHECK(resource->gl_id);
- gl->WaitSyncTokenCHROMIUM(returned.sync_token.GetConstData());
- resource->SetSynchronized();
- } else {
- DCHECK(!resource->gl_id);
- resource->UpdateSyncToken(returned.sync_token);
- }
+ DCHECK(!imported.resource.is_software);
+ imported.returned_sync_token = returned.sync_token;
}
- if (!resource->marked_for_deletion)
- continue;
-
- // The resource belongs to this LayerTreeResourceProvider, so it can be
- // destroyed.
- DeleteResourceInternal(map_iterator, NORMAL);
- }
-}
-
-viz::ResourceId LayerTreeResourceProvider::CreateGpuTextureResource(
- const gfx::Size& size,
- viz::ResourceTextureHint hint,
- viz::ResourceFormat format,
- const gfx::ColorSpace& color_space) {
- DCHECK(compositor_context_provider_);
- DCHECK(!size.IsEmpty());
- DCHECK_LE(size.width(), settings_.max_texture_size);
- DCHECK_LE(size.height(), settings_.max_texture_size);
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(IsTextureFormatSupported(format));
-
- bool use_overlay = settings_.use_gpu_memory_buffer_resources ||
- (hint & viz::ResourceTextureHint::kOverlay);
- DCHECK(!use_overlay || !(hint & viz::ResourceTextureHint::kMipmap));
-
- viz::ResourceId id = next_id_++;
- viz::internal::Resource* resource =
- InsertResource(id, viz::internal::Resource(
- size, viz::internal::Resource::INTERNAL, hint,
- viz::ResourceType::kTexture, format, color_space));
- if (use_overlay && settings_.use_texture_storage_image &&
- viz::IsGpuMemoryBufferFormatSupported(format)) {
- resource->usage = gfx::BufferUsage::SCANOUT;
- resource->target = GetImageTextureTarget(
- compositor_context_provider_->ContextCapabilities(), resource->usage,
- format);
- resource->buffer_format = BufferFormat(format);
- resource->is_overlay_candidate = true;
- }
- return id;
-}
-
-viz::ResourceId LayerTreeResourceProvider::CreateGpuMemoryBufferResource(
- const gfx::Size& size,
- viz::ResourceTextureHint hint,
- viz::ResourceFormat format,
- gfx::BufferUsage usage,
- const gfx::ColorSpace& color_space) {
- DCHECK(compositor_context_provider_);
- DCHECK(!size.IsEmpty());
- DCHECK(compositor_context_provider_);
- DCHECK_LE(size.width(), settings_.max_texture_size);
- DCHECK_LE(size.height(), settings_.max_texture_size);
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- viz::ResourceId id = next_id_++;
- viz::internal::Resource* resource = InsertResource(
- id, viz::internal::Resource(size, viz::internal::Resource::INTERNAL, hint,
- viz::ResourceType::kGpuMemoryBuffer, format,
- color_space));
- resource->target = GetImageTextureTarget(
- compositor_context_provider_->ContextCapabilities(), usage, format);
- resource->buffer_format = BufferFormat(format);
- resource->usage = usage;
- resource->is_overlay_candidate = true;
- // GpuMemoryBuffer provides direct access to the memory used by the GPU. Read
- // lock fences are required to ensure that we're not trying to map a buffer
- // that is currently in-use by the GPU.
- resource->read_lock_fences_enabled = true;
- return id;
-}
-
-viz::ResourceId LayerTreeResourceProvider::CreateBitmapResource(
- const gfx::Size& size,
- const gfx::ColorSpace& color_space,
- viz::ResourceFormat format) {
- DCHECK(!compositor_context_provider_);
- DCHECK(!size.IsEmpty());
- DCHECK(viz::IsBitmapFormatSupported(format));
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // TODO(danakj): Allocate this outside ResourceProvider.
- std::unique_ptr<viz::SharedBitmap> bitmap =
- shared_bitmap_manager_->AllocateSharedBitmap(size, format);
- DCHECK(bitmap);
- DCHECK(bitmap->pixels());
-
- viz::ResourceId id = next_id_++;
- viz::internal::Resource* resource = InsertResource(
- id,
- viz::internal::Resource(size, viz::internal::Resource::INTERNAL,
- viz::ResourceTextureHint::kDefault,
- viz::ResourceType::kBitmap, format, color_space));
- resource->SetSharedBitmap(bitmap.get());
- resource->owned_shared_bitmap = std::move(bitmap);
- return id;
-}
-
-void LayerTreeResourceProvider::DeleteResource(viz::ResourceId id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- ResourceMap::iterator it = resources_.find(id);
- CHECK(it != resources_.end());
- viz::internal::Resource* resource = &it->second;
- DCHECK(!resource->marked_for_deletion);
- DCHECK_EQ(resource->imported_count, 0);
- DCHECK(!resource->locked_for_write);
-
- if (resource->exported_count > 0) {
- resource->marked_for_deletion = true;
- return;
- } else {
- DeleteResourceInternal(it, NORMAL);
+ if (imported.marked_for_deletion) {
+ imported.release_callback->Run(imported.returned_sync_token,
+ imported.returned_lost);
+ imported_resources_.erase(import_it);
+ }
}
}
@@ -468,223 +186,6 @@ void LayerTreeResourceProvider::RemoveImportedResource(viz::ResourceId id) {
}
}
-void LayerTreeResourceProvider::CopyToResource(viz::ResourceId id,
- const uint8_t* image,
- const gfx::Size& image_size) {
- viz::internal::Resource* resource = GetResource(id);
- DCHECK(!resource->locked_for_write);
- DCHECK_EQ(resource->origin, viz::internal::Resource::INTERNAL);
- DCHECK_NE(resource->synchronization_state(),
- viz::internal::Resource::NEEDS_WAIT);
- DCHECK_EQ(resource->exported_count, 0);
-
- DCHECK_EQ(image_size.width(), resource->size.width());
- DCHECK_EQ(image_size.height(), resource->size.height());
-
- if (resource->type == viz::ResourceType::kBitmap) {
- DCHECK_EQ(viz::ResourceType::kBitmap, resource->type);
- DCHECK(resource->allocated);
- DCHECK_EQ(viz::RGBA_8888, resource->format);
- SkImageInfo source_info =
- SkImageInfo::MakeN32Premul(image_size.width(), image_size.height());
- size_t image_stride = image_size.width() * 4;
-
- ScopedWriteLockSoftware lock(this, id);
- SkCanvas dest(lock.sk_bitmap());
- dest.writePixels(source_info, image, image_stride, 0, 0);
- } else {
- // No sync token needed because the lock will set synchronization state to
- // LOCALLY_USED and a sync token will be generated in PrepareSendToParent.
- ScopedWriteLockGL lock(this, id);
- GLuint texture_id = lock.GetTexture();
- DCHECK(texture_id);
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->BindTexture(resource->target, texture_id);
- if (resource->format == viz::ETC1) {
- DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
- int image_bytes =
- viz::ResourceSizes::CheckedSizeInBytes<int>(image_size, viz::ETC1);
- gl->CompressedTexImage2D(resource->target, 0, GLInternalFormat(viz::ETC1),
- image_size.width(), image_size.height(), 0,
- image_bytes, image);
- lock.set_allocated();
- } else {
- gl->TexSubImage2D(resource->target, 0, 0, 0, image_size.width(),
- image_size.height(), GLDataFormat(resource->format),
- GLDataType(resource->format), image);
- }
- }
- DCHECK(resource->allocated);
-}
-
-void LayerTreeResourceProvider::CreateForTesting(viz::ResourceId id) {
- CreateTexture(GetResource(id));
-}
-
-void LayerTreeResourceProvider::CreateTexture(
- viz::internal::Resource* resource) {
- if (!resource->is_gpu_resource_type())
- return;
-
- if (resource->gl_id)
- return;
-
- DCHECK_EQ(resource->origin, viz::internal::Resource::INTERNAL);
- DCHECK(resource->mailbox.IsZero());
-
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
-
- // Create and set texture properties. Allocation of the texture backing is
- // delayed until needed.
- gl->GenTextures(1, &resource->gl_id);
- gl->BindTexture(resource->target, resource->gl_id);
- gl->TexParameteri(resource->target, GL_TEXTURE_MIN_FILTER,
- resource->original_filter);
- gl->TexParameteri(resource->target, GL_TEXTURE_MAG_FILTER,
- resource->original_filter);
- gl->TexParameteri(resource->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(resource->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (settings_.use_texture_usage_hint &&
- (resource->hint & viz::ResourceTextureHint::kFramebuffer)) {
- gl->TexParameteri(resource->target, GL_TEXTURE_USAGE_ANGLE,
- GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
- }
-}
-
-void LayerTreeResourceProvider::CreateMailbox(
- viz::internal::Resource* resource) {
- if (!resource->is_gpu_resource_type())
- return;
-
- if (!resource->mailbox.IsZero())
- return;
-
- CreateTexture(resource);
-
- DCHECK(resource->gl_id);
- DCHECK_EQ(resource->origin, viz::internal::Resource::INTERNAL);
-
- gpu::gles2::GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->GenMailboxCHROMIUM(resource->mailbox.name);
- gl->ProduceTextureDirectCHROMIUM(resource->gl_id, resource->mailbox.name);
- resource->SetLocallyUsed();
-}
-
-void LayerTreeResourceProvider::CreateAndBindImage(
- viz::internal::Resource* resource) {
- DCHECK(resource->gpu_memory_buffer);
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
- // TODO(reveman): This avoids a performance problem on ARM ChromeOS
- // devices. This only works with shared memory backed buffers.
- // https://crbug.com/580166
- DCHECK_EQ(resource->gpu_memory_buffer->GetHandle().type,
- gfx::SHARED_MEMORY_BUFFER);
-#endif
- CreateTexture(resource);
-
- gpu::gles2::GLES2Interface* gl = ContextGL();
- DCHECK(gl);
-
- gl->BindTexture(resource->target, resource->gl_id);
-
- if (!resource->image_id) {
- resource->image_id = gl->CreateImageCHROMIUM(
- resource->gpu_memory_buffer->AsClientBuffer(), resource->size.width(),
- resource->size.height(), GLInternalFormat(resource->format));
-
- DCHECK(resource->image_id ||
- gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR);
-
- gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
- } else {
- gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->image_id);
- gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
- }
-}
-
-void LayerTreeResourceProvider::AllocateForTesting(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- if (!resource->allocated) {
- // Software and external resources are marked allocated on creation.
- DCHECK(resource->is_gpu_resource_type());
- DCHECK_EQ(resource->origin, viz::internal::Resource::INTERNAL);
- ScopedWriteLockGL resource_lock(this, id);
- resource_lock.GetTexture(); // Allocates texture.
- }
-}
-
-void LayerTreeResourceProvider::TransferResource(
- viz::internal::Resource* source,
- viz::ResourceId id,
- viz::TransferableResource* resource) {
- DCHECK(!source->locked_for_write);
- DCHECK(source->allocated);
- resource->id = id;
- resource->format = source->format;
- resource->buffer_format = source->buffer_format;
- resource->filter = source->filter;
- resource->size = source->size;
- resource->read_lock_fences_enabled = source->read_lock_fences_enabled;
- resource->is_overlay_candidate = source->is_overlay_candidate;
- resource->color_space = source->color_space;
-
- if (source->type == viz::ResourceType::kBitmap) {
- DCHECK(source->shared_bitmap);
- resource->mailbox_holder.mailbox = source->shared_bitmap_id;
- resource->is_software = true;
- resource->shared_bitmap_sequence_number =
- source->shared_bitmap->sequence_number();
- } else {
- DCHECK(!source->mailbox.IsZero());
- // This is either an external resource, or a compositor resource that we
- // already exported. Make sure to forward the sync point that we were given.
- resource->mailbox_holder.mailbox = source->mailbox;
- resource->mailbox_holder.texture_target = source->target;
- resource->mailbox_holder.sync_token = source->sync_token();
- }
-}
-
-bool LayerTreeResourceProvider::CanLockForWrite(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- return !resource->locked_for_write && !resource->exported_count &&
- resource->origin == viz::internal::Resource::INTERNAL &&
- !resource->lost;
-}
-
-viz::internal::Resource* LayerTreeResourceProvider::LockForWrite(
- viz::ResourceId id) {
- DCHECK(CanLockForWrite(id));
- viz::internal::Resource* resource = GetResource(id);
- WaitSyncTokenInternal(resource);
- resource->SetLocallyUsed();
- resource->locked_for_write = true;
- resource->mipmap_state = viz::internal::Resource::INVALID;
- return resource;
-}
-
-void LayerTreeResourceProvider::UnlockForWrite(
- viz::internal::Resource* resource) {
- DCHECK(resource->locked_for_write);
- DCHECK_EQ(resource->exported_count, 0);
- DCHECK(resource->origin == viz::internal::Resource::INTERNAL);
- resource->locked_for_write = false;
-}
-
-void LayerTreeResourceProvider::FlushPendingDeletions() const {
- if (auto* gl = ContextGL())
- gl->ShallowFlushCHROMIUM();
-}
-
-GLenum LayerTreeResourceProvider::GetImageTextureTarget(
- const gpu::Capabilities& caps,
- gfx::BufferUsage usage,
- viz::ResourceFormat format) const {
- return gpu::GetBufferTextureTarget(usage, BufferFormat(format), caps);
-}
-
bool LayerTreeResourceProvider::IsTextureFormatSupported(
viz::ResourceFormat format) const {
gpu::Capabilities caps;
@@ -749,239 +250,6 @@ bool LayerTreeResourceProvider::IsRenderBufferFormatSupported(
return false;
}
-viz::ResourceFormat LayerTreeResourceProvider::YuvResourceFormat(
- int bits) const {
- if (bits > 8) {
- return settings_.yuv_highbit_resource_format;
- } else {
- return settings_.yuv_resource_format;
- }
-}
-
-bool LayerTreeResourceProvider::IsLost(viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- return resource->lost;
-}
-
-void LayerTreeResourceProvider::LoseResourceForTesting(viz::ResourceId id) {
- auto it = imported_resources_.find(id);
- if (it != imported_resources_.end()) {
- ImportedResource& imported = it->second;
- imported.returned_lost = true;
- return;
- }
-
- viz::internal::Resource* resource = GetResource(id);
- DCHECK(resource);
- resource->lost = true;
-}
-
-void LayerTreeResourceProvider::EnableReadLockFencesForTesting(
- viz::ResourceId id) {
- viz::internal::Resource* resource = GetResource(id);
- DCHECK(resource);
- resource->read_lock_fences_enabled = true;
-}
-
-LayerTreeResourceProvider::ScopedWriteLockGpu::ScopedWriteLockGpu(
- LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- viz::internal::Resource* resource =
- resource_provider->LockForWrite(resource_id);
- DCHECK_EQ(resource->type, viz::ResourceType::kTexture);
- resource_provider->CreateTexture(resource);
- size_ = resource->size;
- usage_ = resource->usage;
- format_ = resource->format;
- color_space_ = resource_provider_->GetResourceColorSpaceForRaster(resource);
- texture_id_ = resource->gl_id;
- target_ = resource->target;
- hint_ = resource->hint;
- mailbox_ = resource->mailbox;
- is_overlay_ = resource->is_overlay_candidate;
- allocated_ = resource->allocated;
-}
-
-LayerTreeResourceProvider::ScopedWriteLockGpu::~ScopedWriteLockGpu() {
- viz::internal::Resource* resource =
- resource_provider_->GetResource(resource_id_);
- DCHECK(resource->locked_for_write);
- resource->allocated = allocated_;
- resource->mailbox = mailbox_;
- // Don't set empty sync token otherwise resource will be marked synchronized.
- if (has_sync_token_)
- resource->UpdateSyncToken(sync_token_);
- if (synchronized_)
- resource->SetSynchronized();
- if (generate_mipmap_)
- resource->SetGenerateMipmap();
- resource_provider_->UnlockForWrite(resource);
-}
-
-SkColorType LayerTreeResourceProvider::ScopedWriteLockGpu::ColorType() const {
- return ResourceFormatToClosestSkColorType(format_);
-}
-
-void LayerTreeResourceProvider::ScopedWriteLockGpu::CreateMailbox() {
- if (!mailbox_.IsZero())
- return;
- gpu::gles2::GLES2Interface* gl = resource_provider_->ContextGL();
- DCHECK(gl);
- gl->GenMailboxCHROMIUM(mailbox_.name);
- gl->ProduceTextureDirectCHROMIUM(texture_id_, mailbox_.name);
-}
-
-LayerTreeResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
- LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : ScopedWriteLockGpu(resource_provider, resource_id) {}
-
-LayerTreeResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {}
-
-GLuint LayerTreeResourceProvider::ScopedWriteLockGL::GetTexture() {
- LazyAllocate(resource_provider_->ContextGL(), texture_id_);
- return texture_id_;
-}
-
-void LayerTreeResourceProvider::ScopedWriteLockGL::LazyAllocate(
- gpu::gles2::GLES2Interface* gl,
- GLuint texture_id) {
- // ETC1 resources cannot be preallocated.
- if (format_ == viz::ETC1)
- return;
-
- if (allocated_)
- return;
- allocated_ = true;
-
- const Settings& settings = resource_provider_->settings_;
-
- gl->BindTexture(target_, texture_id);
-
- if (is_overlay_) {
- DCHECK(settings.use_texture_storage_image);
- gl->TexStorage2DImageCHROMIUM(target_, viz::TextureStorageFormat(format_),
- GL_SCANOUT_CHROMIUM, size_.width(),
- size_.height());
- if (color_space_.IsValid()) {
- gl->SetColorSpaceMetadataCHROMIUM(
- texture_id, reinterpret_cast<GLColorSpace>(&color_space_));
- }
- } else if (settings.use_texture_storage) {
- GLint levels = 1;
- if (settings.use_texture_npot &&
- (hint_ & viz::ResourceTextureHint::kMipmap)) {
- levels += base::bits::Log2Floor(std::max(size_.width(), size_.height()));
- }
- gl->TexStorage2DEXT(target_, levels, viz::TextureStorageFormat(format_),
- size_.width(), size_.height());
- } else {
- gl->TexImage2D(target_, 0, GLInternalFormat(format_), size_.width(),
- size_.height(), 0, GLDataFormat(format_),
- GLDataType(format_), nullptr);
- }
-}
-
-LayerTreeResourceProvider::ScopedWriteLockRaster::ScopedWriteLockRaster(
- LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : ScopedWriteLockGpu(resource_provider, resource_id) {}
-
-LayerTreeResourceProvider::ScopedWriteLockRaster::~ScopedWriteLockRaster() {}
-
-GLuint LayerTreeResourceProvider::ScopedWriteLockRaster::ConsumeTexture(
- gpu::raster::RasterInterface* ri) {
- DCHECK(ri);
- DCHECK(!mailbox_.IsZero());
-
- GLuint texture_id =
- ri->CreateAndConsumeTexture(is_overlay_, usage_, format_, mailbox_.name);
- DCHECK(texture_id);
-
- LazyAllocate(ri, texture_id);
-
- return texture_id;
-}
-
-void LayerTreeResourceProvider::ScopedWriteLockRaster::LazyAllocate(
- gpu::raster::RasterInterface* ri,
- GLuint texture_id) {
- // ETC1 resources cannot be preallocated.
- if (format_ == viz::ETC1)
- return;
-
- if (allocated_)
- return;
- allocated_ = true;
-
- ri->TexStorage2D(texture_id, 1, size_.width(), size_.height());
- if (is_overlay_ && color_space_.IsValid()) {
- ri->SetColorSpaceMetadata(texture_id,
- reinterpret_cast<GLColorSpace>(&color_space_));
- }
-}
-
-LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer ::
- ScopedWriteLockGpuMemoryBuffer(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- viz::internal::Resource* resource =
- resource_provider->LockForWrite(resource_id);
- DCHECK_EQ(resource->type, viz::ResourceType::kGpuMemoryBuffer);
- size_ = resource->size;
- format_ = resource->format;
- usage_ = resource->usage;
- color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource);
- gpu_memory_buffer_ = std::move(resource->gpu_memory_buffer);
-}
-
-LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer::
- ~ScopedWriteLockGpuMemoryBuffer() {
- viz::internal::Resource* resource =
- resource_provider_->GetResource(resource_id_);
- // Avoid crashing in release builds if GpuMemoryBuffer allocation fails.
- // http://crbug.com/554541
- if (gpu_memory_buffer_) {
- resource->gpu_memory_buffer = std::move(gpu_memory_buffer_);
- resource->allocated = true;
- resource_provider_->CreateAndBindImage(resource);
- }
- resource_provider_->UnlockForWrite(resource);
-}
-
-gfx::GpuMemoryBuffer* LayerTreeResourceProvider::
- ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
- if (!gpu_memory_buffer_) {
- gpu_memory_buffer_ =
- resource_provider_->gpu_memory_buffer_manager()->CreateGpuMemoryBuffer(
- size_, BufferFormat(format_), usage_, gpu::kNullSurfaceHandle);
- // Avoid crashing in release builds if GpuMemoryBuffer allocation fails.
- // http://crbug.com/554541
- if (gpu_memory_buffer_ && color_space_.IsValid())
- gpu_memory_buffer_->SetColorSpace(color_space_);
- }
- return gpu_memory_buffer_.get();
-}
-
-LayerTreeResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
- LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id)
- : resource_provider_(resource_provider), resource_id_(resource_id) {
- viz::internal::Resource* resource =
- resource_provider->LockForWrite(resource_id);
- resource_provider->PopulateSkBitmapWithResource(&sk_bitmap_, resource);
- color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource);
- DCHECK(valid());
-}
-
-LayerTreeResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
- viz::internal::Resource* resource =
- resource_provider_->GetResource(resource_id_);
- resource->SetSynchronized();
- resource_provider_->UnlockForWrite(resource);
-}
-
LayerTreeResourceProvider::ScopedSkSurface::ScopedSkSurface(
GrContext* gr_context,
GLuint texture_id,
@@ -997,9 +265,12 @@ LayerTreeResourceProvider::ScopedSkSurface::ScopedSkSurface(
GrBackendTexture backend_texture(size.width(), size.height(),
GrMipMapped::kNo, texture_info);
SkSurfaceProps surface_props = ComputeSurfaceProps(can_use_lcd_text);
+ // This type is used only for gpu raster, which implies gpu compositing.
+ bool gpu_compositing = true;
surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, msaa_sample_count,
- ResourceFormatToClosestSkColorType(format), nullptr, &surface_props);
+ ResourceFormatToClosestSkColorType(gpu_compositing, format), nullptr,
+ &surface_props);
}
LayerTreeResourceProvider::ScopedSkSurface::~ScopedSkSurface() {
@@ -1023,30 +294,14 @@ SkSurfaceProps LayerTreeResourceProvider::ScopedSkSurface::ComputeSurfaceProps(
void LayerTreeResourceProvider::ValidateResource(viz::ResourceId id) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(id);
- DCHECK(resources_.find(id) != resources_.end() ||
- imported_resources_.find(id) != imported_resources_.end());
+ DCHECK(imported_resources_.find(id) != imported_resources_.end());
}
bool LayerTreeResourceProvider::InUseByConsumer(viz::ResourceId id) {
auto it = imported_resources_.find(id);
- if (it != imported_resources_.end()) {
- ImportedResource& imported = it->second;
- return imported.exported_count > 0 || imported.returned_lost;
- }
-
- viz::internal::Resource* resource = GetResource(id);
- return resource->exported_count > 0 || resource->lost;
-}
-
-bool LayerTreeResourceProvider::OnMemoryDump(
- const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) {
- // Imported resources should be tracked in the client where they
- // originated, as this code has only a name to refer to them and
- // is not keeping them alive.
-
- // Non-imported resources are tracked in the base class.
- return ResourceProvider::OnMemoryDump(args, pmd);
+ DCHECK(it != imported_resources_.end());
+ ImportedResource& imported = it->second;
+ return imported.exported_count > 0 || imported.returned_lost;
}
} // namespace cc
diff --git a/chromium/cc/resources/layer_tree_resource_provider.h b/chromium/cc/resources/layer_tree_resource_provider.h
index 07a85f50a70..b046ea9d33c 100644
--- a/chromium/cc/resources/layer_tree_resource_provider.h
+++ b/chromium/cc/resources/layer_tree_resource_provider.h
@@ -5,53 +5,56 @@
#ifndef CC_RESOURCES_LAYER_TREE_RESOURCE_PROVIDER_H_
#define CC_RESOURCES_LAYER_TREE_RESOURCE_PROVIDER_H_
-#include "cc/resources/resource_provider.h"
+#include <vector>
+
+#include "base/threading/thread_checker.h"
+#include "cc/cc_export.h"
#include "components/viz/common/display/renderer_settings.h"
+#include "components/viz/common/resources/release_callback.h"
+#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/resource_settings.h"
+#include "components/viz/common/resources/single_release_callback.h"
+#include "components/viz/common/resources/transferable_resource.h"
+#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
-namespace viz {
-class SharedBitmapManager;
-} // namespace viz
-
namespace gpu {
-struct Capabilities;
-class GpuMemoryBufferManager;
+namespace gles2 {
+class GLES2Interface;
+}
namespace raster {
class RasterInterface;
}
} // namespace gpu
+namespace viz {
+class ContextProvider;
+} // namespace viz
+
namespace cc {
// This class is not thread-safe and can only be called from the thread it was
// created on (in practice, the impl thread).
-class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider {
+class CC_EXPORT LayerTreeResourceProvider {
public:
- LayerTreeResourceProvider(
- viz::ContextProvider* compositor_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- bool delegated_sync_points_required,
- const viz::ResourceSettings& resource_settings);
- ~LayerTreeResourceProvider() override;
+ LayerTreeResourceProvider(viz::ContextProvider* compositor_context_provider,
+ bool delegated_sync_points_required);
+ ~LayerTreeResourceProvider();
static gpu::SyncToken GenerateSyncTokenHelper(gpu::gles2::GLES2Interface* gl);
static gpu::SyncToken GenerateSyncTokenHelper(
gpu::raster::RasterInterface* ri);
- // Gets the most recent sync token from the indicated resources.
- gpu::SyncToken GetSyncTokenForResources(const ResourceIdArray& resource_ids);
-
// Prepares resources to be transfered to the parent, moving them to
// mailboxes and serializing meta-data into TransferableResources.
// Resources are not removed from the ResourceProvider, but are marked as
// "in use".
void PrepareSendToParent(
- const ResourceIdArray& resource_ids,
- std::vector<viz::TransferableResource>* transferable_resources);
+ const std::vector<viz::ResourceId>& resource_ids,
+ std::vector<viz::TransferableResource>* transferable_resources,
+ viz::ContextProvider* context_provider);
// Receives resources from the parent, moving them from mailboxes. ResourceIds
// passed are in the child namespace.
@@ -60,22 +63,6 @@ class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider {
void ReceiveReturnsFromParent(
const std::vector<viz::ReturnedResource>& transferable_resources);
- viz::ResourceId CreateGpuTextureResource(const gfx::Size& size,
- viz::ResourceTextureHint hint,
- viz::ResourceFormat format,
- const gfx::ColorSpace& color_space);
- viz::ResourceId CreateGpuMemoryBufferResource(
- const gfx::Size& size,
- viz::ResourceTextureHint hint,
- viz::ResourceFormat format,
- gfx::BufferUsage usage,
- const gfx::ColorSpace& color_space);
- viz::ResourceId CreateBitmapResource(const gfx::Size& size,
- const gfx::ColorSpace& color_space,
- viz::ResourceFormat format);
-
- void DeleteResource(viz::ResourceId id);
-
// Receives a resource from an external client that can be used in compositor
// frames, via the returned ResourceId.
viz::ResourceId ImportResource(const viz::TransferableResource&,
@@ -83,18 +70,6 @@ class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider {
// Removes an imported resource, which will call the ReleaseCallback given
// originally, once the resource is no longer in use by any compositor frame.
void RemoveImportedResource(viz::ResourceId);
- // Update pixels from image, copying source_rect (in image) to dest_offset (in
- // the resource).
- void CopyToResource(viz::ResourceId id,
- const uint8_t* image,
- const gfx::Size& image_size);
-
- // For tests only! This prevents detecting uninitialized reads.
- // Use SetPixels or LockForWrite to allocate implicitly.
- void AllocateForTesting(viz::ResourceId id);
-
- // For tests only!
- void CreateForTesting(viz::ResourceId id);
// Verify that the ResourceId is valid and is known to this class, for debug
// checks.
@@ -103,182 +78,13 @@ class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider {
// Checks whether a resource is in use by a consumer.
bool InUseByConsumer(viz::ResourceId id);
- // Indicates if we can currently lock this resource for write.
- bool CanLockForWrite(viz::ResourceId id);
-
- // In the case of GPU resources, we may need to flush the GL context to ensure
- // that texture deletions are seen in a timely fashion. This function should
- // be called after texture deletions that may happen during an idle state.
- void FlushPendingDeletions() const;
-
- GLenum GetImageTextureTarget(const gpu::Capabilities& caps,
- gfx::BufferUsage usage,
- viz::ResourceFormat format) const;
-
bool IsTextureFormatSupported(viz::ResourceFormat format) const;
// Returns true if the provided |format| can be used as a render buffer.
// Note that render buffer support implies texture support.
bool IsRenderBufferFormatSupported(viz::ResourceFormat format) const;
- bool use_sync_query() const { return settings_.use_sync_query; }
-
- int max_texture_size() const { return settings_.max_texture_size; }
-
- // Use this format for making resources that will be rastered and uploaded to
- // from software bitmaps.
- viz::ResourceFormat best_texture_format() const {
- return settings_.best_texture_format;
- }
- // Use this format for making resources that will be rastered to on the Gpu.
- viz::ResourceFormat best_render_buffer_format() const {
- return settings_.best_render_buffer_format;
- }
-
- viz::ResourceFormat YuvResourceFormat(int bits) const;
-
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() {
- return gpu_memory_buffer_manager_;
- }
-
- bool IsLost(viz::ResourceId id);
-
- void LoseResourceForTesting(viz::ResourceId id);
- void EnableReadLockFencesForTesting(viz::ResourceId id);
-
- // The following lock classes are part of the ResourceProvider API and are
- // needed to read and write the resource contents. The user must ensure
- // that they only use GL locks on GL resources, etc, and this is enforced
- // by assertions.
- class CC_EXPORT ScopedWriteLockGpu {
- public:
- ScopedWriteLockGpu(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedWriteLockGpu();
-
- GLenum target() const { return target_; }
- viz::ResourceFormat format() const { return format_; }
- const gfx::Size& size() const { return size_; }
- const gfx::ColorSpace& color_space_for_raster() const {
- return color_space_;
- }
-
- SkColorType ColorType() const;
-
- void set_allocated() { allocated_ = true; }
-
- void set_sync_token(const gpu::SyncToken& sync_token) {
- sync_token_ = sync_token;
- has_sync_token_ = true;
- }
-
- void set_synchronized() { synchronized_ = true; }
-
- void set_generate_mipmap() { generate_mipmap_ = true; }
-
- // Creates mailbox on compositor context that can be consumed on another
- // context.
- void CreateMailbox();
-
- protected:
- LayerTreeResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
-
- // The following are copied from the resource.
- gfx::Size size_;
- gfx::BufferUsage usage_;
- viz::ResourceFormat format_;
- gfx::ColorSpace color_space_;
- GLuint texture_id_;
- GLenum target_;
- viz::ResourceTextureHint hint_;
- gpu::Mailbox mailbox_;
- bool is_overlay_;
- bool allocated_;
-
- // Set by the user.
- gpu::SyncToken sync_token_;
- bool has_sync_token_ = false;
- bool synchronized_ = false;
- bool generate_mipmap_ = false;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpu);
- };
-
- class CC_EXPORT ScopedWriteLockGL : public ScopedWriteLockGpu {
- public:
- ScopedWriteLockGL(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedWriteLockGL();
-
- // Returns texture id on compositor context, allocating if necessary.
- GLuint GetTexture();
-
- private:
- void LazyAllocate(gpu::gles2::GLES2Interface* gl, GLuint texture_id);
-
- DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL);
- };
-
- class CC_EXPORT ScopedWriteLockRaster : public ScopedWriteLockGpu {
- public:
- ScopedWriteLockRaster(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedWriteLockRaster();
-
- // Creates a texture id, allocating if necessary, on the given context. The
- // texture id must be deleted by the caller.
- GLuint ConsumeTexture(gpu::raster::RasterInterface* ri);
-
- private:
- void LazyAllocate(gpu::raster::RasterInterface* gl, GLuint texture_id);
-
- DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockRaster);
- };
-
- class CC_EXPORT ScopedWriteLockGpuMemoryBuffer {
- public:
- ScopedWriteLockGpuMemoryBuffer(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedWriteLockGpuMemoryBuffer();
- gfx::GpuMemoryBuffer* GetGpuMemoryBuffer();
- const gfx::ColorSpace& color_space_for_raster() const {
- return color_space_;
- }
-
- private:
- LayerTreeResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
-
- gfx::Size size_;
- viz::ResourceFormat format_;
- gfx::BufferUsage usage_;
- gfx::ColorSpace color_space_;
- std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpuMemoryBuffer);
- };
-
- class CC_EXPORT ScopedWriteLockSoftware {
- public:
- ScopedWriteLockSoftware(LayerTreeResourceProvider* resource_provider,
- viz::ResourceId resource_id);
- ~ScopedWriteLockSoftware();
-
- SkBitmap& sk_bitmap() { return sk_bitmap_; }
- bool valid() const { return !!sk_bitmap_.getPixels(); }
- const gfx::ColorSpace& color_space_for_raster() const {
- return color_space_;
- }
-
- private:
- LayerTreeResourceProvider* const resource_provider_;
- const viz::ResourceId resource_id_;
- gfx::ColorSpace color_space_;
- SkBitmap sk_bitmap_;
- DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware);
- };
+ bool IsSoftware() const { return !compositor_context_provider_; }
class CC_EXPORT ScopedSkSurface {
public:
@@ -301,52 +107,17 @@ class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider {
DISALLOW_COPY_AND_ASSIGN(ScopedSkSurface);
};
- protected:
- viz::internal::Resource* LockForWrite(viz::ResourceId id);
- void UnlockForWrite(viz::internal::Resource* resource);
- void CreateMailbox(viz::internal::Resource* resource);
-
private:
- // Holds const settings for the ResourceProvider. Never changed after init.
- struct Settings {
- Settings(viz::ContextProvider* compositor_context_provider,
- bool delegated_sync_points_needed,
- const viz::ResourceSettings& resource_settings);
-
- int max_texture_size = 0;
- bool use_texture_storage = false;
- bool use_texture_format_bgra = false;
- bool use_texture_usage_hint = false;
- bool use_texture_npot = false;
- bool use_sync_query = false;
- bool use_texture_storage_image = false;
- viz::ResourceType default_resource_type = viz::ResourceType::kTexture;
- viz::ResourceFormat yuv_resource_format = viz::LUMINANCE_8;
- viz::ResourceFormat yuv_highbit_resource_format = viz::LUMINANCE_8;
- viz::ResourceFormat best_texture_format = viz::RGBA_8888;
- viz::ResourceFormat best_render_buffer_format = viz::RGBA_8888;
- bool use_gpu_memory_buffer_resources = false;
- bool delegated_sync_points_required = false;
- } const settings_;
-
- // base::trace_event::MemoryDumpProvider implementation.
- bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) override;
-
- gfx::ColorSpace GetResourceColorSpaceForRaster(
- const viz::internal::Resource* resource) const;
+ struct ImportedResource;
- void CreateTexture(viz::internal::Resource* resource);
- void CreateAndBindImage(viz::internal::Resource* resource);
- void TransferResource(viz::internal::Resource* source,
- viz::ResourceId id,
- viz::TransferableResource* resource);
+ THREAD_CHECKER(thread_checker_);
+ const bool delegated_sync_points_required_;
+ viz::ContextProvider* const compositor_context_provider_;
- viz::SharedBitmapManager* shared_bitmap_manager_;
- struct ImportedResource;
base::flat_map<viz::ResourceId, ImportedResource> imported_resources_;
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
- viz::ResourceId next_id_;
+ // The ResourceIds in LayerTreeResourceProvider start from 1 to avoid
+ // conflicts with id from viz::DisplayResourceProvider.
+ viz::ResourceId next_id_ = 1;
DISALLOW_COPY_AND_ASSIGN(LayerTreeResourceProvider);
};
diff --git a/chromium/cc/resources/layer_tree_resource_provider_unittest.cc b/chromium/cc/resources/layer_tree_resource_provider_unittest.cc
index b0a47f2a805..e78f363d6b8 100644
--- a/chromium/cc/resources/layer_tree_resource_provider_unittest.cc
+++ b/chromium/cc/resources/layer_tree_resource_provider_unittest.cc
@@ -7,10 +7,10 @@
#include <memory>
#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "components/viz/common/resources/returned_resource.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/test/test_context_provider.h"
-#include "components/viz/test/test_gpu_memory_buffer_manager.h"
-#include "components/viz/test/test_shared_bitmap_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,10 +27,7 @@ class LayerTreeResourceProviderTest : public testing::TestWithParam<bool> {
bound_(context_provider_->BindToCurrentThread()),
provider_(std::make_unique<LayerTreeResourceProvider>(
use_gpu_ ? context_provider_.get() : nullptr,
- &shared_bitmap_manager_,
- &gpu_memory_buffer_manager_,
- delegated_sync_points_required_,
- resource_settings_)) {
+ delegated_sync_points_required_)) {
DCHECK_EQ(bound_, gpu::ContextResult::kSuccess);
}
@@ -59,8 +56,6 @@ class LayerTreeResourceProviderTest : public testing::TestWithParam<bool> {
r.mailbox_holder.sync_token = SyncTokenFromUInt(sync_token_value);
r.mailbox_holder.texture_target = 6;
}
- if (!gpu)
- r.shared_bitmap_sequence_number = sync_token_value;
return r;
}
@@ -68,15 +63,17 @@ class LayerTreeResourceProviderTest : public testing::TestWithParam<bool> {
bool use_gpu() const { return use_gpu_; }
LayerTreeResourceProvider& provider() const { return *provider_; }
+ viz::ContextProvider* context_provider() const {
+ return context_provider_.get();
+ }
+
+ void DestroyProvider() { provider_.reset(); }
private:
bool use_gpu_;
scoped_refptr<viz::TestContextProvider> context_provider_;
gpu::ContextResult bound_;
- viz::TestSharedBitmapManager shared_bitmap_manager_;
- viz::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
bool delegated_sync_points_required_ = true;
- viz::ResourceSettings resource_settings_;
std::unique_ptr<LayerTreeResourceProvider> provider_;
};
@@ -93,7 +90,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceReleased) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// The local id is different.
EXPECT_NE(id, tran.id);
@@ -108,14 +105,15 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceReleased) {
TEST_P(LayerTreeResourceProviderTest, TransferableResourceSendToParent) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ tran.buffer_format = gfx::BufferFormat::RGBX_8888;
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
ASSERT_EQ(exported.size(), 1u);
// Exported resource matches except for the id which was mapped
@@ -132,8 +130,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceSendToParent) {
EXPECT_EQ(exported[0].mailbox_holder.sync_token, verified_sync_token);
EXPECT_EQ(exported[0].mailbox_holder.texture_target,
tran.mailbox_holder.texture_target);
- EXPECT_EQ(exported[0].shared_bitmap_sequence_number,
- tran.shared_bitmap_sequence_number);
+ EXPECT_EQ(exported[0].buffer_format, tran.buffer_format);
// Exported resources are not released when removed, until the export returns.
EXPECT_CALL(release, Released(_, _)).Times(0);
@@ -153,18 +150,83 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceSendToParent) {
provider().ReceiveReturnsFromParent(returned);
}
+TEST_P(LayerTreeResourceProviderTest, TransferableResourceSendTwoToParent) {
+ viz::TransferableResource tran[] = {
+ MakeTransferableResource(use_gpu(), 'a', 15),
+ MakeTransferableResource(use_gpu(), 'b', 16)};
+ viz::ResourceId id1 = provider().ImportResource(
+ tran[0], viz::SingleReleaseCallback::Create(base::DoNothing()));
+ viz::ResourceId id2 = provider().ImportResource(
+ tran[1], viz::SingleReleaseCallback::Create(base::DoNothing()));
+
+ // Export the resource.
+ std::vector<viz::ResourceId> to_send = {id1, id2};
+ std::vector<viz::TransferableResource> exported;
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
+ ASSERT_EQ(exported.size(), 2u);
+
+ // Exported resource matches except for the id which was mapped
+ // to the local ResourceProvider, and the sync token should be
+ // verified if it's a gpu resource.
+ for (int i = 0; i < 2; ++i) {
+ gpu::SyncToken verified_sync_token = tran[i].mailbox_holder.sync_token;
+ if (!tran[i].is_software)
+ verified_sync_token.SetVerifyFlush();
+ EXPECT_EQ(exported[i].id, to_send[i]);
+ EXPECT_EQ(exported[i].is_software, tran[i].is_software);
+ EXPECT_EQ(exported[i].filter, tran[i].filter);
+ EXPECT_EQ(exported[i].size, tran[i].size);
+ EXPECT_EQ(exported[i].mailbox_holder.mailbox,
+ tran[i].mailbox_holder.mailbox);
+ EXPECT_EQ(exported[i].mailbox_holder.sync_token, verified_sync_token);
+ EXPECT_EQ(exported[i].mailbox_holder.texture_target,
+ tran[i].mailbox_holder.texture_target);
+ EXPECT_EQ(exported[i].buffer_format, tran[i].buffer_format);
+ }
+}
+
+TEST_P(LayerTreeResourceProviderTest,
+ TransferableResourceSendToParentTwoTimes) {
+ viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ viz::ResourceId id = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::DoNothing()));
+
+ // Export the resource.
+ std::vector<viz::ResourceId> to_send = {id};
+ std::vector<viz::TransferableResource> exported;
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
+ ASSERT_EQ(exported.size(), 1u);
+ EXPECT_EQ(exported[0].id, id);
+
+ // Return the resource, with a sync token if using gpu.
+ std::vector<viz::ReturnedResource> returned;
+ returned.push_back({});
+ returned.back().id = exported[0].id;
+ if (use_gpu())
+ returned.back().sync_token = SyncTokenFromUInt(31);
+ returned.back().count = 1;
+ returned.back().lost = false;
+ provider().ReceiveReturnsFromParent(returned);
+
+ // Then export again, it still sends.
+ exported.clear();
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
+ ASSERT_EQ(exported.size(), 1u);
+ EXPECT_EQ(exported[0].id, id);
+}
+
TEST_P(LayerTreeResourceProviderTest,
TransferableResourceLostOnShutdownIfExported) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
EXPECT_CALL(release, Released(_, true));
Shutdown();
@@ -174,13 +236,13 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceRemovedAfterReturn) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Return the resource. This does not release the resource back to
// the client.
@@ -204,13 +266,13 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceExportedTwice) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource once.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Exported resources are not released when removed, until all exports are
// returned.
@@ -219,7 +281,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceExportedTwice) {
// Export the resource twice.
exported = {};
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Return the resource the first time.
std::vector<viz::ReturnedResource> returned;
@@ -243,13 +305,13 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceReturnedTwiceAtOnce) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource once.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Exported resources are not released when removed, until all exports are
// returned.
@@ -258,7 +320,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceReturnedTwiceAtOnce) {
// Export the resource twice.
exported = {};
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Return both exports at once.
std::vector<viz::ReturnedResource> returned;
@@ -278,13 +340,13 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnReturn) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource once.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Exported resources are not released when removed, until all exports are
// returned.
@@ -293,7 +355,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnReturn) {
// Export the resource twice.
exported = {};
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Return the resource the first time, not lost.
std::vector<viz::ReturnedResource> returned;
@@ -303,7 +365,8 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnReturn) {
returned.back().lost = false;
provider().ReceiveReturnsFromParent(returned);
- // Return a second time, as lost. The ReturnCallback should report it lost.
+ // Return a second time, as lost. The viz::ReturnCallback should report it
+ // lost.
returned.back().lost = true;
EXPECT_CALL(release, Released(_, true));
provider().ReceiveReturnsFromParent(returned);
@@ -313,13 +376,13 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnFirstReturn) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
viz::ResourceId id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
// Export the resource once.
std::vector<viz::ResourceId> to_send = {id};
std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Exported resources are not released when removed, until all exports are
// returned.
@@ -328,7 +391,7 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnFirstReturn) {
// Export the resource twice.
exported = {};
- provider().PrepareSendToParent(to_send, &exported);
+ provider().PrepareSendToParent(to_send, &exported, context_provider());
// Return the resource the first time, marked as lost.
std::vector<viz::ReturnedResource> returned;
@@ -344,92 +407,149 @@ TEST_P(LayerTreeResourceProviderTest, TransferableResourceLostOnFirstReturn) {
provider().ReceiveReturnsFromParent(returned);
}
-TEST_P(LayerTreeResourceProviderTest,
- NormalPlusTransferableResourceSendToParent) {
+TEST_P(LayerTreeResourceProviderTest, ReturnedSyncTokensArePassedToClient) {
+ // SyncTokens are gpu-only.
+ if (!use_gpu())
+ return;
+
+ MockReleaseCallback release;
+
+ GLuint texture;
+ context_provider()->ContextGL()->GenTextures(1, &texture);
+ context_provider()->ContextGL()->BindTexture(GL_TEXTURE_2D, texture);
+ gpu::Mailbox mailbox;
+ context_provider()->ContextGL()->GenMailboxCHROMIUM(mailbox.name);
+ context_provider()->ContextGL()->ProduceTextureDirectCHROMIUM(texture,
+ mailbox.name);
+ gpu::SyncToken sync_token;
+ context_provider()->ContextGL()->GenSyncTokenCHROMIUM(sync_token.GetData());
+
+ auto tran = viz::TransferableResource::MakeGL(mailbox, GL_LINEAR,
+ GL_TEXTURE_2D, sync_token);
+ viz::ResourceId resource = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
+ &MockReleaseCallback::Released, base::Unretained(&release))));
+
+ EXPECT_TRUE(tran.mailbox_holder.sync_token.HasData());
+ // All the logic below assumes that the sync token releases are all positive.
+ EXPECT_LT(0u, tran.mailbox_holder.sync_token.release_count());
+
+ // Transfer the resource, expect the sync points to be consistent.
+ std::vector<viz::TransferableResource> list;
+ provider().PrepareSendToParent({resource}, &list, context_provider());
+ ASSERT_EQ(1u, list.size());
+ EXPECT_LE(sync_token.release_count(),
+ list[0].mailbox_holder.sync_token.release_count());
+ EXPECT_EQ(0, memcmp(mailbox.name, list[0].mailbox_holder.mailbox.name,
+ sizeof(mailbox.name)));
+
+ // Make a new texture id from the mailbox.
+ context_provider()->ContextGL()->WaitSyncTokenCHROMIUM(
+ list[0].mailbox_holder.sync_token.GetConstData());
+ unsigned other_texture =
+ context_provider()->ContextGL()->CreateAndConsumeTextureCHROMIUM(
+ mailbox.name);
+ // Then delete it and make a new SyncToken.
+ context_provider()->ContextGL()->DeleteTextures(1, &other_texture);
+ context_provider()->ContextGL()->GenSyncTokenCHROMIUM(
+ list[0].mailbox_holder.sync_token.GetData());
+ EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
+
+ // Receive the resource, then delete it, expect the SyncTokens to be
+ // consistent.
+ provider().ReceiveReturnsFromParent(
+ viz::TransferableResource::ReturnResources(list));
+
+ gpu::SyncToken returned_sync_token;
+ EXPECT_CALL(release, Released(_, false))
+ .WillOnce(testing::SaveArg<0>(&returned_sync_token));
+ provider().RemoveImportedResource(resource);
+ EXPECT_GE(returned_sync_token.release_count(),
+ list[0].mailbox_holder.sync_token.release_count());
+}
+
+TEST_P(LayerTreeResourceProviderTest, LostResourcesAreReturnedLost) {
MockReleaseCallback release;
viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ viz::ResourceId resource = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
+ &MockReleaseCallback::Released, base::Unretained(&release))));
+
+ // Transfer the resource to the parent.
+ std::vector<viz::TransferableResource> list;
+ provider().PrepareSendToParent({resource}, &list, context_provider());
+ EXPECT_EQ(1u, list.size());
- viz::ResourceId tran_id = provider().ImportResource(
- tran, viz::SingleReleaseCallback::Create(base::Bind(
+ // Receive it back marked lost.
+ std::vector<viz::ReturnedResource> returned_to_child;
+ returned_to_child.push_back(list[0].ToReturnedResource());
+ returned_to_child.back().lost = true;
+ provider().ReceiveReturnsFromParent(returned_to_child);
+
+ // Delete the resource in the child. Expect the resource to be lost.
+ EXPECT_CALL(release, Released(_, true));
+ provider().RemoveImportedResource(resource);
+}
+
+TEST_P(LayerTreeResourceProviderTest, ShutdownPreservesLostState) {
+ MockReleaseCallback release;
+ viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ viz::ResourceId resource = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
&MockReleaseCallback::Released, base::Unretained(&release))));
- viz::ResourceId norm_id;
- if (use_gpu()) {
- norm_id = provider().CreateGpuTextureResource(
- gfx::Size(3, 4), viz::ResourceTextureHint::kDefault, viz::RGBA_8888,
- gfx::ColorSpace());
- } else {
- norm_id = provider().CreateBitmapResource(
- gfx::Size(3, 4), gfx::ColorSpace(), viz::RGBA_8888);
- }
- provider().AllocateForTesting(norm_id);
- // Export the resources.
- std::vector<viz::ResourceId> to_send = {tran_id, norm_id};
- std::vector<viz::TransferableResource> exported;
- provider().PrepareSendToParent(to_send, &exported);
- ASSERT_EQ(exported.size(), 2u);
+ // Transfer the resource to the parent.
+ std::vector<viz::TransferableResource> list;
+ provider().PrepareSendToParent({resource}, &list, context_provider());
+ EXPECT_EQ(1u, list.size());
- // They're both exported (normal resources come first).
- EXPECT_EQ(exported[0].id, norm_id);
- EXPECT_EQ(exported[1].id, tran_id);
- viz::TransferableResource exported_norm = exported[0];
- viz::TransferableResource exported_tran = exported[1];
-
- // Exported normal Resource matches what it should.
- EXPECT_EQ(exported_norm.id, norm_id);
- EXPECT_EQ(exported_norm.is_software, tran.is_software);
- EXPECT_NE(exported_norm.filter, 0u);
- EXPECT_EQ(exported_norm.size, gfx::Size(3, 4));
- EXPECT_NE(exported_norm.mailbox_holder.mailbox, gpu::Mailbox());
- if (use_gpu()) {
- EXPECT_NE(exported_norm.mailbox_holder.sync_token, gpu::SyncToken());
- EXPECT_NE(exported_norm.mailbox_holder.texture_target, 0u);
- EXPECT_EQ(exported_norm.shared_bitmap_sequence_number, 0u);
- } else {
- EXPECT_EQ(exported_norm.mailbox_holder.sync_token, gpu::SyncToken());
- EXPECT_EQ(exported_norm.mailbox_holder.texture_target, 0u);
- EXPECT_NE(exported_norm.shared_bitmap_sequence_number, 0u);
- }
+ // Receive it back marked lost.
+ std::vector<viz::ReturnedResource> returned_to_child;
+ returned_to_child.push_back(list[0].ToReturnedResource());
+ returned_to_child.back().lost = true;
+ provider().ReceiveReturnsFromParent(returned_to_child);
- // Exported TransferableResource matches except for the id which was mapped
- // to the local ResourceProvider, and the sync token should be
- // verified if it's a gpu resource.
- gpu::SyncToken verified_sync_token = tran.mailbox_holder.sync_token;
- if (!tran.is_software)
- verified_sync_token.SetVerifyFlush();
- EXPECT_EQ(exported_tran.id, tran_id);
- EXPECT_EQ(exported_tran.is_software, tran.is_software);
- EXPECT_EQ(exported_tran.filter, tran.filter);
- EXPECT_EQ(exported_tran.size, tran.size);
- EXPECT_EQ(exported_tran.mailbox_holder.mailbox, tran.mailbox_holder.mailbox);
- EXPECT_EQ(exported_tran.mailbox_holder.sync_token, verified_sync_token);
- EXPECT_EQ(exported_tran.mailbox_holder.texture_target,
- tran.mailbox_holder.texture_target);
- EXPECT_EQ(exported_tran.shared_bitmap_sequence_number,
- tran.shared_bitmap_sequence_number);
+ // Shutdown, and expect the resource to be lost..
+ EXPECT_CALL(release, Released(_, true));
+ DestroyProvider();
+}
- // Return both resources, with sync tokens if using gpu.
- std::vector<viz::ReturnedResource> returned;
- returned.push_back({});
- returned.back().id = exported_norm.id;
- if (use_gpu())
- returned.back().sync_token = SyncTokenFromUInt(31);
- returned.back().count = 1;
- returned.back().lost = false;
+TEST_P(LayerTreeResourceProviderTest, ShutdownLosesExportedResources) {
+ MockReleaseCallback release;
+ viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ viz::ResourceId resource = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
+ &MockReleaseCallback::Released, base::Unretained(&release))));
- returned.push_back({});
- returned.back().id = exported_tran.id;
- if (use_gpu())
- returned.back().sync_token = SyncTokenFromUInt(82);
- returned.back().count = 1;
- returned.back().lost = false;
+ // Transfer the resource to the parent.
+ std::vector<viz::TransferableResource> list;
+ provider().PrepareSendToParent({resource}, &list, context_provider());
+ EXPECT_EQ(1u, list.size());
- provider().ReceiveReturnsFromParent(returned);
+ // Destroy the LayerTreeResourceProvider, the resource is returned lost.
+ EXPECT_CALL(release, Released(_, true));
+ DestroyProvider();
+}
+
+TEST_P(LayerTreeResourceProviderTest, ShutdownDoesNotLoseUnexportedResources) {
+ MockReleaseCallback release;
+ viz::TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15);
+ viz::ResourceId resource = provider().ImportResource(
+ tran, viz::SingleReleaseCallback::Create(base::BindOnce(
+ &MockReleaseCallback::Released, base::Unretained(&release))));
+
+ // Transfer the resource to the parent.
+ std::vector<viz::TransferableResource> list;
+ provider().PrepareSendToParent({resource}, &list, context_provider());
+ EXPECT_EQ(1u, list.size());
+
+ // Receive it back.
+ provider().ReceiveReturnsFromParent(
+ viz::TransferableResource::ReturnResources(list));
- // The sync token for the TransferableResource is given to the
- // ReleaseCallback.
- EXPECT_CALL(release, Released(returned[1].sync_token, false));
- provider().RemoveImportedResource(tran_id);
+ // Destroy the LayerTreeResourceProvider, the resource is not lost.
+ EXPECT_CALL(release, Released(_, false));
+ DestroyProvider();
}
} // namespace
diff --git a/chromium/cc/resources/resource.h b/chromium/cc/resources/resource.h
deleted file mode 100644
index f35fa0bf19b..00000000000
--- a/chromium/cc/resources/resource.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2012 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_RESOURCES_RESOURCE_H_
-#define CC_RESOURCES_RESOURCE_H_
-
-#include "base/macros.h"
-#include "cc/cc_export.h"
-#include "components/viz/common/resources/resource_format.h"
-#include "components/viz/common/resources/resource_id.h"
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class CC_EXPORT Resource {
- public:
- Resource() : id_(0), format_(viz::RGBA_8888) {}
- Resource(unsigned id,
- const gfx::Size& size,
- viz::ResourceFormat format,
- const gfx::ColorSpace& color_space)
- : id_(id), size_(size), format_(format), color_space_(color_space) {}
-
- viz::ResourceId id() const { return id_; }
- const gfx::Size& size() const { return size_; }
- viz::ResourceFormat format() const { return format_; }
- const gfx::ColorSpace& color_space() const { return color_space_; }
-
- protected:
- void set_id(viz::ResourceId id) { id_ = id; }
- void set_dimensions(const gfx::Size& size, viz::ResourceFormat format) {
- size_ = size;
- format_ = format;
- }
- void set_color_space(const gfx::ColorSpace& color_space) {
- color_space_ = color_space;
- }
-
- private:
- viz::ResourceId id_;
- gfx::Size size_;
- viz::ResourceFormat format_;
- gfx::ColorSpace color_space_;
-
- DISALLOW_COPY_AND_ASSIGN(Resource);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RESOURCE_H_
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index 659d5743972..a6d8b841c92 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -14,13 +14,16 @@
#include "base/format_macros.h"
#include "base/memory/memory_coordinator_client_registry.h"
#include "base/memory/shared_memory_handle.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "cc/base/container_util.h"
#include "cc/resources/layer_tree_resource_provider.h"
+#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/resource_sizes.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
using base::trace_event::MemoryAllocatorDump;
using base::trace_event::MemoryDumpLevelOfDetail;
@@ -65,12 +68,12 @@ constexpr base::TimeDelta ResourcePool::kDefaultExpirationDelay;
ResourcePool::ResourcePool(
LayerTreeResourceProvider* resource_provider,
+ viz::ContextProvider* context_provider,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::TimeDelta& expiration_delay,
- Mode resource_mode,
bool disallow_non_exact_reuse)
: resource_provider_(resource_provider),
- using_gpu_resources_(resource_mode == Mode::kGpu),
+ context_provider_(context_provider),
task_runner_(std::move(task_runner)),
resource_expiration_delay_(expiration_delay),
disallow_non_exact_reuse_(disallow_non_exact_reuse),
@@ -160,7 +163,7 @@ ResourcePool::InUsePoolResource ResourcePool::AcquireResource(
PoolResource* resource = ReuseResource(size, format, color_space);
if (!resource)
resource = CreateResource(size, format, color_space);
- return InUsePoolResource(resource, using_gpu_resources_);
+ return InUsePoolResource(resource, !!context_provider_);
}
// Iterate over all three resource lists (unused, in-use, and busy), updating
@@ -241,7 +244,7 @@ ResourcePool::TryAcquireResourceForPartialRaster(
// These will be updated when raster completes successfully.
resource->set_invalidated_rect(gfx::Rect());
resource->set_content_id(0);
- return InUsePoolResource(resource, using_gpu_resources_);
+ return InUsePoolResource(resource, !!context_provider_);
}
return InUsePoolResource();
@@ -275,7 +278,7 @@ void ResourcePool::OnResourceReleased(size_t unique_id,
}
resource->set_resource_id(0);
- if (using_gpu_resources_)
+ if (context_provider_)
resource->gpu_backing()->returned_sync_token = sync_token;
DidFinishUsingResource(std::move(*busy_it));
busy_resources_.erase(busy_it);
@@ -300,10 +303,7 @@ void ResourcePool::PrepareForExport(const InUsePoolResource& resource) {
} else {
transferable = viz::TransferableResource::MakeSoftware(
resource.resource_->software_backing()->shared_bitmap_id,
- // Not needed since this software resource's SharedBitmapId was
- // notified to the display compositor through the CompositorFrameSink.
- /*sequence_number=*/0, resource.resource_->size(),
- resource.resource_->format());
+ resource.resource_->size(), resource.resource_->format());
}
transferable.format = resource.resource_->format();
transferable.buffer_format = viz::BufferFormat(transferable.format);
@@ -486,7 +486,8 @@ void ResourcePool::EvictExpiredResources() {
// If nothing is evictable, we have deleted one (and possibly more)
// resources without any new activity. Flush to ensure these deletions are
// processed.
- resource_provider_->FlushPendingDeletions();
+ if (context_provider_)
+ context_provider_->ContextGL()->ShallowFlushCHROMIUM();
return;
}
@@ -522,8 +523,8 @@ base::TimeTicks ResourcePool::GetUsageTimeForLRUResource() const {
bool ResourcePool::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
- std::string dump_name = base::StringPrintf(
- "cc/tile_memory/provider_%d", resource_provider_->tracing_id());
+ std::string dump_name =
+ base::StringPrintf("cc/tile_memory/provider_%d", tracing_id_);
MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
dump->AddScalar(MemoryAllocatorDump::kNameSize,
MemoryAllocatorDump::kUnitsBytes,
diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h
index b55cf829297..e401582bc6d 100644
--- a/chromium/cc/resources/resource_pool.h
+++ b/chromium/cc/resources/resource_pool.h
@@ -20,11 +20,12 @@
#include "base/trace_event/memory_dump_provider.h"
#include "base/unguessable_token.h"
#include "cc/cc_export.h"
-#include "cc/resources/resource.h"
#include "components/viz/common/quads/shared_bitmap.h"
#include "components/viz/common/resources/resource_format.h"
+#include "components/viz/common/resources/resource_id.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -32,6 +33,10 @@ namespace base {
class SingleThreadTaskRunner;
}
+namespace viz {
+class ContextProvider;
+}
+
namespace cc {
class LayerTreeResourceProvider;
@@ -161,14 +166,13 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider,
PoolResource* resource_ = nullptr;
};
- enum class Mode { kGpu, kSoftware };
-
- // This takes a hint for if the pool will be holding gpu or software
- // resources, which is used for consistency checking.
+ // When holding gpu resources, the |context_provider| should be non-null,
+ // and when holding software resources, it should be null. It is used for
+ // consistency checking as well as for correctness.
ResourcePool(LayerTreeResourceProvider* resource_provider,
+ viz::ContextProvider* context_provider,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::TimeDelta& expiration_delay,
- Mode resource_mode,
bool disallow_non_exact_reuse);
~ResourcePool() override;
@@ -343,8 +347,8 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider,
bool HasEvictableResources() const;
base::TimeTicks GetUsageTimeForLRUResource() const;
- LayerTreeResourceProvider* const resource_provider_ = nullptr;
- const bool using_gpu_resources_ = false;
+ LayerTreeResourceProvider* const resource_provider_;
+ viz::ContextProvider* const context_provider_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const base::TimeDelta resource_expiration_delay_;
const bool disallow_non_exact_reuse_ = false;
diff --git a/chromium/cc/resources/resource_pool_unittest.cc b/chromium/cc/resources/resource_pool_unittest.cc
index cf233dc40b4..509a5a27421 100644
--- a/chromium/cc/resources/resource_pool_unittest.cc
+++ b/chromium/cc/resources/resource_pool_unittest.cc
@@ -23,11 +23,11 @@ class ResourcePoolTest : public testing::Test {
context_provider_ = viz::TestContextProvider::Create();
context_provider_->BindToCurrentThread();
resource_provider_ = FakeResourceProvider::CreateLayerTreeResourceProvider(
- context_provider_.get(), nullptr);
+ context_provider_.get());
task_runner_ = base::ThreadTaskRunnerHandle::Get();
resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu, false);
+ resource_provider_.get(), context_provider_.get(), task_runner_,
+ ResourcePool::kDefaultExpirationDelay, false);
}
protected:
@@ -163,7 +163,15 @@ TEST_F(ResourcePoolTest, LostResource) {
SetBackingOnResource(resource);
resource_pool_->PrepareForExport(resource);
- resource_provider_->LoseResourceForTesting(resource.resource_id_for_export());
+ std::vector<viz::ResourceId> export_ids = {resource.resource_id_for_export()};
+ std::vector<viz::TransferableResource> transferable_resources;
+ resource_provider_->PrepareSendToParent(export_ids, &transferable_resources,
+ context_provider_.get());
+ auto returned_resources =
+ viz::TransferableResource::ReturnResources(transferable_resources);
+ ASSERT_EQ(1u, returned_resources.size());
+ returned_resources[0].lost = true;
+ resource_provider_->ReceiveReturnsFromParent(returned_resources);
EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting());
resource_pool_->ReleaseResource(std::move(resource));
@@ -174,8 +182,8 @@ 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(), task_runner_,
- base::TimeDelta::FromMilliseconds(10), ResourcePool::Mode::kGpu, false);
+ 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;
@@ -196,7 +204,7 @@ TEST_F(ResourcePoolTest, BusyResourcesNotFreed) {
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
- &transfers);
+ &transfers, context_provider_.get());
resource_pool_->ReleaseResource(std::move(resource));
EXPECT_EQ(40000u, resource_pool_->GetTotalMemoryUsageForTesting());
@@ -221,8 +229,8 @@ 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(), task_runner_,
- base::TimeDelta::FromMilliseconds(100), ResourcePool::Mode::kGpu, false);
+ 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;
@@ -245,7 +253,7 @@ TEST_F(ResourcePoolTest, UnusedResourcesEventuallyFreed) {
resource_pool_->PrepareForExport(resource);
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
- &transfers);
+ &transfers, context_provider_.get());
resource_pool_->ReleaseResource(std::move(resource));
EXPECT_EQ(40000u, resource_pool_->GetTotalMemoryUsageForTesting());
@@ -467,7 +475,7 @@ TEST_F(ResourcePoolTest, PurgedMemory) {
// released.
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
- &transfers);
+ &transfers, context_provider_.get());
// Release the resource making it busy.
resource_pool_->OnMemoryStateChange(base::MemoryState::NORMAL);
@@ -523,7 +531,7 @@ TEST_F(ResourcePoolTest, MemoryStateSuspended) {
// released.
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
- &transfers);
+ &transfers, context_provider_.get());
// Release the resource making it busy.
resource_pool_->OnMemoryStateChange(base::MemoryState::NORMAL);
@@ -586,7 +594,8 @@ TEST_F(ResourcePoolTest, InvalidateResources) {
// once released.
std::vector<viz::TransferableResource> transfers;
resource_provider_->PrepareSendToParent(
- {busy_resource.resource_id_for_export()}, &transfers);
+ {busy_resource.resource_id_for_export()}, &transfers,
+ context_provider_.get());
// Release the resource making it busy.
resource_pool_->ReleaseResource(std::move(busy_resource));
@@ -622,8 +631,8 @@ TEST_F(ResourcePoolTest, ExactRequestsRespected) {
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), task_runner_,
- base::TimeDelta::FromMilliseconds(100), ResourcePool::Mode::kGpu, true);
+ resource_provider_.get(), context_provider_.get(), task_runner_,
+ base::TimeDelta::FromMilliseconds(100), true);
// Create unused resource with size 100x100.
CheckAndReturnResource(resource_pool_->AcquireResource(gfx::Size(100, 100),
@@ -679,7 +688,7 @@ TEST_F(ResourcePoolTest, MetadataSentToDisplayCompositor) {
std::vector<viz::TransferableResource> transfer;
resource_provider_->PrepareSendToParent({resource.resource_id_for_export()},
- &transfer);
+ &transfer, context_provider_.get());
// The verified_flush flag will be set by the ResourceProvider when it exports
// the resource.
diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc
deleted file mode 100644
index fcc3b6158e7..00000000000
--- a/chromium/cc/resources/resource_provider.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2012 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/resources/resource_provider.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <limits>
-#include <unordered_map>
-
-#include "base/atomic_sequence_num.h"
-#include "base/macros.h"
-#include "base/metrics/histogram.h"
-#include "base/numerics/safe_math.h"
-#include "base/stl_util.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/resources/resource_sizes.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
-#include "skia/ext/texture_handle.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/icc_profile.h"
-#include "ui/gl/trace_util.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-namespace {
-
-// Generates process-unique IDs to use for tracing a ResourceProvider's
-// resources.
-base::AtomicSequenceNumber g_next_resource_provider_tracing_id;
-
-} // namespace
-
-ResourceProvider::ResourceProvider(
- viz::ContextProvider* compositor_context_provider)
- : compositor_context_provider_(compositor_context_provider),
- lost_context_provider_(false),
- tracing_id_(g_next_resource_provider_tracing_id.GetNext()) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
- // Don't register a dump provider in these cases.
- // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
- if (base::ThreadTaskRunnerHandle::IsSet()) {
- base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- this, "cc::ResourceProvider", base::ThreadTaskRunnerHandle::Get());
- }
-
- if (!compositor_context_provider)
- return;
-}
-
-ResourceProvider::~ResourceProvider() {
- base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
- this);
-
- while (!resources_.empty())
- DeleteResourceInternal(resources_.begin(), FOR_SHUTDOWN);
-
- if (!compositor_context_provider_)
- return;
-
-#if DCHECK_IS_ON()
- // Check that all GL resources has been deleted.
- for (const auto& pair : resources_)
- DCHECK(!pair.second.is_gpu_resource_type());
-#endif // DCHECK_IS_ON()
-}
-
-void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
- DeleteStyle style) {
- TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
- viz::internal::Resource* resource = &it->second;
- DCHECK(resource->exported_count == 0 || style != NORMAL);
-
- // Exported resources are lost on shutdown.
- bool exported_resource_lost =
- style == FOR_SHUTDOWN && resource->exported_count > 0;
- // GPU resources are lost when context is lost.
- bool gpu_resource_lost =
- resource->is_gpu_resource_type() && lost_context_provider_;
- bool lost_resource =
- resource->lost || exported_resource_lost || gpu_resource_lost;
-
- // Wait on sync token before deleting resources we own.
- if (!lost_resource && resource->origin == viz::internal::Resource::INTERNAL)
- WaitSyncTokenInternal(resource);
-
- if (resource->image_id) {
- DCHECK_EQ(resource->origin, viz::internal::Resource::INTERNAL);
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->DestroyImageCHROMIUM(resource->image_id);
- }
-
- if (resource->gl_id) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->DeleteTextures(1, &resource->gl_id);
- resource->gl_id = 0;
- }
-
- if (resource->owned_shared_bitmap) {
- DCHECK_EQ(viz::ResourceType::kBitmap, resource->type);
- resource->shared_bitmap = nullptr;
- resource->pixels = nullptr;
- resource->owned_shared_bitmap = nullptr;
- }
-
- if (resource->gpu_memory_buffer) {
- DCHECK_EQ(viz::ResourceType::kGpuMemoryBuffer, resource->type);
- resource->gpu_memory_buffer = nullptr;
- }
-
- resources_.erase(it);
-}
-
-GLenum ResourceProvider::GetResourceTextureTarget(viz::ResourceId id) {
- return GetResource(id)->target;
-}
-
-viz::internal::Resource* ResourceProvider::InsertResource(
- viz::ResourceId id,
- viz::internal::Resource resource) {
- std::pair<ResourceMap::iterator, bool> result =
- resources_.insert(ResourceMap::value_type(id, std::move(resource)));
- DCHECK(result.second);
- return &result.first->second;
-}
-
-viz::internal::Resource* ResourceProvider::GetResource(viz::ResourceId id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(id);
- ResourceMap::iterator it = resources_.find(id);
- DCHECK(it != resources_.end());
- return &it->second;
-}
-
-viz::internal::Resource* ResourceProvider::TryGetResource(viz::ResourceId id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!id)
- return nullptr;
- ResourceMap::iterator it = resources_.find(id);
- if (it == resources_.end())
- return nullptr;
- return &it->second;
-}
-
-void ResourceProvider::PopulateSkBitmapWithResource(
- SkBitmap* sk_bitmap,
- const viz::internal::Resource* resource) {
- DCHECK(IsBitmapFormatSupported(resource->format));
- SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
- resource->size.height());
- bool pixels_installed =
- sk_bitmap->installPixels(info, resource->pixels, info.minRowBytes());
- DCHECK(pixels_installed);
-}
-
-void ResourceProvider::WaitSyncTokenInternal(
- viz::internal::Resource* resource) {
- DCHECK(resource);
- if (!resource->ShouldWaitSyncToken())
- return;
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- // In the case of context lost, this sync token may be empty (see comment in
- // the UpdateSyncToken() function). The WaitSyncTokenCHROMIUM() function
- // handles empty sync tokens properly so just wait anyways and update the
- // state the synchronized.
- gl->WaitSyncTokenCHROMIUM(resource->sync_token().GetConstData());
- resource->SetSynchronized();
-}
-
-GLES2Interface* ResourceProvider::ContextGL() const {
- viz::ContextProvider* context_provider = compositor_context_provider_;
- return context_provider ? context_provider->ContextGL() : nullptr;
-}
-
-bool ResourceProvider::OnMemoryDump(
- const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- const uint64_t tracing_process_id =
- base::trace_event::MemoryDumpManager::GetInstance()
- ->GetTracingProcessId();
-
- for (const auto& resource_entry : resources_) {
- const auto& resource = resource_entry.second;
-
- bool backing_memory_allocated = false;
- switch (resource.type) {
- case viz::ResourceType::kGpuMemoryBuffer:
- backing_memory_allocated = !!resource.gpu_memory_buffer;
- break;
- case viz::ResourceType::kTexture:
- backing_memory_allocated = !!resource.gl_id;
- break;
- case viz::ResourceType::kBitmap:
- backing_memory_allocated = !!resource.shared_bitmap;
- break;
- }
-
- if (!backing_memory_allocated) {
- // Don't log unallocated resources - they have no backing memory.
- continue;
- }
-
- // ResourceIds are not process-unique, so log with the ResourceProvider's
- // unique id.
- std::string dump_name =
- base::StringPrintf("cc/resource_memory/provider_%d/resource_%d",
- tracing_id_, resource_entry.first);
- base::trace_event::MemoryAllocatorDump* dump =
- pmd->CreateAllocatorDump(dump_name);
-
- // Texture resources may not come with a size, in which case don't report
- // one.
- if (!resource.size.IsEmpty()) {
- uint64_t total_bytes =
- viz::ResourceSizes::UncheckedSizeInBytesAligned<size_t>(
- resource.size, resource.format);
- dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- static_cast<uint64_t>(total_bytes));
- }
-
- // Resources may be shared across processes and require a shared GUID to
- // prevent double counting the memory.
- base::trace_event::MemoryAllocatorDumpGuid guid;
- base::UnguessableToken shared_memory_guid;
- switch (resource.type) {
- case viz::ResourceType::kGpuMemoryBuffer:
- // GpuMemoryBuffers may be backed by shared memory, and in that case we
- // use the guid from there to attribute for the global shared memory
- // dumps. Otherwise, they may be backed by native structures, and we
- // fall back to that with GetGUIDForTracing.
- shared_memory_guid =
- resource.gpu_memory_buffer->GetHandle().handle.GetGUID();
- if (shared_memory_guid.is_empty()) {
- guid =
- resource.gpu_memory_buffer->GetGUIDForTracing(tracing_process_id);
- }
- break;
- case viz::ResourceType::kTexture:
- DCHECK(resource.gl_id);
- guid = gl::GetGLTextureClientGUIDForTracing(
- compositor_context_provider_->ContextSupport()
- ->ShareGroupTracingGUID(),
- resource.gl_id);
- break;
- case viz::ResourceType::kBitmap:
- // If the resource comes from out of process, it will have this id,
- // which we prefer. Otherwise, we fall back to the SharedBitmapGUID
- // which can be generated for in-process bitmaps.
- shared_memory_guid = resource.shared_bitmap->GetCrossProcessGUID();
- if (shared_memory_guid.is_empty())
- guid = viz::GetSharedBitmapGUIDForTracing(resource.shared_bitmap_id);
- break;
- }
-
- DCHECK(!shared_memory_guid.is_empty() || !guid.empty());
-
- const int kImportanceForInteral = 2;
- const int kImportanceForExternal = 1;
- int importance = resource.origin == viz::internal::Resource::INTERNAL
- ? kImportanceForInteral
- : kImportanceForExternal;
- if (!shared_memory_guid.is_empty()) {
- pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid,
- importance);
- } else {
- pmd->CreateSharedGlobalAllocatorDump(guid);
- pmd->AddOwnershipEdge(dump->guid(), guid, importance);
- }
- }
-
- return true;
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/resource_provider.h b/chromium/cc/resources/resource_provider.h
deleted file mode 100644
index 31e46d23620..00000000000
--- a/chromium/cc/resources/resource_provider.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2012 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_RESOURCES_RESOURCE_PROVIDER_H_
-#define CC_RESOURCES_RESOURCE_PROVIDER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/small_map.h"
-#include "base/macros.h"
-#include "base/memory/linked_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "cc/cc_export.h"
-#include "cc/resources/return_callback.h"
-#include "components/viz/common/resources/release_callback.h"
-#include "components/viz/common/resources/resource.h"
-#include "components/viz/common/resources/resource_id.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace viz {
-class ContextProvider;
-} // namespace viz
-
-namespace cc {
-
-// This class provides abstractions for allocating and transferring resources
-// between modules/threads/processes. It abstracts away GL textures vs
-// GpuMemoryBuffers vs software bitmaps behind a single ResourceId so that
-// code in common can hold onto ResourceIds, as long as the code using them
-// knows the correct type.
-//
-// The resource's underlying type is accessed through Read and Write locks that
-// help to safeguard correct usage with DCHECKs. All resources held in
-// ResourceProvider are immutable - they can not change format or size once
-// they are created, only their contents.
-//
-// This class is not thread-safe and can only be called from the thread it was
-// created on (in practice, the impl thread).
-class CC_EXPORT ResourceProvider
- : public base::trace_event::MemoryDumpProvider {
- public:
- using ResourceIdArray = std::vector<viz::ResourceId>;
- using ResourceIdMap = std::unordered_map<viz::ResourceId, viz::ResourceId>;
-
- explicit ResourceProvider(viz::ContextProvider* compositor_context_provider);
- ~ResourceProvider() override;
-
- bool IsSoftware() const { return !compositor_context_provider_; }
-
- void DidLoseContextProvider() { lost_context_provider_ = true; }
-
- size_t num_resources() const { return resources_.size(); }
-
- GLenum GetResourceTextureTarget(viz::ResourceId id);
-
- // base::trace_event::MemoryDumpProvider implementation.
- bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) override;
-
- int tracing_id() const { return tracing_id_; }
-
- protected:
- using ResourceMap =
- std::unordered_map<viz::ResourceId, viz::internal::Resource>;
-
- viz::internal::Resource* InsertResource(viz::ResourceId id,
- viz::internal::Resource resource);
- viz::internal::Resource* GetResource(viz::ResourceId id);
-
- // TODO(ericrk): TryGetResource is part of a temporary workaround for cases
- // where resources which should be available are missing. This version may
- // return nullptr if a resource is not found. https://crbug.com/811858
- viz::internal::Resource* TryGetResource(viz::ResourceId id);
-
- void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
- const viz::internal::Resource* resource);
-
- enum DeleteStyle {
- NORMAL,
- FOR_SHUTDOWN,
- };
-
- void DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style);
-
- void WaitSyncTokenInternal(viz::internal::Resource* resource);
-
- // Returns null if we do not have a viz::ContextProvider.
- gpu::gles2::GLES2Interface* ContextGL() const;
-
- ResourceMap resources_;
-
- viz::ContextProvider* compositor_context_provider_;
-
- bool lost_context_provider_;
-
- THREAD_CHECKER(thread_checker_);
-
- private:
- // A process-unique ID used for disambiguating memory dumps from different
- // resource providers.
- int tracing_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RESOURCE_PROVIDER_H_
diff --git a/chromium/cc/resources/resource_provider_unittest.cc b/chromium/cc/resources/resource_provider_unittest.cc
deleted file mode 100644
index b569bcdd8a7..00000000000
--- a/chromium/cc/resources/resource_provider_unittest.cc
+++ /dev/null
@@ -1,3709 +0,0 @@
-// Copyright 2012 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/resources/display_resource_provider.h"
-#include "cc/resources/layer_tree_resource_provider.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/resource_provider_test_utils.h"
-#include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "components/viz/test/test_context_provider.h"
-#include "components/viz/test/test_gpu_memory_buffer_manager.h"
-#include "components/viz/test/test_shared_bitmap_manager.h"
-#include "components/viz/test/test_texture.h"
-#include "components/viz/test/test_web_graphics_context_3d.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-using testing::InSequence;
-using testing::Mock;
-using testing::NiceMock;
-using testing::Return;
-using testing::StrictMock;
-using testing::_;
-using testing::AnyNumber;
-
-namespace cc {
-namespace {
-
-static const bool kUseGpuMemoryBufferResources = false;
-static const bool kDelegatedSyncPointsRequired = true;
-
-MATCHER_P(MatchesSyncToken, sync_token, "") {
- gpu::SyncToken other;
- memcpy(&other, arg, sizeof(other));
- return other == sync_token;
-}
-
-static void ReleaseCallback(gpu::SyncToken* release_sync_token,
- bool* release_lost_resource,
- const gpu::SyncToken& sync_token,
- bool lost_resource) {
- *release_sync_token = sync_token;
- *release_lost_resource = lost_resource;
-}
-
-static void ReleaseSharedBitmapCallback(
- std::unique_ptr<viz::SharedBitmap> shared_bitmap,
- bool* release_called,
- gpu::SyncToken* release_sync_token,
- bool* lost_resource_result,
- const gpu::SyncToken& sync_token,
- bool lost_resource) {
- *release_called = true;
- *release_sync_token = sync_token;
- *lost_resource_result = lost_resource;
-}
-
-static std::unique_ptr<viz::SharedBitmap> CreateAndFillSharedBitmap(
- viz::SharedBitmapManager* manager,
- const gfx::Size& size,
- viz::ResourceFormat format,
- uint32_t value) {
- std::unique_ptr<viz::SharedBitmap> shared_bitmap =
- manager->AllocateSharedBitmap(size, format);
- CHECK(shared_bitmap);
- uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels());
- CHECK(pixels);
- std::fill_n(pixels, size.GetArea(), value);
- return shared_bitmap;
-}
-
-static viz::ResourceSettings CreateResourceSettings() {
- viz::ResourceSettings resource_settings;
- resource_settings.use_gpu_memory_buffer_resources =
- kUseGpuMemoryBufferResources;
- return resource_settings;
-}
-
-class TextureStateTrackingContext : public viz::TestWebGraphicsContext3D {
- public:
- MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
- MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
- MOCK_METHOD1(waitSyncToken, void(const GLbyte* sync_token));
- MOCK_METHOD2(produceTextureDirectCHROMIUM,
- void(GLuint texture, const GLbyte* mailbox));
- MOCK_METHOD1(createAndConsumeTextureCHROMIUM,
- unsigned(const GLbyte* mailbox));
-
- // Force all textures to be consecutive numbers starting at "1",
- // so we easily can test for them.
- GLuint NextTextureId() override {
- base::AutoLock lock(namespace_->lock);
- return namespace_->next_texture_id++;
- }
-
- void RetireTextureId(GLuint) override {}
-
- void genSyncToken(GLbyte* sync_token) override {
- gpu::SyncToken sync_token_data(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x123),
- next_fence_sync_++);
- sync_token_data.SetVerifyFlush();
- memcpy(sync_token, &sync_token_data, sizeof(sync_token_data));
- }
-
- GLuint64 GetNextFenceSync() const { return next_fence_sync_; }
-
- GLuint64 next_fence_sync_ = 1;
-};
-
-// Shared data between multiple ResourceProviderContext. This contains mailbox
-// contents as well as information about sync points.
-class ContextSharedData {
- public:
- static std::unique_ptr<ContextSharedData> Create() {
- return base::WrapUnique(new ContextSharedData());
- }
-
- uint32_t InsertFenceSync() { return next_fence_sync_++; }
-
- void GenMailbox(GLbyte* mailbox) {
- memset(mailbox, 0, GL_MAILBOX_SIZE_CHROMIUM);
- memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
- ++next_mailbox_;
- }
-
- void ProduceTexture(const GLbyte* mailbox_name,
- const gpu::SyncToken& sync_token,
- scoped_refptr<viz::TestTexture> texture) {
- uint32_t sync_point = static_cast<uint32_t>(sync_token.release_count());
-
- unsigned mailbox = 0;
- memcpy(&mailbox, mailbox_name, sizeof(mailbox));
- ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
- textures_[mailbox] = texture;
- ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
- sync_point_for_mailbox_[mailbox] = sync_point;
- }
-
- scoped_refptr<viz::TestTexture> ConsumeTexture(
- const GLbyte* mailbox_name,
- const gpu::SyncToken& sync_token) {
- unsigned mailbox = 0;
- memcpy(&mailbox, mailbox_name, sizeof(mailbox));
- DCHECK(mailbox && mailbox < next_mailbox_);
-
- // If the latest sync point the context has waited on is before the sync
- // point for when the mailbox was set, pretend we never saw that
- // ProduceTexture.
- if (sync_point_for_mailbox_[mailbox] > sync_token.release_count()) {
- NOTREACHED();
- return scoped_refptr<viz::TestTexture>();
- }
- return textures_[mailbox];
- }
-
- private:
- ContextSharedData() : next_fence_sync_(1), next_mailbox_(1) {}
-
- uint64_t next_fence_sync_;
- unsigned next_mailbox_;
- using TextureMap =
- std::unordered_map<unsigned, scoped_refptr<viz::TestTexture>>;
- TextureMap textures_;
- std::unordered_map<unsigned, uint32_t> sync_point_for_mailbox_;
-};
-
-class ResourceProviderContext : public viz::TestWebGraphicsContext3D {
- public:
- static std::unique_ptr<ResourceProviderContext> Create(
- ContextSharedData* shared_data) {
- return base::WrapUnique(new ResourceProviderContext(shared_data));
- }
-
- void genSyncToken(GLbyte* sync_token) override {
- uint64_t fence_sync = shared_data_->InsertFenceSync();
- gpu::SyncToken sync_token_data(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x123),
- fence_sync);
- sync_token_data.SetVerifyFlush();
- // Commit the ProduceTextureDirectCHROMIUM calls at this point, so that
- // they're associated with the sync point.
- for (const std::unique_ptr<PendingProduceTexture>& pending_texture :
- pending_produce_textures_) {
- shared_data_->ProduceTexture(pending_texture->mailbox, sync_token_data,
- pending_texture->texture);
- }
- pending_produce_textures_.clear();
- memcpy(sync_token, &sync_token_data, sizeof(sync_token_data));
- }
-
- void waitSyncToken(const GLbyte* sync_token) override {
- gpu::SyncToken sync_token_data;
- if (sync_token)
- memcpy(&sync_token_data, sync_token, sizeof(sync_token_data));
-
- if (sync_token_data.release_count() >
- last_waited_sync_token_.release_count()) {
- last_waited_sync_token_ = sync_token_data;
- }
- }
-
- const gpu::SyncToken& last_waited_sync_token() const {
- return last_waited_sync_token_;
- }
-
- void texStorage2DEXT(GLenum target,
- GLint levels,
- GLuint internalformat,
- GLint width,
- GLint height) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_EQ(1, levels);
- GLenum format = GL_RGBA;
- switch (internalformat) {
- case GL_RGBA8_OES:
- break;
- case GL_BGRA8_EXT:
- format = GL_BGRA_EXT;
- break;
- default:
- NOTREACHED();
- }
- AllocateTexture(gfx::Size(width, height), format);
- }
-
- void texImage2D(GLenum target,
- GLint level,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const void* pixels) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_FALSE(level);
- ASSERT_EQ(internalformat, format);
- ASSERT_FALSE(border);
- ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- AllocateTexture(gfx::Size(width, height), format);
- if (pixels)
- SetPixels(0, 0, width, height, pixels);
- }
-
- void texSubImage2D(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels) override {
- CheckTextureIsBound(target);
- ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- ASSERT_FALSE(level);
- ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- {
- base::AutoLock lock_for_texture_access(namespace_->lock);
- ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
- }
- ASSERT_TRUE(pixels);
- SetPixels(xoffset, yoffset, width, height, pixels);
- }
-
- void genMailboxCHROMIUM(GLbyte* mailbox) override {
- return shared_data_->GenMailbox(mailbox);
- }
-
- void produceTextureDirectCHROMIUM(GLuint texture,
- const GLbyte* mailbox) override {
- // Delay moving the texture into the mailbox until the next
- // sync token, so that it is not visible to other contexts that
- // haven't waited on that sync point.
- std::unique_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
- memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
- base::AutoLock lock_for_texture_access(namespace_->lock);
- pending->texture = UnboundTexture(texture);
- pending_produce_textures_.push_back(std::move(pending));
- }
-
- GLuint createAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override {
- GLuint texture_id = createTexture();
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture =
- shared_data_->ConsumeTexture(mailbox, last_waited_sync_token_);
- namespace_->textures.Replace(texture_id, texture);
- return texture_id;
- }
-
- void GetPixels(const gfx::Size& size,
- viz::ResourceFormat format,
- uint8_t* pixels) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
- ASSERT_EQ(texture->size, size);
- ASSERT_EQ(texture->format, format);
- memcpy(pixels, texture->data.get(), TextureSizeBytes(size, format));
- }
-
- protected:
- explicit ResourceProviderContext(ContextSharedData* shared_data)
- : shared_data_(shared_data) {}
-
- private:
- void AllocateTexture(const gfx::Size& size, GLenum format) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- viz::ResourceFormat texture_format = viz::RGBA_8888;
- switch (format) {
- case GL_RGBA:
- texture_format = viz::RGBA_8888;
- break;
- case GL_BGRA_EXT:
- texture_format = viz::BGRA_8888;
- break;
- }
- base::AutoLock lock_for_texture_access(namespace_->lock);
- BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
- }
-
- void SetPixels(int xoffset,
- int yoffset,
- int width,
- int height,
- const void* pixels) {
- CheckTextureIsBound(GL_TEXTURE_2D);
- base::AutoLock lock_for_texture_access(namespace_->lock);
- scoped_refptr<viz::TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
- ASSERT_TRUE(texture->data.get());
- ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
- ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
- ASSERT_TRUE(pixels);
- size_t in_pitch = TextureSizeBytes(gfx::Size(width, 1), texture->format);
- size_t out_pitch =
- TextureSizeBytes(gfx::Size(texture->size.width(), 1), texture->format);
- uint8_t* dest = texture->data.get() + yoffset * out_pitch +
- TextureSizeBytes(gfx::Size(xoffset, 1), texture->format);
- const uint8_t* src = static_cast<const uint8_t*>(pixels);
- for (int i = 0; i < height; ++i) {
- memcpy(dest, src, in_pitch);
- dest += out_pitch;
- src += in_pitch;
- }
- }
-
- struct PendingProduceTexture {
- GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
- scoped_refptr<viz::TestTexture> texture;
- };
- ContextSharedData* shared_data_;
- gpu::SyncToken last_waited_sync_token_;
- std::vector<std::unique_ptr<PendingProduceTexture>> pending_produce_textures_;
-};
-
-void GetResourcePixels(DisplayResourceProvider* resource_provider,
- ResourceProviderContext* context,
- viz::ResourceId id,
- const gfx::Size& size,
- viz::ResourceFormat format,
- uint8_t* pixels) {
- resource_provider->WaitSyncToken(id);
- if (resource_provider->IsSoftware()) {
- DisplayResourceProvider::ScopedReadLockSoftware lock_software(
- resource_provider, id);
- memcpy(pixels, lock_software.sk_bitmap()->getPixels(),
- lock_software.sk_bitmap()->computeByteSize());
- } else {
- DisplayResourceProvider::ScopedReadLockGL lock_gl(resource_provider, id);
- ASSERT_NE(0U, lock_gl.texture_id());
- context->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
- context->GetPixels(size, format, pixels);
- }
-}
-
-class ResourceProviderTest : public testing::TestWithParam<bool> {
- public:
- explicit ResourceProviderTest(bool child_needs_sync_token)
- : use_gpu_(GetParam()),
- child_needs_sync_token_(child_needs_sync_token),
- shared_data_(ContextSharedData::Create()) {
- if (use_gpu_) {
- auto context3d(ResourceProviderContext::Create(shared_data_.get()));
- context3d_ = context3d.get();
- context_provider_ =
- viz::TestContextProvider::Create(std::move(context3d));
- context_provider_->UnboundTestContext3d()
- ->set_support_texture_format_bgra8888(true);
- context_provider_->BindToCurrentThread();
-
- auto child_context_owned =
- ResourceProviderContext::Create(shared_data_.get());
- child_context_ = child_context_owned.get();
- child_context_provider_ =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider_->UnboundTestContext3d()
- ->set_support_texture_format_bgra8888(true);
- child_context_provider_->BindToCurrentThread();
- gpu_memory_buffer_manager_ =
- std::make_unique<viz::TestGpuMemoryBufferManager>();
- child_gpu_memory_buffer_manager_ =
- gpu_memory_buffer_manager_->CreateClientGpuMemoryBufferManager();
- } else {
- shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
- }
-
- resource_provider_ = std::make_unique<DisplayResourceProvider>(
- context_provider_.get(), shared_bitmap_manager_.get());
-
- MakeChildResourceProvider();
- }
-
- ResourceProviderTest() : ResourceProviderTest(true) {}
-
- bool use_gpu() const { return use_gpu_; }
-
- void MakeChildResourceProvider() {
- child_resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
- child_context_provider_.get(), shared_bitmap_manager_.get(),
- child_gpu_memory_buffer_manager_.get(), child_needs_sync_token_,
- CreateResourceSettings());
- }
-
- static void CollectResources(
- std::vector<viz::ReturnedResource>* array,
- const std::vector<viz::ReturnedResource>& returned) {
- array->insert(array->end(), returned.begin(), returned.end());
- }
-
- static ReturnCallback GetReturnCallback(
- std::vector<viz::ReturnedResource>* array) {
- return base::Bind(&ResourceProviderTest::CollectResources, array);
- }
-
- static void SetResourceFilter(DisplayResourceProvider* resource_provider,
- viz::ResourceId id,
- GLenum filter) {
- DisplayResourceProvider::ScopedSamplerGL sampler(resource_provider, id,
- GL_TEXTURE_2D, filter);
- }
-
- ResourceProviderContext* context() { return context3d_; }
-
- viz::ResourceId CreateChildMailbox(gpu::SyncToken* release_sync_token,
- bool* lost_resource,
- bool* release_called,
- gpu::SyncToken* sync_token,
- viz::ResourceFormat format) {
- if (use_gpu()) {
- unsigned texture = child_context_->createTexture();
- gpu::Mailbox gpu_mailbox;
- child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
- child_context_->produceTextureDirectCHROMIUM(texture, gpu_mailbox.name);
- child_context_->genSyncToken(sync_token->GetData());
- EXPECT_TRUE(sync_token->HasData());
-
- std::unique_ptr<viz::SharedBitmap> shared_bitmap;
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
- ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
- release_called, release_sync_token, lost_resource));
- viz::TransferableResource gl_resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, *sync_token);
- gl_resource.format = format;
- return child_resource_provider_->ImportResource(gl_resource,
- std::move(callback));
- } else {
- gfx::Size size(64, 64);
- std::unique_ptr<viz::SharedBitmap> shared_bitmap(
- CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, format,
- 0));
-
- viz::SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::Bind(
- ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
- release_called, release_sync_token, lost_resource));
- return child_resource_provider_->ImportResource(
- viz::TransferableResource::MakeSoftware(
- shared_bitmap_ptr->id(), shared_bitmap_ptr->sequence_number(),
- size, format),
- std::move(callback));
- }
- }
-
- viz::ResourceId MakeGpuResourceAndSendToDisplay(
- char c,
- GLuint filter,
- GLuint target,
- const gpu::SyncToken& sync_token,
- DisplayResourceProvider* resource_provider) {
- ReturnCallback return_callback = base::DoNothing();
-
- int child = resource_provider->CreateChild(return_callback);
-
- gpu::Mailbox gpu_mailbox;
- gpu_mailbox.name[0] = c;
- gpu_mailbox.name[1] = 0;
- auto resource = viz::TransferableResource::MakeGL(gpu_mailbox, GL_LINEAR,
- target, sync_token);
- resource.id = 11;
- resource_provider->ReceiveFromChild(child, {resource});
- auto& map = resource_provider->GetChildToParentMap(child);
- return map.find(resource.id)->second;
- }
-
- protected:
- const bool use_gpu_;
- const bool child_needs_sync_token_;
- const std::unique_ptr<ContextSharedData> shared_data_;
- ResourceProviderContext* context3d_ = nullptr;
- ResourceProviderContext* child_context_ = nullptr;
- scoped_refptr<viz::TestContextProvider> context_provider_;
- scoped_refptr<viz::TestContextProvider> child_context_provider_;
- std::unique_ptr<viz::TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
- std::unique_ptr<DisplayResourceProvider> resource_provider_;
- std::unique_ptr<viz::TestGpuMemoryBufferManager>
- child_gpu_memory_buffer_manager_;
- std::unique_ptr<LayerTreeResourceProvider> child_resource_provider_;
- std::unique_ptr<viz::TestSharedBitmapManager> shared_bitmap_manager_;
-};
-
-TEST_P(ResourceProviderTest, Basic) {
- DCHECK_EQ(resource_provider_->IsSoftware(), !use_gpu());
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id;
- if (!use_gpu()) {
- id = child_resource_provider_->CreateBitmapResource(size, gfx::ColorSpace(),
- format);
- } else {
- id = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- }
- EXPECT_EQ(1, static_cast<int>(child_resource_provider_->num_resources()));
- if (use_gpu())
- EXPECT_EQ(0u, context()->NumTextures());
-
- uint8_t data[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id, data, size);
- if (use_gpu())
- EXPECT_EQ(1u, context()->NumTextures());
-
- // Give the resource to the parent to read its pixels.
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id}, &list);
- resource_provider_->ReceiveFromChild(child_id, list);
- auto id_map = resource_provider_->GetChildToParentMap(child_id);
-
- uint8_t result[4] = {0};
- GetResourcePixels(resource_provider_.get(), context(), id_map[id], size,
- format, result);
- EXPECT_EQ(0, memcmp(data, result, pixel_size));
-
- // Give it back to the child.
- resource_provider_->DeclareUsedResourcesFromChild(child_id, {});
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-
- child_resource_provider_->DeleteResource(id);
- EXPECT_EQ(0, static_cast<int>(child_resource_provider_->num_resources()));
- if (use_gpu())
- EXPECT_EQ(0u, context()->NumTextures());
-}
-
-TEST_P(ResourceProviderTest, SimpleUpload) {
- gfx::Size size(2, 2);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(16U, pixel_size);
-
- viz::ResourceId id1;
- viz::ResourceId id2;
- if (use_gpu()) {
- id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
-
- } else {
- id1 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- id2 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- }
-
- uint8_t image[16] = {0};
- child_resource_provider_->CopyToResource(id1, image, size);
-
- for (uint8_t i = 0; i < pixel_size; ++i)
- image[i] = i;
- child_resource_provider_->CopyToResource(id2, image, size);
-
- // Return the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- SendResourceAndGetChildToParentMap({id1, id2}, resource_provider_.get(),
- child_resource_provider_.get());
- viz::ResourceId mapped_id1 = resource_map[id1];
- viz::ResourceId mapped_id2 = resource_map[id2];
-
- {
- uint8_t result[16] = {0};
- uint8_t expected[16] = {0};
- GetResourcePixels(resource_provider_.get(), context(), mapped_id1, size,
- format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
-
- {
- uint8_t result[16] = {0};
- uint8_t expected[16] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- GetResourcePixels(resource_provider_.get(), context(), mapped_id2, size,
- format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
-}
-
-TEST_P(ResourceProviderTest, TransferGLResources) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- // Use some non-default format to detect when defaults aren't changed
- // correctly.
- viz::ResourceFormat format = viz::BGRA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- gfx::ColorSpace color_space1 = gfx::ColorSpace::CreateSRGB();
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, color_space1);
- uint8_t data1[4] = { 1, 2, 3, 4 };
- child_resource_provider_->CopyToResource(id1, data1, size);
-
- viz::ResourceId id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data2[4] = { 5, 5, 5, 5 };
- child_resource_provider_->CopyToResource(id2, data2, size);
-
- viz::ResourceId id3 = child_resource_provider_->CreateGpuMemoryBufferResource(
- size, viz::ResourceTextureHint::kDefault, format,
- gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::ColorSpace());
- {
- LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
- child_resource_provider_.get(), id3);
- EXPECT_TRUE(lock.GetGpuMemoryBuffer());
- }
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
- resource_ids_to_transfer.push_back(id3);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(3u, list.size());
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[1].mailbox_holder.sync_token.HasData());
- EXPECT_EQ(list[0].mailbox_holder.sync_token,
- list[1].mailbox_holder.sync_token);
- EXPECT_TRUE(list[2].mailbox_holder.sync_token.HasData());
- EXPECT_EQ(list[0].mailbox_holder.sync_token,
- list[2].mailbox_holder.sync_token);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[0].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[1].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[2].mailbox_holder.texture_target);
- EXPECT_EQ(list[0].buffer_format, gfx::BufferFormat::RGBA_8888);
- EXPECT_EQ(list[1].buffer_format, gfx::BufferFormat::RGBA_8888);
- EXPECT_EQ(list[2].buffer_format, gfx::BufferFormat::BGRA_8888);
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
- resource_provider_->ReceiveFromChild(child_id, list);
- EXPECT_NE(list[0].mailbox_holder.sync_token,
- context3d_->last_waited_sync_token());
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- {
- viz::ResourceId mapped_resource_id = resource_map[list[0].id];
- resource_provider_->WaitSyncToken(mapped_resource_id);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- mapped_resource_id);
- }
- EXPECT_EQ(list[0].mailbox_holder.sync_token,
- context3d_->last_waited_sync_token());
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_ids_to_receive.insert(id3);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
-
- EXPECT_EQ(3u, resource_provider_->num_resources());
- viz::ResourceId mapped_id1 = resource_map[id1];
- viz::ResourceId mapped_id2 = resource_map[id2];
- viz::ResourceId mapped_id3 = resource_map[id3];
- EXPECT_NE(0u, mapped_id1);
- EXPECT_NE(0u, mapped_id2);
- EXPECT_NE(0u, mapped_id3);
- EXPECT_FALSE(resource_provider_->InUse(mapped_id1));
- EXPECT_FALSE(resource_provider_->InUse(mapped_id2));
- EXPECT_FALSE(resource_provider_->InUse(mapped_id3));
-
- uint8_t result[4] = { 0 };
- GetResourcePixels(
- resource_provider_.get(), context(), mapped_id1, size, format, result);
- EXPECT_EQ(0, memcmp(data1, result, pixel_size));
-
- GetResourcePixels(
- resource_provider_.get(), context(), mapped_id2, size, format, result);
- EXPECT_EQ(0, memcmp(data2, result, pixel_size));
-
- EXPECT_FALSE(resource_provider_->IsOverlayCandidate(mapped_id1));
- EXPECT_FALSE(resource_provider_->IsOverlayCandidate(mapped_id2));
- EXPECT_TRUE(resource_provider_->IsOverlayCandidate(mapped_id3));
-
- {
- resource_provider_->WaitSyncToken(mapped_id1);
- DisplayResourceProvider::ScopedReadLockGL lock1(resource_provider_.get(),
- mapped_id1);
- EXPECT_TRUE(lock1.color_space() == color_space1);
- }
-
- {
- // Check that transfering again the same resource from the child to the
- // parent works.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
- resource_ids_to_transfer.push_back(id3);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- EXPECT_EQ(3u, list.size());
- EXPECT_EQ(id1, list[0].id);
- EXPECT_EQ(id2, list[1].id);
- EXPECT_EQ(id3, list[2].id);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[0].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[1].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[2].mailbox_holder.texture_target);
- EXPECT_EQ(list[0].buffer_format, gfx::BufferFormat::RGBA_8888);
- EXPECT_EQ(list[1].buffer_format, gfx::BufferFormat::RGBA_8888);
- EXPECT_EQ(list[2].buffer_format, gfx::BufferFormat::BGRA_8888);
- std::vector<viz::ReturnedResource> returned =
- viz::TransferableResource::ReturnResources(list);
- child_resource_provider_->ReceiveReturnsFromParent(returned);
- // ids were exported twice, we returned them only once, they should still
- // be in-use.
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
- }
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- ASSERT_EQ(3u, returned_to_child.size());
- EXPECT_TRUE(returned_to_child[0].sync_token.HasData());
- EXPECT_TRUE(returned_to_child[1].sync_token.HasData());
- EXPECT_TRUE(returned_to_child[2].sync_token.HasData());
- EXPECT_FALSE(returned_to_child[0].lost);
- EXPECT_FALSE(returned_to_child[1].lost);
- EXPECT_FALSE(returned_to_child[2].lost);
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- returned_to_child.clear();
- }
- EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
- EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
-
- {
- // ScopedWriteLockGL will wait for the sync token, which is convenient since
- // |child_resource_provider_| doesn't expose that.
- LayerTreeResourceProvider::ScopedWriteLockGL lock(
- child_resource_provider_.get(), id1);
- ASSERT_NE(0U, lock.GetTexture());
- }
- // Ensure copying to resource doesn't fail.
- child_resource_provider_->CopyToResource(id2, data2, size);
- {
- // ScopedWriteLockGL will wait for the sync token.
- LayerTreeResourceProvider::ScopedWriteLockGL lock(
- child_resource_provider_.get(), id2);
- ASSERT_NE(0U, lock.GetTexture());
- }
- {
- // Transfer resources to the parent again.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
- resource_ids_to_transfer.push_back(id3);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(id1, list[0].id);
- EXPECT_EQ(id2, list[1].id);
- EXPECT_EQ(id3, list[2].id);
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[1].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[2].mailbox_holder.sync_token.HasData());
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[0].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[1].mailbox_holder.texture_target);
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[2].mailbox_holder.texture_target);
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_ids_to_receive.insert(id3);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- EXPECT_EQ(0u, returned_to_child.size());
-
- EXPECT_EQ(3u, resource_provider_->num_resources());
- resource_provider_->DestroyChild(child_id);
- EXPECT_EQ(0u, resource_provider_->num_resources());
-
- ASSERT_EQ(3u, returned_to_child.size());
- EXPECT_TRUE(returned_to_child[0].sync_token.HasData());
- EXPECT_TRUE(returned_to_child[1].sync_token.HasData());
- EXPECT_TRUE(returned_to_child[2].sync_token.HasData());
- EXPECT_FALSE(returned_to_child[0].lost);
- EXPECT_FALSE(returned_to_child[1].lost);
- EXPECT_FALSE(returned_to_child[2].lost);
-}
-
-#if defined(OS_ANDROID)
-TEST_P(ResourceProviderTest, OverlayPromotionHint) {
- if (!use_gpu())
- return;
-
- GLuint external_texture_id = child_context_->createExternalTexture();
-
- gpu::Mailbox external_mailbox;
- child_context_->genMailboxCHROMIUM(external_mailbox.name);
- child_context_->produceTextureDirectCHROMIUM(external_texture_id,
- external_mailbox.name);
- gpu::SyncToken external_sync_token;
- child_context_->genSyncToken(external_sync_token.GetData());
- EXPECT_TRUE(external_sync_token.HasData());
-
- viz::TransferableResource id1_transfer =
- viz::TransferableResource::MakeGLOverlay(
- external_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES,
- external_sync_token, gfx::Size(1, 1), true);
- id1_transfer.wants_promotion_hint = true;
- id1_transfer.is_backed_by_surface_texture = true;
- viz::ResourceId id1 = child_resource_provider_->ImportResource(
- id1_transfer, viz::SingleReleaseCallback::Create(base::DoNothing()));
-
- viz::TransferableResource id2_transfer =
- viz::TransferableResource::MakeGLOverlay(
- external_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES,
- external_sync_token, gfx::Size(1, 1), true);
- id2_transfer.wants_promotion_hint = false;
- id2_transfer.is_backed_by_surface_texture = false;
- viz::ResourceId id2 = child_resource_provider_->ImportResource(
- id2_transfer, viz::SingleReleaseCallback::Create(base::DoNothing()));
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- resource_provider_->ReceiveFromChild(child_id, list);
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- viz::ResourceId mapped_id1 = resource_map[list[0].id];
- viz::ResourceId mapped_id2 = resource_map[list[1].id];
-
- // The promotion hints should not be recorded until after we wait. This is
- // because we can't notify them until they're synchronized, and we choose to
- // ignore unwaited resources rather than send them a "no" hint. If they end
- // up in the request set before we wait, then the attempt to notify them wil;
- // DCHECK when we try to lock them for reading in SendPromotionHints.
- EXPECT_EQ(0u, resource_provider_->CountPromotionHintRequestsForTesting());
- {
- resource_provider_->WaitSyncToken(mapped_id1);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- mapped_id1);
- }
- EXPECT_EQ(1u, resource_provider_->CountPromotionHintRequestsForTesting());
-
- EXPECT_EQ(list[0].mailbox_holder.sync_token,
- context3d_->last_waited_sync_token());
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
-
- EXPECT_EQ(2u, resource_provider_->num_resources());
-
- EXPECT_NE(0u, mapped_id1);
- EXPECT_NE(0u, mapped_id2);
-
- // Make sure that the request for a promotion hint was noticed.
- EXPECT_TRUE(resource_provider_->IsOverlayCandidate(mapped_id1));
- EXPECT_TRUE(resource_provider_->IsBackedBySurfaceTexture(mapped_id1));
- EXPECT_TRUE(resource_provider_->WantsPromotionHintForTesting(mapped_id1));
-
- EXPECT_TRUE(resource_provider_->IsOverlayCandidate(mapped_id2));
- EXPECT_FALSE(resource_provider_->IsBackedBySurfaceTexture(mapped_id2));
- EXPECT_FALSE(resource_provider_->WantsPromotionHintForTesting(mapped_id2));
-
- // ResourceProvider maintains a set of promotion hint requests that should be
- // cleared when resources are deleted.
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(2u, returned_to_child.size());
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-
- EXPECT_EQ(0u, resource_provider_->CountPromotionHintRequestsForTesting());
-
- resource_provider_->DestroyChild(child_id);
-}
-#endif
-
-TEST_P(ResourceProviderTest, TransferGLResources_NoSyncToken) {
- if (!use_gpu())
- return;
-
- bool need_sync_tokens = false;
- auto no_token_resource_provider = std::make_unique<LayerTreeResourceProvider>(
- child_context_provider_.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), need_sync_tokens,
- CreateResourceSettings());
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1 = no_token_resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data1[4] = {1, 2, 3, 4};
- no_token_resource_provider->CopyToResource(id1, data1, size);
-
- viz::ResourceId id2 =
- no_token_resource_provider->CreateGpuMemoryBufferResource(
- size, viz::ResourceTextureHint::kDefault, format,
- gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::ColorSpace());
- {
- // Ensure locking the memory buffer doesn't create an unnecessary sync
- // point.
- LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
- no_token_resource_provider.get(), id2);
- EXPECT_TRUE(lock.GetGpuMemoryBuffer());
- }
-
- GLuint external_texture_id = child_context_->createExternalTexture();
-
- // A sync point is specified directly and should be used.
- gpu::Mailbox external_mailbox;
- child_context_->genMailboxCHROMIUM(external_mailbox.name);
- child_context_->produceTextureDirectCHROMIUM(external_texture_id,
- external_mailbox.name);
- gpu::SyncToken external_sync_token;
- child_context_->genSyncToken(external_sync_token.GetData());
- EXPECT_TRUE(external_sync_token.HasData());
- viz::ResourceId id3 = no_token_resource_provider->ImportResource(
- viz::TransferableResource::MakeGL(external_mailbox, GL_LINEAR,
- GL_TEXTURE_EXTERNAL_OES,
- external_sync_token),
- viz::SingleReleaseCallback::Create(base::DoNothing()));
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- resource_provider_->SetChildNeedsSyncTokens(child_id, false);
- {
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
- resource_ids_to_transfer.push_back(id3);
- std::vector<viz::TransferableResource> list;
- no_token_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(3u, list.size());
- // Standard resources shouldn't require creating and sending a sync point.
- EXPECT_FALSE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_FALSE(list[1].mailbox_holder.sync_token.HasData());
- // A given sync point should be passed through.
- EXPECT_EQ(external_sync_token, list[2].mailbox_holder.sync_token);
- resource_provider_->ReceiveFromChild(child_id, list);
-
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_ids_to_receive.insert(id3);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- ASSERT_EQ(3u, returned_to_child.size());
- std::map<viz::ResourceId, gpu::SyncToken> returned_sync_tokens;
- for (const auto& returned : returned_to_child)
- returned_sync_tokens[returned.id] = returned.sync_token;
-
- ASSERT_TRUE(returned_sync_tokens.find(id1) != returned_sync_tokens.end());
- // No new sync point should be created transferring back.
- ASSERT_TRUE(returned_sync_tokens.find(id1) != returned_sync_tokens.end());
- EXPECT_FALSE(returned_sync_tokens[id1].HasData());
- ASSERT_TRUE(returned_sync_tokens.find(id2) != returned_sync_tokens.end());
- EXPECT_FALSE(returned_sync_tokens[id2].HasData());
- // Original sync point given should be returned.
- ASSERT_TRUE(returned_sync_tokens.find(id3) != returned_sync_tokens.end());
- EXPECT_EQ(external_sync_token, returned_sync_tokens[id3]);
- EXPECT_FALSE(returned_to_child[0].lost);
- EXPECT_FALSE(returned_to_child[1].lost);
- EXPECT_FALSE(returned_to_child[2].lost);
- no_token_resource_provider->ReceiveReturnsFromParent(returned_to_child);
- returned_to_child.clear();
- }
-
- resource_provider_->DestroyChild(child_id);
-}
-
-// Test that SetBatchReturnResources batching works.
-TEST_P(ResourceProviderTest, SetBatchPreventsReturn) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- uint8_t data1[4] = {1, 2, 3, 4};
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- viz::ResourceId ids[2];
- for (size_t i = 0; i < arraysize(ids); i++) {
- ids[i] = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- child_resource_provider_->CopyToResource(ids[i], data1, size);
- resource_ids_to_transfer.push_back(ids[i]);
- }
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(ids[0]));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(ids[1]));
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
-
- std::vector<std::unique_ptr<DisplayResourceProvider::ScopedReadLockGL>>
- read_locks;
- for (auto& resource_id : list) {
- unsigned int mapped_resource_id = resource_map[resource_id.id];
- resource_provider_->WaitSyncToken(mapped_resource_id);
- read_locks.push_back(
- std::make_unique<DisplayResourceProvider::ScopedReadLockGL>(
- resource_provider_.get(), mapped_resource_id));
- }
-
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- std::unique_ptr<DisplayResourceProvider::ScopedBatchReturnResources>
- returner =
- std::make_unique<DisplayResourceProvider::ScopedBatchReturnResources>(
- resource_provider_.get());
- EXPECT_EQ(0u, returned_to_child.size());
-
- read_locks.clear();
- EXPECT_EQ(0u, returned_to_child.size());
-
- returner.reset();
- EXPECT_EQ(2u, returned_to_child.size());
- // All resources in a batch should share a sync token.
- EXPECT_EQ(returned_to_child[0].sync_token, returned_to_child[1].sync_token);
-
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- child_resource_provider_->DeleteResource(ids[0]);
- child_resource_provider_->DeleteResource(ids[1]);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
-}
-
-TEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data1[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data1, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- viz::ResourceId mapped_resource_id = resource_map[list[0].id];
- resource_provider_->WaitSyncToken(mapped_resource_id);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- mapped_resource_id);
-
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(0u, returned_to_child.size());
- }
-
- EXPECT_EQ(1u, returned_to_child.size());
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-
- // No need to wait for the sync token here -- it will be returned to the
- // client on delete.
- EXPECT_EQ(1u, child_resource_provider_->num_resources());
- child_resource_provider_->DeleteResource(id1);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
-
- resource_provider_->DestroyChild(child_id);
-}
-
-class TestFence : public viz::ResourceFence {
- public:
- TestFence() = default;
-
- // viz::ResourceFence implementation.
- void Set() override {}
- bool HasPassed() override { return passed; }
- void Wait() override {}
-
- bool passed = false;
-
- private:
- ~TestFence() override = default;
-};
-
-TEST_P(ResourceProviderTest, ReadLockFenceStopsReturnToChildOrDelete) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data1[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data1, size);
- child_resource_provider_->EnableReadLockFencesForTesting(id1);
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(list[0].read_lock_fences_enabled);
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
-
- scoped_refptr<TestFence> fence(new TestFence);
- resource_provider_->SetReadLockFence(fence.get());
- {
- unsigned parent_id = resource_map[list.front().id];
- resource_provider_->WaitSyncToken(parent_id);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- parent_id);
- }
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(0u, returned_to_child.size());
-
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(0u, returned_to_child.size());
- fence->passed = true;
-
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(1u, returned_to_child.size());
-
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- child_resource_provider_->DeleteResource(id1);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
-}
-
-TEST_P(ResourceProviderTest, ReadLockFenceDestroyChild) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data, size);
- child_resource_provider_->EnableReadLockFencesForTesting(id1);
-
- viz::ResourceId id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- child_resource_provider_->CopyToResource(id2, data, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
-
- scoped_refptr<TestFence> fence(new TestFence);
- resource_provider_->SetReadLockFence(fence.get());
- {
- for (size_t i = 0; i < list.size(); i++) {
- unsigned parent_id = resource_map[list[i].id];
- resource_provider_->WaitSyncToken(parent_id);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- parent_id);
- }
- }
- EXPECT_EQ(0u, returned_to_child.size());
-
- EXPECT_EQ(2u, resource_provider_->num_resources());
-
- resource_provider_->DestroyChild(child_id);
-
- EXPECT_EQ(0u, resource_provider_->num_resources());
- EXPECT_EQ(2u, returned_to_child.size());
-
- // id1 should be lost and id2 should not.
- EXPECT_EQ(returned_to_child[0].lost, returned_to_child[0].id == id1);
- EXPECT_EQ(returned_to_child[1].lost, returned_to_child[1].id == id1);
-
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- child_resource_provider_->DeleteResource(id1);
- child_resource_provider_->DeleteResource(id2);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
-}
-
-TEST_P(ResourceProviderTest, ReadLockFenceContextLost) {
- if (!use_gpu())
- return;
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- uint8_t data[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data, size);
- child_resource_provider_->EnableReadLockFencesForTesting(id1);
-
- viz::ResourceId id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- child_resource_provider_->CopyToResource(id2, data, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
- // Transfer resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-
- resource_provider_->ReceiveFromChild(child_id, list);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
-
- scoped_refptr<TestFence> fence(new TestFence);
- resource_provider_->SetReadLockFence(fence.get());
- {
- for (size_t i = 0; i < list.size(); i++) {
- unsigned parent_id = resource_map[list[i].id];
- resource_provider_->WaitSyncToken(parent_id);
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
- parent_id);
- }
- }
- EXPECT_EQ(0u, returned_to_child.size());
-
- EXPECT_EQ(2u, resource_provider_->num_resources());
- resource_provider_->DidLoseContextProvider();
- resource_provider_ = nullptr;
-
- EXPECT_EQ(2u, returned_to_child.size());
-
- EXPECT_TRUE(returned_to_child[0].lost);
- EXPECT_TRUE(returned_to_child[1].lost);
-}
-
-TEST_P(ResourceProviderTest, TransferSoftwareResources) {
- if (use_gpu())
- return;
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- uint8_t data1[4] = { 1, 2, 3, 4 };
- child_resource_provider_->CopyToResource(id1, data1, size);
-
- viz::ResourceId id2 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- uint8_t data2[4] = { 5, 5, 5, 5 };
- child_resource_provider_->CopyToResource(id2, data2, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- EXPECT_FALSE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_FALSE(list[1].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- EXPECT_EQ(2u, resource_provider_->num_resources());
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- viz::ResourceId mapped_id1 = resource_map[id1];
- viz::ResourceId mapped_id2 = resource_map[id2];
- EXPECT_NE(0u, mapped_id1);
- EXPECT_NE(0u, mapped_id2);
- EXPECT_FALSE(resource_provider_->InUse(mapped_id1));
- EXPECT_FALSE(resource_provider_->InUse(mapped_id2));
-
- uint8_t result[4] = { 0 };
- GetResourcePixels(
- resource_provider_.get(), context(), mapped_id1, size, format, result);
- EXPECT_EQ(0, memcmp(data1, result, pixel_size));
-
- GetResourcePixels(
- resource_provider_.get(), context(), mapped_id2, size, format, result);
- EXPECT_EQ(0, memcmp(data2, result, pixel_size));
-
- {
- // Check that transfering again the same resource from the child to the
- // parent works.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- EXPECT_EQ(2u, list.size());
- EXPECT_EQ(id1, list[0].id);
- EXPECT_EQ(id2, list[1].id);
- std::vector<viz::ReturnedResource> returned =
- viz::TransferableResource::ReturnResources(list);
- child_resource_provider_->ReceiveReturnsFromParent(returned);
- // ids were exported twice, we returned them only once, they should still
- // be in-use.
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- }
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- ASSERT_EQ(2u, returned_to_child.size());
- EXPECT_FALSE(returned_to_child[0].sync_token.HasData());
- EXPECT_FALSE(returned_to_child[1].sync_token.HasData());
- std::set<viz::ResourceId> expected_ids;
- expected_ids.insert(id1);
- expected_ids.insert(id2);
- std::set<viz::ResourceId> returned_ids;
- for (unsigned i = 0; i < returned_to_child.size(); i++)
- returned_ids.insert(returned_to_child[i].id);
- EXPECT_EQ(expected_ids, returned_ids);
- EXPECT_FALSE(returned_to_child[0].lost);
- EXPECT_FALSE(returned_to_child[1].lost);
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- returned_to_child.clear();
- }
- EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
-
- {
- LayerTreeResourceProvider::ScopedWriteLockSoftware lock(
- child_resource_provider_.get(), id1);
- const SkBitmap sk_bitmap = lock.sk_bitmap();
- EXPECT_EQ(sk_bitmap.width(), size.width());
- EXPECT_EQ(sk_bitmap.height(), size.height());
- EXPECT_EQ(0, memcmp(data1, sk_bitmap.getPixels(), pixel_size));
- }
- {
- LayerTreeResourceProvider::ScopedWriteLockSoftware lock(
- child_resource_provider_.get(), id2);
- const SkBitmap sk_bitmap = lock.sk_bitmap();
- EXPECT_EQ(sk_bitmap.width(), size.width());
- EXPECT_EQ(sk_bitmap.height(), size.height());
- EXPECT_EQ(0, memcmp(data2, sk_bitmap.getPixels(), pixel_size));
- }
- {
- // Transfer resources to the parent again.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(id1, list[0].id);
- EXPECT_EQ(id2, list[1].id);
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- EXPECT_EQ(0u, returned_to_child.size());
-
- EXPECT_EQ(2u, resource_provider_->num_resources());
- resource_provider_->DestroyChild(child_id);
- EXPECT_EQ(0u, resource_provider_->num_resources());
-
- ASSERT_EQ(2u, returned_to_child.size());
- EXPECT_FALSE(returned_to_child[0].sync_token.HasData());
- EXPECT_FALSE(returned_to_child[1].sync_token.HasData());
- std::set<viz::ResourceId> expected_ids;
- expected_ids.insert(id1);
- expected_ids.insert(id2);
- std::set<viz::ResourceId> returned_ids;
- for (unsigned i = 0; i < returned_to_child.size(); i++)
- returned_ids.insert(returned_to_child[i].id);
- EXPECT_EQ(expected_ids, returned_ids);
- EXPECT_FALSE(returned_to_child[0].lost);
- EXPECT_FALSE(returned_to_child[1].lost);
-}
-
-TEST_P(ResourceProviderTest, TransferGLToSoftware) {
- if (use_gpu())
- return;
-
- scoped_refptr<viz::TestContextProvider> child_context_provider =
- viz::TestContextProvider::Create(
- ResourceProviderContext::Create(shared_data_.get()));
- child_context_provider->BindToCurrentThread();
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- child_context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1 = child_resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, viz::RGBA_8888,
- gfx::ColorSpace());
- uint8_t data1[4] = { 1, 2, 3, 4 };
- child_resource_provider->CopyToResource(id1, data1, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
- list[0].mailbox_holder.texture_target);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
- resource_provider_->ReceiveFromChild(child_id, list);
- }
-
- EXPECT_EQ(0u, resource_provider_->num_resources());
- ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_EQ(returned_to_child[0].id, id1);
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- viz::ResourceId mapped_id1 = resource_map[id1];
- EXPECT_EQ(0u, mapped_id1);
-
- resource_provider_->DestroyChild(child_id);
- EXPECT_EQ(0u, resource_provider_->num_resources());
-
- ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_FALSE(returned_to_child[0].lost);
-}
-
-TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
- if (use_gpu())
- return;
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- uint8_t data1[4] = { 1, 2, 3, 4 };
- child_resource_provider_->CopyToResource(id1, data1, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- // Make invalid.
- list[0].mailbox_holder.mailbox.name[1] ^= 0xff;
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- resource_provider_->ReceiveFromChild(child_id, list);
- }
-
- EXPECT_EQ(1u, resource_provider_->num_resources());
- EXPECT_EQ(0u, returned_to_child.size());
-
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider_->GetChildToParentMap(child_id);
- viz::ResourceId mapped_id1 = resource_map[id1];
- EXPECT_NE(0u, mapped_id1);
- {
- DisplayResourceProvider::ScopedReadLockSoftware lock(
- resource_provider_.get(), mapped_id1);
- EXPECT_FALSE(lock.valid());
- }
-
- resource_provider_->DestroyChild(child_id);
- EXPECT_EQ(0u, resource_provider_->num_resources());
-
- ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_FALSE(returned_to_child[0].lost);
-}
-
-TEST_P(ResourceProviderTest, DeleteExportedResources) {
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1;
- viz::ResourceId id2;
- if (use_gpu()) {
- id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- } else {
- id1 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- id2 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- }
-
- uint8_t data1[4] = { 1, 2, 3, 4 };
- child_resource_provider_->CopyToResource(id1, data1, size);
- uint8_t data2[4] = {5, 5, 5, 5};
- child_resource_provider_->CopyToResource(id2, data2, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- if (use_gpu()) {
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[1].mailbox_holder.sync_token.HasData());
- }
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
-
- std::vector<viz::ReturnedResource> returned =
- viz::TransferableResource::ReturnResources(list);
- child_resource_provider_->ReceiveReturnsFromParent(returned);
- EXPECT_EQ(0u, returned_to_child.size());
- EXPECT_EQ(2u, resource_provider_->num_resources());
-
- // Return the resources from the parent, it should be returned at this
- // point.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
- EXPECT_EQ(2u, returned_to_child.size());
- EXPECT_EQ(0u, resource_provider_->num_resources());
- }
-}
-
-TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id1;
- viz::ResourceId id2;
- if (use_gpu()) {
- id1 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- id2 = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- } else {
- id1 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- id2 = child_resource_provider_->CreateBitmapResource(
- size, gfx::ColorSpace(), format);
- }
-
- uint8_t data1[4] = {1, 2, 3, 4};
- child_resource_provider_->CopyToResource(id1, data1, size);
- uint8_t data2[4] = {5, 5, 5, 5};
- child_resource_provider_->CopyToResource(id2, data2, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer some resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id1);
- resource_ids_to_transfer.push_back(id2);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(2u, list.size());
- if (use_gpu()) {
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[1].mailbox_holder.sync_token.HasData());
- }
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id1);
- resource_ids_to_receive.insert(id2);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
-
- EXPECT_EQ(0u, returned_to_child.size());
- EXPECT_EQ(2u, resource_provider_->num_resources());
- // Destroy the child, the resources should be returned.
- resource_provider_->DestroyChild(child_id);
- EXPECT_EQ(2u, returned_to_child.size());
- EXPECT_EQ(0u, resource_provider_->num_resources());
- }
-}
-
-TEST_P(ResourceProviderTest, DeleteTransferredResources) {
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id;
- if (use_gpu()) {
- id = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- } else {
- id = child_resource_provider_->CreateBitmapResource(size, gfx::ColorSpace(),
- format);
- }
-
- uint8_t data[4] = { 1, 2, 3, 4 };
- child_resource_provider_->CopyToResource(id, data, size);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer some resource to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id);
-
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- if (use_gpu())
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- // Delete textures in the child, while they are transfered.
- child_resource_provider_->DeleteResource(id);
- EXPECT_EQ(1u, child_resource_provider_->num_resources());
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- ASSERT_EQ(1u, returned_to_child.size());
- if (use_gpu())
- EXPECT_TRUE(returned_to_child[0].sync_token.HasData());
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- EXPECT_EQ(0u, child_resource_provider_->num_resources());
- }
-}
-
-class ResourceProviderTestTextureFilters : public ResourceProviderTest {
- public:
- static void RunTest(GLenum child_filter, GLenum parent_filter) {
- auto child_context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* child_context = child_context_owned.get();
-
- auto child_context_provider =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider->BindToCurrentThread();
- auto shared_bitmap_manager =
- std::make_unique<viz::TestSharedBitmapManager>();
-
- viz::ResourceSettings resource_settings = CreateResourceSettings();
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- child_context_provider.get(), shared_bitmap_manager.get(), nullptr,
- kDelegatedSyncPointsRequired, resource_settings));
-
- auto parent_context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* parent_context = parent_context_owned.get();
-
- auto parent_context_provider =
- viz::TestContextProvider::Create(std::move(parent_context_owned));
- parent_context_provider->BindToCurrentThread();
-
- auto parent_resource_provider(std::make_unique<DisplayResourceProvider>(
- parent_context_provider.get(), shared_bitmap_manager.get()));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- int child_texture_id = 1;
- int parent_texture_id = 2;
-
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(4U, pixel_size);
-
- viz::ResourceId id = child_resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
-
- // The new texture is created with GL_LINEAR.
- EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id))
- .Times(2); // Once to create and once to allocate.
- EXPECT_CALL(*child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- EXPECT_CALL(
- *child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- EXPECT_CALL(
- *child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- child_resource_provider->AllocateForTesting(id);
- Mock::VerifyAndClearExpectations(child_context);
-
- uint8_t data[4] = { 1, 2, 3, 4 };
-
- EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
- child_resource_provider->CopyToResource(id, data, size);
- Mock::VerifyAndClearExpectations(child_context);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id = parent_resource_provider->CreateChild(
- GetReturnCallback(&returned_to_child));
-
- // Transfer some resource to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id);
- std::vector<viz::TransferableResource> list;
-
- EXPECT_CALL(*child_context, produceTextureDirectCHROMIUM(_, _));
-
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- Mock::VerifyAndClearExpectations(child_context);
-
- ASSERT_EQ(1u, list.size());
- EXPECT_EQ(static_cast<unsigned>(child_filter), list[0].filter);
-
- EXPECT_CALL(*parent_context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(parent_texture_id));
-
- parent_resource_provider->ReceiveFromChild(child_id, list);
- ResourceProvider::ResourceIdMap resource_map =
- parent_resource_provider->GetChildToParentMap(child_id);
- viz::ResourceId mapped_id = resource_map[id];
- EXPECT_NE(0u, mapped_id);
-
- {
- parent_resource_provider->WaitSyncToken(mapped_id);
- DisplayResourceProvider::ScopedReadLockGL lock(
- parent_resource_provider.get(), mapped_id);
- }
- Mock::VerifyAndClearExpectations(parent_context);
-
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id);
- parent_resource_provider->DeclareUsedResourcesFromChild(
- child_id, resource_ids_to_receive);
- Mock::VerifyAndClearExpectations(parent_context);
-
- // The texture is set to |parent_filter| in the parent.
- EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
- EXPECT_CALL(
- *parent_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, parent_filter));
- EXPECT_CALL(
- *parent_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, parent_filter));
- SetResourceFilter(parent_resource_provider.get(), mapped_id, parent_filter);
- Mock::VerifyAndClearExpectations(parent_context);
-
- // The texture should be reset to |child_filter| in the parent when it is
- // returned, since that is how it was received.
- EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
- EXPECT_CALL(*parent_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*parent_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources
- // as being in use.
- viz::ResourceIdSet no_resources;
- parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
- no_resources);
- Mock::VerifyAndClearExpectations(parent_context);
-
- ASSERT_EQ(1u, returned_to_child.size());
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
- }
- }
-};
-
-TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) {
- if (!use_gpu())
- return;
- ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, TransferMailboxResources) {
- // Other mailbox transfers tested elsewhere.
- if (!use_gpu())
- return;
- unsigned texture = context()->createTexture();
- context()->bindTexture(GL_TEXTURE_2D, texture);
- uint8_t data[4] = { 1, 2, 3, 4 };
- context()->texImage2D(
- GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
- gpu::Mailbox mailbox;
- context()->genMailboxCHROMIUM(mailbox.name);
- context()->produceTextureDirectCHROMIUM(texture, mailbox.name);
- gpu::SyncToken sync_token;
- context()->genSyncToken(sync_token.GetData());
- EXPECT_TRUE(sync_token.HasData());
-
- // All the logic below assumes that the sync token releases are all positive.
- EXPECT_LT(0u, sync_token.release_count());
-
- gpu::SyncToken release_sync_token;
- bool lost_resource = false;
- viz::ReleaseCallback callback =
- base::Bind(ReleaseCallback, &release_sync_token, &lost_resource);
- viz::ResourceId resource = child_resource_provider_->ImportResource(
- viz::TransferableResource::MakeGL(mailbox, GL_LINEAR, GL_TEXTURE_2D,
- sync_token),
- viz::SingleReleaseCallback::Create(std::move(callback)));
- EXPECT_EQ(1u, context()->NumTextures());
- EXPECT_FALSE(release_sync_token.HasData());
- {
- // Transfer the resource, expect the sync points to be consistent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_LE(sync_token.release_count(),
- list[0].mailbox_holder.sync_token.release_count());
- EXPECT_EQ(0,
- memcmp(mailbox.name,
- list[0].mailbox_holder.mailbox.name,
- sizeof(mailbox.name)));
- EXPECT_FALSE(release_sync_token.HasData());
-
- context()->waitSyncToken(list[0].mailbox_holder.sync_token.GetConstData());
- unsigned other_texture =
- context()->createAndConsumeTextureCHROMIUM(mailbox.name);
- uint8_t test_data[4] = { 0 };
- context()->GetPixels(gfx::Size(1, 1), viz::RGBA_8888, test_data);
- EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
-
- context()->produceTextureDirectCHROMIUM(other_texture, mailbox.name);
- context()->deleteTexture(other_texture);
- context()->genSyncToken(list[0].mailbox_holder.sync_token.GetData());
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
-
- // Receive the resource, then delete it, expect the sync points to be
- // consistent.
- std::vector<viz::ReturnedResource> returned =
- viz::TransferableResource::ReturnResources(list);
- child_resource_provider_->ReceiveReturnsFromParent(returned);
- EXPECT_EQ(1u, context()->NumTextures());
- EXPECT_FALSE(release_sync_token.HasData());
-
- child_resource_provider_->RemoveImportedResource(resource);
- EXPECT_LE(list[0].mailbox_holder.sync_token.release_count(),
- release_sync_token.release_count());
- EXPECT_FALSE(lost_resource);
- }
-
- // We're going to do the same thing as above, but testing the case where we
- // delete the resource before we receive it back.
- sync_token = release_sync_token;
- EXPECT_LT(0u, sync_token.release_count());
- release_sync_token.Clear();
- callback = base::Bind(ReleaseCallback, &release_sync_token, &lost_resource);
- resource = child_resource_provider_->ImportResource(
- viz::TransferableResource::MakeGL(mailbox, GL_LINEAR, GL_TEXTURE_2D,
- sync_token),
- viz::SingleReleaseCallback::Create(std::move(callback)));
- EXPECT_EQ(1u, context()->NumTextures());
- EXPECT_FALSE(release_sync_token.HasData());
- {
- // Transfer the resource, expect the sync points to be consistent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_LE(sync_token.release_count(),
- list[0].mailbox_holder.sync_token.release_count());
- EXPECT_EQ(0,
- memcmp(mailbox.name,
- list[0].mailbox_holder.mailbox.name,
- sizeof(mailbox.name)));
- EXPECT_FALSE(release_sync_token.HasData());
-
- context()->waitSyncToken(list[0].mailbox_holder.sync_token.GetConstData());
- unsigned other_texture =
- context()->createAndConsumeTextureCHROMIUM(mailbox.name);
- uint8_t test_data[4] = { 0 };
- context()->GetPixels(gfx::Size(1, 1), viz::RGBA_8888, test_data);
- EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
-
- context()->produceTextureDirectCHROMIUM(other_texture, mailbox.name);
- context()->deleteTexture(other_texture);
- context()->genSyncToken(list[0].mailbox_holder.sync_token.GetData());
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.HasData());
-
- // Delete the resource, which shouldn't do anything.
- child_resource_provider_->RemoveImportedResource(resource);
- EXPECT_EQ(1u, context()->NumTextures());
- EXPECT_FALSE(release_sync_token.HasData());
-
- // Then receive the resource which should release the mailbox, expect the
- // sync points to be consistent.
- std::vector<viz::ReturnedResource> returned =
- viz::TransferableResource::ReturnResources(list);
- child_resource_provider_->ReceiveReturnsFromParent(returned);
- EXPECT_LE(list[0].mailbox_holder.sync_token.release_count(),
- release_sync_token.release_count());
- EXPECT_FALSE(lost_resource);
- }
-
- context()->waitSyncToken(release_sync_token.GetConstData());
- texture = context()->createAndConsumeTextureCHROMIUM(mailbox.name);
- context()->deleteTexture(texture);
-}
-
-TEST_P(ResourceProviderTest, LostResourceInParent) {
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- viz::ResourceId id;
- if (use_gpu()) {
- id = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- } else {
- id = child_resource_provider_->CreateBitmapResource(size, gfx::ColorSpace(),
- format);
- }
-
- child_resource_provider_->AllocateForTesting(id);
- // Expect a GL resource to be lost.
- bool should_lose_resource = use_gpu();
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer the resource to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(id);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- EXPECT_EQ(1u, list.size());
-
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(id);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- // Lose the output surface in the parent.
- resource_provider_->DidLoseContextProvider();
-
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- // Expect a GL resource to be lost.
- ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_EQ(should_lose_resource, returned_to_child[0].lost);
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- returned_to_child.clear();
- }
-
- // A GL resource should be lost.
- EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(id));
-
- // Lost resources stay in use in the parent forever.
- EXPECT_EQ(should_lose_resource,
- child_resource_provider_->InUseByConsumer(id));
-}
-
-
-TEST_P(ResourceProviderTest, LostMailboxInParent) {
- gpu::SyncToken release_sync_token;
- bool lost_resource = false;
- bool release_called = false;
- gpu::SyncToken sync_token;
- viz::ResourceId resource =
- CreateChildMailbox(&release_sync_token, &lost_resource, &release_called,
- &sync_token, viz::RGBA_8888);
-
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id =
- resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- {
- // Transfer the resource to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource);
- std::vector<viz::TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
- &list);
- EXPECT_EQ(1u, list.size());
-
- resource_provider_->ReceiveFromChild(child_id, list);
- viz::ResourceIdSet resource_ids_to_receive;
- resource_ids_to_receive.insert(resource);
- resource_provider_->DeclareUsedResourcesFromChild(child_id,
- resource_ids_to_receive);
- }
-
- // Lose the output surface in the parent.
- resource_provider_->DidLoseContextProvider();
-
- {
- EXPECT_EQ(0u, returned_to_child.size());
-
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- viz::ResourceIdSet no_resources;
- resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
- ASSERT_EQ(1u, returned_to_child.size());
- // Losing an output surface only loses hardware resources.
- EXPECT_EQ(returned_to_child[0].lost, use_gpu());
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
- returned_to_child.clear();
- }
-
- // Delete the resource in the child. Expect the resource to be lost if it's
- // a GL texture.
- child_resource_provider_->RemoveImportedResource(resource);
- EXPECT_EQ(lost_resource, use_gpu());
-}
-
-TEST_P(ResourceProviderTest, Shutdown) {
- enum Cases {
- // If not exported, the resource is returned not lost, and doesn't need a
- // sync token.
- kShutdownWithoutExport = 0,
- // If exported and not returned, the resource is lost, and doesn't need/have
- // a sync token to give.
- kShutdownAfterExport,
- // If exported and returned, the resource is not lost.
- kShutdownAfterExportAndReturn,
- // If returned as lost, then the resource must report lost on shutdown too.
- kShutdownAfterExportAndReturnWithLostResource,
- // If the context is lost, it doesn't affect imported resources as they are
- // just weak references.
- kShutdownAfterContextLossWithoutExport,
- // If the context is lost, it doesn't affect imported resources as they are
- // just weak references.
- kShutdownAfterContextLossAfterExportAndReturn,
- kNumCases,
- };
-
- for (int i = 0; i < kNumCases; ++i) {
- auto c = static_cast<Cases>(i);
- SCOPED_TRACE(c);
-
- gpu::SyncToken release_sync_token;
- bool lost_resource = false;
- bool release_called = false;
- gpu::SyncToken sync_token;
- viz::ResourceId id =
- CreateChildMailbox(&release_sync_token, &lost_resource, &release_called,
- &sync_token, viz::RGBA_8888);
-
- if (i == kShutdownAfterExport || i == kShutdownAfterExportAndReturn ||
- i == kShutdownAfterExportAndReturnWithLostResource ||
- i == kShutdownAfterContextLossAfterExportAndReturn) {
- std::vector<viz::TransferableResource> send_list;
- child_resource_provider_->PrepareSendToParent({id}, &send_list);
- }
-
- if (i == kShutdownAfterExportAndReturn ||
- i == kShutdownAfterExportAndReturnWithLostResource ||
- i == kShutdownAfterContextLossAfterExportAndReturn) {
- viz::ReturnedResource r;
- r.id = id;
- r.sync_token = sync_token;
- r.count = 1;
- r.lost = (i == kShutdownAfterExportAndReturnWithLostResource);
- child_resource_provider_->ReceiveReturnsFromParent({r});
- }
-
- EXPECT_FALSE(release_sync_token.HasData());
- EXPECT_FALSE(lost_resource);
-
- // Shutdown!
- child_resource_provider_ = nullptr;
-
- // If the resource was exported and returned, then it should come with a
- // sync token.
- if (use_gpu()) {
- if (i == kShutdownAfterExportAndReturn ||
- i == kShutdownAfterExportAndReturnWithLostResource ||
- i == kShutdownAfterContextLossAfterExportAndReturn) {
- EXPECT_LE(sync_token.release_count(),
- release_sync_token.release_count());
- }
- }
-
- // We always get the ReleaseCallback called.
- EXPECT_TRUE(release_called);
- bool expect_lost = i == kShutdownAfterExport ||
- i == kShutdownAfterExportAndReturnWithLostResource;
- EXPECT_EQ(expect_lost, lost_resource);
-
- // Recreate it for the next case.
- MakeChildResourceProvider();
- }
-}
-
-TEST_P(ResourceProviderTest, ScopedSampler) {
- // Sampling is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned = std::make_unique<TextureStateTrackingContext>();
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- viz::ResourceSettings resource_settings = CreateResourceSettings();
- auto resource_provider(std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get()));
-
- auto child_context_owned = std::make_unique<TextureStateTrackingContext>();
- TextureStateTrackingContext* child_context = child_context_owned.get();
-
- auto child_context_provider =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider->BindToCurrentThread();
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- child_context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- resource_settings));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- int texture_id = 1;
-
- viz::ResourceId id = child_resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
-
- // Check that the texture gets created with the right sampler settings.
- EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, texture_id))
- .Times(2); // Once to create and once to allocate.
- EXPECT_CALL(*child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*child_context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- EXPECT_CALL(*child_context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE));
- EXPECT_CALL(*child_context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE));
-
- child_resource_provider->AllocateForTesting(id);
- Mock::VerifyAndClearExpectations(child_context);
-
- // Return the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- SendResourceAndGetChildToParentMap({id}, resource_provider.get(),
- child_resource_provider.get());
- viz::ResourceId mapped_id = resource_map[id];
- resource_provider->WaitSyncToken(mapped_id);
- int parent_texture_id = 3;
- // Creating a sampler with the default filter should not change any texture
- // parameters.
- {
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(parent_texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
- DisplayResourceProvider::ScopedSamplerGL sampler(
- resource_provider.get(), mapped_id, GL_TEXTURE_2D, GL_LINEAR);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Using a different filter should be reflected in the texture parameters.
- {
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
- DisplayResourceProvider::ScopedSamplerGL sampler(
- resource_provider.get(), mapped_id, GL_TEXTURE_2D, GL_NEAREST);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Test resetting to the default filter.
- {
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- DisplayResourceProvider::ScopedSamplerGL sampler(
- resource_provider.get(), mapped_id, GL_TEXTURE_2D, GL_LINEAR);
- Mock::VerifyAndClearExpectations(context);
- }
-}
-
-TEST_P(ResourceProviderTest, ManagedResource) {
- // Sampling is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
- int texture_id = 1;
-
- // Check that the texture gets created with the right sampler settings.
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- resource_provider->CreateForTesting(id);
- EXPECT_NE(0u, id);
-
- Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, TextureWrapMode) {
- // Sampling is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- for (int texture_id = 1; texture_id <= 2; ++texture_id) {
- // Check that the texture gets created with the right sampler settings.
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE));
- EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE));
- resource_provider->CreateForTesting(id);
- EXPECT_NE(0u, id);
-
- Mock::VerifyAndClearExpectations(context);
- }
-}
-
-TEST_P(ResourceProviderTest, TextureHint) {
- // Sampling is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- context->set_support_texture_storage(true);
- context->set_support_texture_usage(true);
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- const viz::ResourceTextureHint hints[] = {
- viz::ResourceTextureHint::kDefault,
- viz::ResourceTextureHint::kFramebuffer,
- };
- for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
- // Check that the texture gets created with the right sampler settings.
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- size, hints[texture_id - 1], format, gfx::ColorSpace());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- EXPECT_CALL(
- *context,
- texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- // Check that GL_TEXTURE_USAGE_ANGLE is set iff the kFramebuffer hint is
- // used.
- bool is_framebuffer_hint =
- hints[texture_id - 1] & viz::ResourceTextureHint::kFramebuffer;
- EXPECT_CALL(*context,
- texParameteri(GL_TEXTURE_2D,
- GL_TEXTURE_USAGE_ANGLE,
- GL_FRAMEBUFFER_ATTACHMENT_ANGLE))
- .Times(is_framebuffer_hint ? 1 : 0);
- resource_provider->CreateForTesting(id);
- EXPECT_NE(0u, id);
-
- Mock::VerifyAndClearExpectations(context);
- }
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_SharedMemory) {
- if (use_gpu())
- return;
-
- gfx::Size size(64, 64);
- viz::ResourceFormat format = viz::RGBA_8888;
- const uint32_t kBadBeef = 0xbadbeef;
- std::unique_ptr<viz::SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap(
- shared_bitmap_manager_.get(), size, format, kBadBeef));
-
- auto resource_provider(std::make_unique<DisplayResourceProvider>(
- nullptr, shared_bitmap_manager_.get()));
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- nullptr, shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(),
- kDelegatedSyncPointsRequired, CreateResourceSettings()));
-
- gpu::SyncToken release_sync_token;
- bool lost_resource = false;
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(
- base::Bind(&ReleaseCallback, &release_sync_token, &lost_resource));
- auto resource = viz::TransferableResource::MakeSoftware(
- shared_bitmap->id(), shared_bitmap->sequence_number(), size, format);
-
- viz::ResourceId resource_id =
- child_resource_provider->ImportResource(resource, std::move(callback));
- EXPECT_NE(0u, resource_id);
-
- // Transfer resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource_id);
-
- std::vector<viz::TransferableResource> send_to_parent;
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id = resource_provider->CreateChild(
- base::Bind(&CollectResources, &returned_to_child));
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &send_to_parent);
- resource_provider->ReceiveFromChild(child_id, send_to_parent);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider->GetChildToParentMap(child_id);
- viz::ResourceId mapped_resource_id = resource_map[resource_id];
-
- {
- DisplayResourceProvider::ScopedReadLockSoftware lock(
- resource_provider.get(), mapped_resource_id);
- const SkBitmap* sk_bitmap = lock.sk_bitmap();
- EXPECT_EQ(sk_bitmap->width(), size.width());
- EXPECT_EQ(sk_bitmap->height(), size.height());
- EXPECT_EQ(*sk_bitmap->getAddr32(16, 16), kBadBeef);
- }
-
- EXPECT_EQ(0u, returned_to_child.size());
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- resource_provider->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(1u, returned_to_child.size());
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
-
- child_resource_provider->RemoveImportedResource(resource_id);
- EXPECT_FALSE(release_sync_token.HasData());
- EXPECT_FALSE(lost_resource);
-}
-
-class ResourceProviderTestImportedResourceGLFilters
- : public ResourceProviderTest {
- public:
- static void RunTest(
- viz::TestSharedBitmapManager* shared_bitmap_manager,
- viz::TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
- bool mailbox_nearest_neighbor,
- GLenum sampler_filter) {
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager));
-
- auto child_context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* child_context = child_context_owned.get();
- auto child_context_provider =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider->BindToCurrentThread();
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- child_context_provider.get(), shared_bitmap_manager,
- gpu_memory_buffer_manager, kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- unsigned texture_id = 1;
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x12),
- 0x34);
- const GLuint64 current_fence_sync = child_context->GetNextFenceSync();
-
- EXPECT_CALL(*child_context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*child_context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*child_context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*child_context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- gpu::Mailbox gpu_mailbox;
- memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
- gpu::SyncToken release_sync_token;
- bool lost_resource = false;
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(
- base::Bind(&ReleaseCallback, &release_sync_token, &lost_resource));
-
- GLuint filter = mailbox_nearest_neighbor ? GL_NEAREST : GL_LINEAR;
- auto resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, filter, GL_TEXTURE_2D, sync_token);
-
- viz::ResourceId resource_id =
- child_resource_provider->ImportResource(resource, std::move(callback));
- EXPECT_NE(0u, resource_id);
- EXPECT_EQ(current_fence_sync, child_context->GetNextFenceSync());
-
- Mock::VerifyAndClearExpectations(child_context);
-
- // Transfer resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource_id);
-
- std::vector<viz::TransferableResource> send_to_parent;
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id = resource_provider->CreateChild(
- base::Bind(&CollectResources, &returned_to_child));
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &send_to_parent);
- resource_provider->ReceiveFromChild(child_id, send_to_parent);
-
- // In DisplayResourceProvider's namespace, use the mapped resource id.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider->GetChildToParentMap(child_id);
- viz::ResourceId mapped_resource_id = resource_map[resource_id];
- {
- // The verified flush flag will be set by
- // LayerTreeResourceProvider::PrepareSendToParent. Before checking if
- // the gpu::SyncToken matches, set this flag first.
- sync_token.SetVerifyFlush();
-
- // Mailbox sync point WaitSyncToken before using the texture.
- EXPECT_CALL(*context, waitSyncToken(MatchesSyncToken(sync_token)));
- resource_provider->WaitSyncToken(mapped_resource_id);
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
-
- // The sampler will reset these if |mailbox_nearest_neighbor| does not
- // match |sampler_filter|.
- if (mailbox_nearest_neighbor != (sampler_filter == GL_NEAREST)) {
- EXPECT_CALL(*context, texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sampler_filter));
- EXPECT_CALL(*context, texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sampler_filter));
- }
-
- DisplayResourceProvider::ScopedSamplerGL lock(
- resource_provider.get(), mapped_resource_id, sampler_filter);
- Mock::VerifyAndClearExpectations(context);
- EXPECT_EQ(current_fence_sync, context->GetNextFenceSync());
-
- // When done with it, a sync point should be inserted, but no produce is
- // necessary.
- EXPECT_CALL(*child_context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*child_context, produceTextureDirectCHROMIUM(_, _)).Times(0);
-
- EXPECT_CALL(*child_context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*child_context, createAndConsumeTextureCHROMIUM(_)).Times(0);
- }
-
- EXPECT_EQ(0u, returned_to_child.size());
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- resource_provider->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(1u, returned_to_child.size());
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
-
- child_resource_provider->RemoveImportedResource(resource_id);
- EXPECT_TRUE(release_sync_token.HasData());
- EXPECT_FALSE(lost_resource);
- }
-};
-
-TEST_P(ResourceProviderTest, ImportedResource_GLTexture2D_LinearToLinear) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- ResourceProviderTestImportedResourceGLFilters::RunTest(
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), false,
- GL_LINEAR);
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_GLTexture2D_NearestToNearest) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- ResourceProviderTestImportedResourceGLFilters::RunTest(
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), true,
- GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_GLTexture2D_NearestToLinear) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- ResourceProviderTestImportedResourceGLFilters::RunTest(
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), true,
- GL_LINEAR);
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_GLTexture2D_LinearToNearest) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- ResourceProviderTestImportedResourceGLFilters::RunTest(
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), false,
- GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_GLTextureExternalOES) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get()));
-
- auto child_context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* child_context = child_context_owned.get();
- auto child_context_provider =
- viz::TestContextProvider::Create(std::move(child_context_owned));
- child_context_provider->BindToCurrentThread();
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- child_context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x12), 0x34);
- const GLuint64 current_fence_sync = child_context->GetNextFenceSync();
-
- EXPECT_CALL(*child_context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*child_context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*child_context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*child_context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- gpu::Mailbox gpu_mailbox;
- memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::DoNothing());
-
- auto resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, GL_LINEAR, GL_TEXTURE_EXTERNAL_OES, sync_token);
-
- viz::ResourceId resource_id =
- child_resource_provider->ImportResource(resource, std::move(callback));
- EXPECT_NE(0u, resource_id);
- EXPECT_EQ(current_fence_sync, child_context->GetNextFenceSync());
-
- Mock::VerifyAndClearExpectations(child_context);
-
- // Transfer resources to the parent.
- ResourceProvider::ResourceIdArray resource_ids_to_transfer;
- resource_ids_to_transfer.push_back(resource_id);
-
- std::vector<viz::TransferableResource> send_to_parent;
- std::vector<viz::ReturnedResource> returned_to_child;
- int child_id = resource_provider->CreateChild(
- base::Bind(&CollectResources, &returned_to_child));
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &send_to_parent);
- resource_provider->ReceiveFromChild(child_id, send_to_parent);
-
- // Before create DrawQuad in DisplayResourceProvider's namespace, get the
- // mapped resource id first.
- ResourceProvider::ResourceIdMap resource_map =
- resource_provider->GetChildToParentMap(child_id);
- viz::ResourceId mapped_resource_id = resource_map[resource_id];
- {
- // The verified flush flag will be set by
- // LayerTreeResourceProvider::PrepareSendToParent. Before checking if
- // the gpu::SyncToken matches, set this flag first.
- sync_token.SetVerifyFlush();
-
- // Mailbox sync point WaitSyncToken before using the texture.
- EXPECT_CALL(*context, waitSyncToken(MatchesSyncToken(sync_token)));
- resource_provider->WaitSyncToken(mapped_resource_id);
- Mock::VerifyAndClearExpectations(context);
-
- unsigned texture_id = 1;
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(texture_id));
-
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
-
- DisplayResourceProvider::ScopedReadLockGL lock(resource_provider.get(),
- mapped_resource_id);
- Mock::VerifyAndClearExpectations(context);
-
- // When done with it, a sync point should be inserted, but no produce is
- // necessary.
- EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
-
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_)).Times(0);
- Mock::VerifyAndClearExpectations(context);
- }
- EXPECT_EQ(0u, returned_to_child.size());
- // Transfer resources back from the parent to the child. Set no resources as
- // being in use.
- resource_provider->DeclareUsedResourcesFromChild(child_id,
- viz::ResourceIdSet());
- EXPECT_EQ(1u, returned_to_child.size());
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
-
- child_resource_provider->RemoveImportedResource(resource_id);
-}
-
-TEST_P(ResourceProviderTest, WaitSyncTokenIfNeeded_ResourceFromChild) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider = std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get());
-
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x12), 0x34);
- const GLuint64 current_fence_sync = context->GetNextFenceSync();
-
- EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- // Receive a resource from the child.
- std::vector<viz::ReturnedResource> returned;
- ReturnCallback return_callback = base::Bind(
- [](std::vector<viz::ReturnedResource>* out,
- const std::vector<viz::ReturnedResource>& in) {
- *out = std::move(in);
- },
- &returned);
- int child = resource_provider->CreateChild(return_callback);
-
- // Send a bunch of resources, to make sure things work when there's more than
- // one resource, and to make vectors reallocate and such.
- for (int i = 0; i < 100; ++i) {
- gpu::Mailbox gpu_mailbox;
- memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
- auto resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
- resource.id = i;
- resource_provider->ReceiveFromChild(child, {resource});
- auto& map = resource_provider->GetChildToParentMap(child);
- EXPECT_EQ(i + 1u, map.size());
- }
-
- EXPECT_EQ(current_fence_sync, context->GetNextFenceSync());
- resource_provider.reset();
- // Returned resources don't have InsertFenceSyncCHROMIUM() called.
- EXPECT_EQ(current_fence_sync, context->GetNextFenceSync());
-
- // The returned resource has a verified sync token.
- ASSERT_EQ(returned.size(), 100u);
- for (viz::ReturnedResource& r : returned)
- EXPECT_TRUE(r.sync_token.verified_flush());
-}
-
-TEST_P(ResourceProviderTest, WaitSyncTokenIfNeeded_WithSyncToken) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider = std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get());
-
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x12), 0x34);
- const GLuint64 current_fence_sync = context->GetNextFenceSync();
-
- EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- viz::ResourceId id = MakeGpuResourceAndSendToDisplay(
- 'a', GL_LINEAR, GL_TEXTURE_2D, sync_token, resource_provider.get());
- EXPECT_NE(0u, id);
- EXPECT_EQ(current_fence_sync, context->GetNextFenceSync());
-
- Mock::VerifyAndClearExpectations(context);
-
- {
- // First call to WaitSyncToken should call waitSyncToken.
- EXPECT_CALL(*context, waitSyncToken(MatchesSyncToken(sync_token)));
- resource_provider->WaitSyncToken(id);
- Mock::VerifyAndClearExpectations(context);
-
- // Subsequent calls to WaitSyncToken shouldn't call waitSyncToken.
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- resource_provider->WaitSyncToken(id);
- Mock::VerifyAndClearExpectations(context);
- }
-}
-
-TEST_P(ResourceProviderTest,
- ImportedResource_WaitSyncTokenIfNeeded_NoSyncToken) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider = std::make_unique<DisplayResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get());
-
- gpu::SyncToken sync_token;
- const GLuint64 current_fence_sync = context->GetNextFenceSync();
-
- EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- viz::ResourceId id = MakeGpuResourceAndSendToDisplay(
- 'h', GL_LINEAR, GL_TEXTURE_2D, sync_token, resource_provider.get());
-
- EXPECT_EQ(current_fence_sync, context->GetNextFenceSync());
- EXPECT_NE(0u, id);
-
- Mock::VerifyAndClearExpectations(context);
-
- {
- // WaitSyncToken with empty sync_token shouldn't call waitSyncToken.
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- resource_provider->WaitSyncToken(id);
- Mock::VerifyAndClearExpectations(context);
- }
-}
-
-TEST_P(ResourceProviderTest, ImportedResource_PrepareSendToParent_NoSyncToken) {
- // Mailboxing is only supported for GL textures.
- if (!use_gpu())
- return;
-
- auto context_owned(std::make_unique<TextureStateTrackingContext>());
- TextureStateTrackingContext* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
- EXPECT_CALL(*context, waitSyncToken(_)).Times(0);
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _)).Times(0);
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_)).Times(0);
-
- auto resource = viz::TransferableResource::MakeGL(
- gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken());
-
- std::unique_ptr<viz::SingleReleaseCallback> callback =
- viz::SingleReleaseCallback::Create(base::DoNothing());
-
- viz::ResourceId id =
- resource_provider->ImportResource(resource, std::move(callback));
- EXPECT_NE(0u, id);
- Mock::VerifyAndClearExpectations(context);
-
- ResourceProvider::ResourceIdArray resource_ids_to_transfer{id};
- std::vector<viz::TransferableResource> list;
- resource_provider->PrepareSendToParent(resource_ids_to_transfer, &list);
- ASSERT_EQ(1u, list.size());
- EXPECT_FALSE(list[0].mailbox_holder.sync_token.HasData());
- EXPECT_TRUE(list[0].mailbox_holder.sync_token.verified_flush());
- Mock::VerifyAndClearExpectations(context);
-}
-
-class AllocationTrackingContext3D : public TextureStateTrackingContext {
- public:
- MOCK_METHOD0(NextTextureId, GLuint());
- MOCK_METHOD1(RetireTextureId, void(GLuint id));
- MOCK_METHOD5(texStorage2DImageCHROMIUM,
- void(GLenum target,
- GLenum internalformat,
- GLenum bufferusage,
- GLsizei width,
- GLsizei height));
- MOCK_METHOD5(texStorage2DEXT,
- void(GLenum target,
- GLsizei levels,
- GLenum internalformat,
- GLsizei width,
- GLsizei height));
- MOCK_METHOD9(texImage2D,
- void(GLenum target,
- GLint level,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const void* pixels));
- MOCK_METHOD9(texSubImage2D,
- void(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels));
- MOCK_METHOD9(asyncTexImage2DCHROMIUM,
- void(GLenum target,
- GLint level,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const void* pixels));
- MOCK_METHOD9(asyncTexSubImage2DCHROMIUM,
- void(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels));
- MOCK_METHOD8(compressedTexImage2D,
- void(GLenum target,
- GLint level,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLsizei image_size,
- const void* data));
- MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(GLenum));
- MOCK_METHOD4(createImageCHROMIUM,
- GLuint(ClientBuffer, GLsizei, GLsizei, GLenum));
- MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
- MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
- MOCK_METHOD2(releaseTexImage2DCHROMIUM, void(GLenum, GLint));
- MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
-};
-
-TEST_P(ResourceProviderTest, TextureAllocation) {
- if (!use_gpu())
- return;
-
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- gfx::Size size(2, 2);
- viz::ResourceFormat format = viz::RGBA_8888;
- viz::ResourceId id = 0;
- uint8_t pixels[16] = { 0 };
- int texture_id = 123;
-
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- // Lazy allocation. Don't allocate when creating the resource.
- id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
-
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
- resource_provider->CreateForTesting(id);
-
- EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
- resource_provider->DeleteResource(id);
-
- Mock::VerifyAndClearExpectations(context);
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
-
- // Do allocate when we set the pixels.
- id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
-
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
- EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, _, _, 2, 2, _, _, _, _))
- .Times(1);
- EXPECT_CALL(*context, texSubImage2D(GL_TEXTURE_2D, _, _, _, 2, 2, _, _, _))
- .Times(1);
- resource_provider->CopyToResource(id, pixels, size);
-
- EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
- resource_provider->DeleteResource(id);
-
- Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, TextureStorageAllocation) {
- if (!use_gpu())
- return;
-
- auto context_owned =
- std::make_unique<StrictMock<AllocationTrackingContext3D>>();
- auto* context = context_owned.get();
- context->set_support_texture_storage(true);
- context->set_support_texture_usage(true);
-
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- auto child_resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- viz::ResourceId id = child_resource_provider->CreateGpuTextureResource(
- gfx::Size(2, 2), viz::ResourceTextureHint::kDefault, viz::RGBA_8888,
- gfx::ColorSpace());
-
- const GLuint kTextureId = 123u;
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(2);
- EXPECT_CALL(*context, texStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 2, 2))
- .Times(1);
- EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, _, _)).Times(AnyNumber());
- child_resource_provider->AllocateForTesting(id);
-
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
- child_resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, ScopedWriteLockGpuMemoryBuffer) {
- if (!use_gpu())
- return;
-
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- const int kWidth = 2;
- const int kHeight = 2;
- viz::ResourceFormat format = viz::RGBA_8888;
- const unsigned kTextureId = 123u;
- const unsigned kImageId = 234u;
-
- auto resource_provider = std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings());
-
- viz::ResourceId id = resource_provider->CreateGpuMemoryBufferResource(
- gfx::Size(kWidth, kHeight), viz::ResourceTextureHint::kDefault, format,
- gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::ColorSpace());
-
- InSequence sequence;
-
- // Create texture and image upon releasing the lock.
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
- .WillOnce(Return(kImageId));
- EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId));
-
- {
- LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
- resource_provider.get(), id);
- EXPECT_TRUE(lock.GetGpuMemoryBuffer());
- }
- Mock::VerifyAndClearExpectations(context);
-
- // Upload to GPU again since image is dirty after the write lock.
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId));
- EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId));
-
- {
- LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
- resource_provider.get(), id);
- EXPECT_TRUE(lock.GetGpuMemoryBuffer());
- }
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId));
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
-}
-
-TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
- if (!use_gpu())
- return;
-
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new AllocationTrackingContext3D);
- AllocationTrackingContext3D* context = context_owned.get();
- context_owned->set_support_compressed_texture_etc1(true);
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- gfx::Size size(4, 4);
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
- int texture_id = 123;
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, viz::ETC1, gfx::ColorSpace());
- EXPECT_NE(0u, id);
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
- resource_provider->AllocateForTesting(id);
-
- EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
- resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) {
- if (!use_gpu())
- return;
-
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new AllocationTrackingContext3D);
- AllocationTrackingContext3D* context = context_owned.get();
- context_owned->set_support_compressed_texture_etc1(true);
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- gfx::Size size(4, 4);
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
- int texture_id = 123;
- uint8_t pixels[8];
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, viz::ETC1, gfx::ColorSpace());
- EXPECT_NE(0u, id);
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
- EXPECT_CALL(*context,
- compressedTexImage2D(
- _, 0, _, size.width(), size.height(), _, _, _)).Times(1);
- resource_provider->CopyToResource(id, pixels, size);
-
- EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
- resource_provider->DeleteResource(id);
-}
-
-INSTANTIATE_TEST_CASE_P(ResourceProviderTests,
- ResourceProviderTest,
- ::testing::Values(true, false));
-
-class TextureIdAllocationTrackingContext
- : public viz::TestWebGraphicsContext3D {
- public:
- GLuint NextTextureId() override {
- base::AutoLock lock(namespace_->lock);
- return namespace_->next_texture_id++;
- }
- void RetireTextureId(GLuint) override {}
- GLuint PeekTextureId() {
- base::AutoLock lock(namespace_->lock);
- return namespace_->next_texture_id;
- }
-};
-
-TEST_P(ResourceProviderTest, GetSyncTokenForResources) {
- if (!use_gpu())
- return;
-
- gfx::Size size(1, 1);
- viz::ResourceFormat format = viz::RGBA_8888;
-
- // ~Random set of |release_count|s to set on sync tokens.
- uint64_t release_counts[5] = {7, 3, 10, 2, 5};
-
- ResourceProvider::ResourceIdArray array;
- for (uint32_t i = 0; i < arraysize(release_counts); ++i) {
- viz::ResourceId id = child_resource_provider_->CreateGpuTextureResource(
- size, viz::ResourceTextureHint::kDefault, format, gfx::ColorSpace());
- array.push_back(id);
-
- LayerTreeResourceProvider::ScopedWriteLockGL lock(
- child_resource_provider_.get(), id);
- gpu::SyncToken token;
- token.Set(gpu::CommandBufferNamespace::INVALID, gpu::CommandBufferId(),
- release_counts[i]);
- lock.set_sync_token(token);
- }
-
- gpu::SyncToken last_token =
- child_resource_provider_->GetSyncTokenForResources(array);
- EXPECT_EQ(last_token.release_count(), 10u);
-}
-
-TEST_P(ResourceProviderTest, ScopedWriteLockGL) {
- if (!use_gpu())
- return;
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- const int kWidth = 2;
- const int kHeight = 2;
- const viz::ResourceFormat format = viz::RGBA_8888;
- const unsigned kTextureId = 123u;
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- gfx::Size(kWidth, kHeight), viz::ResourceTextureHint::kDefault, format,
- gfx::ColorSpace());
-
- InSequence sequence;
-
- // First use will allocate lazily when accessing the texture.
- {
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format),
- kWidth, kHeight, 0, GLDataFormat(format),
- GLDataType(format), nullptr));
- LayerTreeResourceProvider::ScopedWriteLockGL lock(resource_provider.get(),
- id);
- EXPECT_EQ(lock.GetTexture(), kTextureId);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Subsequent uses will not allocate.
- {
- LayerTreeResourceProvider::ScopedWriteLockGL lock(resource_provider.get(),
- id);
- EXPECT_EQ(lock.GetTexture(), kTextureId);
- }
-
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
- resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, ScopedWriteLockGL_Overlay) {
- if (!use_gpu())
- return;
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- context->set_support_texture_storage_image(true);
-
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- const int kWidth = 2;
- const int kHeight = 2;
- const viz::ResourceFormat format = viz::RGBA_8888;
- const unsigned kTextureId = 123u;
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- gfx::Size(kWidth, kHeight), viz::ResourceTextureHint::kOverlay, format,
- gfx::ColorSpace());
-
- InSequence sequence;
-
- // First use will allocate lazily on accessing the texture.
- {
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texStorage2DImageCHROMIUM(GL_TEXTURE_2D, GL_RGBA8_OES,
- GL_SCANOUT_CHROMIUM, kWidth,
- kHeight));
- LayerTreeResourceProvider::ScopedWriteLockGL lock(resource_provider.get(),
- id);
- EXPECT_EQ(lock.GetTexture(), kTextureId);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Subsequent uses will not allocate.
- {
- LayerTreeResourceProvider::ScopedWriteLockGL lock(resource_provider.get(),
- id);
- EXPECT_EQ(lock.GetTexture(), kTextureId);
- }
-
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
- resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, ScopedWriteLockRaster_Mailbox) {
- if (!use_gpu())
- return;
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- const int kWidth = 2;
- const int kHeight = 2;
- const viz::ResourceFormat format = viz::RGBA_8888;
- const unsigned kTextureId = 123u;
- const unsigned kWorkerTextureId = 234u;
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- gfx::Size(kWidth, kHeight), viz::ResourceTextureHint::kDefault, format,
- gfx::ColorSpace());
-
- InSequence sequence;
- gpu::SyncToken sync_token;
-
- // First use will create mailbox when lock is created and allocate lazily in
- // ConsumeTexture.
- {
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- LayerTreeResourceProvider::ScopedWriteLockRaster lock(
- resource_provider.get(), id);
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(kTextureId, _));
- lock.CreateMailbox();
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(kWorkerTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kWorkerTextureId));
- EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format),
- kWidth, kHeight, 0, GLDataFormat(format),
- GLDataType(format), nullptr));
- EXPECT_EQ(kWorkerTextureId,
- lock.ConsumeTexture(context_provider->RasterInterface()));
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, RetireTextureId(kWorkerTextureId));
- context_provider->ContextGL()->DeleteTextures(1, &kWorkerTextureId);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Subsequent uses will not create mailbox or allocate.
- {
- LayerTreeResourceProvider::ScopedWriteLockRaster lock(
- resource_provider.get(), id);
- lock.CreateMailbox();
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(kWorkerTextureId));
- EXPECT_EQ(kWorkerTextureId,
- lock.ConsumeTexture(context_provider->RasterInterface()));
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, RetireTextureId(kWorkerTextureId));
- context_provider->ContextGL()->DeleteTextures(1, &kWorkerTextureId);
-
- sync_token = LayerTreeResourceProvider::GenerateSyncTokenHelper(
- context_provider->RasterInterface());
- lock.set_sync_token(sync_token);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Wait for worker context sync token before deleting texture.
- EXPECT_CALL(*context, waitSyncToken(MatchesSyncToken(sync_token)));
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
- resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, ScopedWriteLockRaster_Mailbox_Overlay) {
- if (!use_gpu())
- return;
-
- std::unique_ptr<AllocationTrackingContext3D> context_owned(
- new StrictMock<AllocationTrackingContext3D>);
- AllocationTrackingContext3D* context = context_owned.get();
- context->set_support_texture_storage_image(true);
-
- auto context_provider =
- viz::TestContextProvider::Create(std::move(context_owned));
- context_provider->BindToCurrentThread();
-
- const int kWidth = 2;
- const int kHeight = 2;
- const viz::ResourceFormat format = viz::RGBA_8888;
- const unsigned kTextureId = 123u;
- const unsigned kWorkerTextureId = 234u;
-
- auto resource_provider(std::make_unique<LayerTreeResourceProvider>(
- context_provider.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), kDelegatedSyncPointsRequired,
- CreateResourceSettings()));
-
- viz::ResourceId id = resource_provider->CreateGpuTextureResource(
- gfx::Size(kWidth, kHeight), viz::ResourceTextureHint::kOverlay, format,
- gfx::ColorSpace());
-
- InSequence sequence;
- gpu::SyncToken sync_token;
-
- // First use will create mailbox when lock is created and allocate lazily in
- // ConsumeTexture.
- {
- EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(kTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId));
- EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
- LayerTreeResourceProvider::ScopedWriteLockRaster lock(
- resource_provider.get(), id);
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, produceTextureDirectCHROMIUM(kTextureId, _));
- lock.CreateMailbox();
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(kWorkerTextureId));
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kWorkerTextureId));
- EXPECT_CALL(*context, texStorage2DImageCHROMIUM(GL_TEXTURE_2D, GL_RGBA8_OES,
- GL_SCANOUT_CHROMIUM, kWidth,
- kHeight));
- EXPECT_EQ(kWorkerTextureId,
- lock.ConsumeTexture(context_provider->RasterInterface()));
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, RetireTextureId(kWorkerTextureId));
- context_provider->ContextGL()->DeleteTextures(1, &kWorkerTextureId);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Subsequent uses will not create mailbox or allocate.
- {
- LayerTreeResourceProvider::ScopedWriteLockRaster lock(
- resource_provider.get(), id);
- lock.CreateMailbox();
- Mock::VerifyAndClearExpectations(context);
-
- EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_))
- .WillOnce(Return(kWorkerTextureId));
- EXPECT_EQ(kWorkerTextureId,
- lock.ConsumeTexture(context_provider->RasterInterface()));
- Mock::VerifyAndClearExpectations(context);
-
- sync_token = LayerTreeResourceProvider::GenerateSyncTokenHelper(
- context_provider->RasterInterface());
- lock.set_sync_token(sync_token);
-
- EXPECT_CALL(*context, RetireTextureId(kWorkerTextureId));
- context_provider->ContextGL()->DeleteTextures(1, &kWorkerTextureId);
- Mock::VerifyAndClearExpectations(context);
- }
-
- // Wait for worker context sync token before deleting texture.
- EXPECT_CALL(*context, waitSyncToken(MatchesSyncToken(sync_token)));
- EXPECT_CALL(*context, RetireTextureId(kTextureId));
- resource_provider->DeleteResource(id);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/resource_util_unittest.cc b/chromium/cc/resources/resource_util_unittest.cc
deleted file mode 100644
index 4680c0ca312..00000000000
--- a/chromium/cc/resources/resource_util_unittest.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-
-#include "base/logging.h"
-#include "components/viz/common/resources/resource_sizes.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-struct TestFormat {
- viz::ResourceFormat format;
- size_t expected_bytes;
- size_t expected_bytes_aligned;
-};
-
-// Modify this constant as per TestFormat variables defined in following tests.
-const int kTestFormats = 4;
-
-class ResourceUtilTest : public testing::Test {
- public:
- void TestVerifyWidthInBytes(int width, const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- EXPECT_TRUE(viz::ResourceSizes::VerifyWidthInBytes<size_t>(
- width, test_formats[i].format));
- }
- }
-
- void TestCheckedWidthInBytes(int width, const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::CheckedWidthInBytes<size_t>(
- width, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes);
- }
- }
-
- void TestUncheckedWidthInBytes(int width, const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::UncheckedWidthInBytes<size_t>(
- width, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes);
- }
- }
-
- void TestUncheckedWidthInBytesAligned(int width,
- const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::UncheckedWidthInBytesAligned<size_t>(
- width, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes_aligned);
- }
- }
-
- void TestVerifySizeInBytes(const gfx::Size& size,
- const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- EXPECT_TRUE(viz::ResourceSizes::VerifySizeInBytes<size_t>(
- size, test_formats[i].format));
- }
- }
-
- void TestCheckedSizeInBytes(const gfx::Size& size,
- const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::CheckedSizeInBytes<size_t>(
- size, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes);
- }
- }
-
- void TestUncheckedSizeInBytes(const gfx::Size& size,
- const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::UncheckedSizeInBytes<size_t>(
- size, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes);
- }
- }
-
- void TestUncheckedSizeInBytesAligned(const gfx::Size& size,
- const TestFormat* test_formats) {
- for (int i = 0; i < kTestFormats; ++i) {
- size_t bytes = viz::ResourceSizes::UncheckedSizeInBytesAligned<size_t>(
- size, test_formats[i].format);
- EXPECT_EQ(bytes, test_formats[i].expected_bytes_aligned);
- }
- }
-};
-
-TEST_F(ResourceUtilTest, WidthInBytes) {
- // Check bytes for even width.
- int width = 10;
- TestFormat test_formats[] = {
- {viz::RGBA_8888, 40, 40}, // for 32 bits
- {viz::RGBA_4444, 20, 20}, // for 16 bits
- {viz::ALPHA_8, 10, 12}, // for 8 bits
- {viz::ETC1, 5, 8} // for 4 bits
- };
-
- TestVerifyWidthInBytes(width, test_formats);
- TestCheckedWidthInBytes(width, test_formats);
- TestUncheckedWidthInBytes(width, test_formats);
- TestUncheckedWidthInBytesAligned(width, test_formats);
-
- // Check bytes for odd width.
- int width_odd = 11;
- TestFormat test_formats_odd[] = {
- {viz::RGBA_8888, 44, 44}, // for 32 bits
- {viz::RGBA_4444, 22, 24}, // for 16 bits
- {viz::ALPHA_8, 11, 12}, // for 8 bits
- {viz::ETC1, 6, 8} // for 4 bits
- };
-
- TestVerifyWidthInBytes(width_odd, test_formats_odd);
- TestCheckedWidthInBytes(width_odd, test_formats_odd);
- TestUncheckedWidthInBytes(width_odd, test_formats_odd);
- TestUncheckedWidthInBytesAligned(width_odd, test_formats_odd);
-}
-
-TEST_F(ResourceUtilTest, SizeInBytes) {
- // Check bytes for even size.
- gfx::Size size(10, 10);
- TestFormat test_formats[] = {
- {viz::RGBA_8888, 400, 400}, // for 32 bits
- {viz::RGBA_4444, 200, 200}, // for 16 bits
- {viz::ALPHA_8, 100, 120}, // for 8 bits
- {viz::ETC1, 50, 80} // for 4 bits
- };
-
- TestVerifySizeInBytes(size, test_formats);
- TestCheckedSizeInBytes(size, test_formats);
- TestUncheckedSizeInBytes(size, test_formats);
- TestUncheckedSizeInBytesAligned(size, test_formats);
-
- // Check bytes for odd size.
- gfx::Size size_odd(11, 11);
- TestFormat test_formats_odd[] = {
- {viz::RGBA_8888, 484, 484}, // for 32 bits
- {viz::RGBA_4444, 242, 264}, // for 16 bits
- {viz::ALPHA_8, 121, 132}, // for 8 bits
- {viz::ETC1, 66, 88} // for 4 bits
- };
-
- TestVerifySizeInBytes(size_odd, test_formats_odd);
- TestCheckedSizeInBytes(size_odd, test_formats_odd);
- TestUncheckedSizeInBytes(size_odd, test_formats_odd);
- TestUncheckedSizeInBytesAligned(size_odd, test_formats_odd);
-}
-
-TEST_F(ResourceUtilTest, WidthInBytesOverflow) {
- int width = 10;
- // 10 * 16 = 160 bits, overflows in char, but fits in unsigned char.
- EXPECT_FALSE(viz::ResourceSizes::VerifyWidthInBytes<signed char>(
- width, viz::RGBA_4444));
- EXPECT_TRUE(viz::ResourceSizes::VerifyWidthInBytes<unsigned char>(
- width, viz::RGBA_4444));
-}
-
-TEST_F(ResourceUtilTest, SizeInBytesOverflow) {
- gfx::Size size(10, 10);
- // 10 * 16 * 10 = 1600 bits, overflows in char, but fits in int.
- EXPECT_FALSE(
- viz::ResourceSizes::VerifySizeInBytes<signed char>(size, viz::RGBA_4444));
- EXPECT_TRUE(viz::ResourceSizes::VerifySizeInBytes<int>(size, viz::RGBA_4444));
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/return_callback.h b/chromium/cc/resources/return_callback.h
deleted file mode 100644
index a8d5c3a1819..00000000000
--- a/chromium/cc/resources/return_callback.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_RETURN_CALLBACK_H_
-#define CC_RESOURCES_RETURN_CALLBACK_H_
-
-#include "base/callback.h"
-#include "components/viz/common/resources/returned_resource.h"
-
-namespace cc {
-
-using ReturnCallback =
- base::Callback<void(const std::vector<viz::ReturnedResource>&)>;
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RETURN_CALLBACK_H_
diff --git a/chromium/cc/resources/video_resource_updater.cc b/chromium/cc/resources/video_resource_updater.cc
index 6b3b19215d7..5004919630a 100644
--- a/chromium/cc/resources/video_resource_updater.cc
+++ b/chromium/cc/resources/video_resource_updater.cc
@@ -22,7 +22,6 @@
#include "cc/base/math_util.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/resources/layer_tree_resource_provider.h"
-#include "cc/trees/layer_tree_frame_sink.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/texture_allocation.h"
#include "components/viz/common/quads/render_pass.h"
@@ -31,6 +30,7 @@
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/resource_sizes.h"
+#include "components/viz/common/resources/shared_bitmap_reporter.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -43,6 +43,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/skia_util.h"
+#include "ui/gl/gl_enums.h"
#include "ui/gl/trace_util.h"
namespace cc {
@@ -84,8 +85,7 @@ VideoFrameResourceType ExternalResourceTypeForHardwarePlanes(
case media::PIXEL_FORMAT_NV12:
DCHECK(target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_2D ||
target == GL_TEXTURE_RECTANGLE_ARB)
- << "Unsupported texture target " << std::hex << std::showbase
- << target;
+ << "Unsupported target " << gl::GLEnums::GetStringEnum(target);
// Single plane textures can be sampled as RGB.
if (num_textures > 1)
return VideoFrameResourceType::YUV;
@@ -252,14 +252,14 @@ class VideoResourceUpdater::SoftwarePlaneResource
public:
SoftwarePlaneResource(uint32_t plane_resource_id,
const gfx::Size& size,
- LayerTreeFrameSink* layer_tree_frame_sink)
+ viz::SharedBitmapReporter* shared_bitmap_reporter)
: PlaneResource(plane_resource_id,
size,
viz::ResourceFormat::RGBA_8888,
/*is_software=*/true),
- layer_tree_frame_sink_(layer_tree_frame_sink),
+ shared_bitmap_reporter_(shared_bitmap_reporter),
shared_bitmap_id_(viz::SharedBitmap::GenerateId()) {
- DCHECK(layer_tree_frame_sink_);
+ DCHECK(shared_bitmap_reporter_);
// Allocate SharedMemory and notify display compositor of the allocation.
shared_memory_ = viz::bitmap_allocation::AllocateMappedBitmap(
@@ -268,11 +268,11 @@ class VideoResourceUpdater::SoftwarePlaneResource
viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
shared_memory_.get(), resource_size(),
viz::ResourceFormat::RGBA_8888);
- layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(handle),
- shared_bitmap_id_);
+ shared_bitmap_reporter_->DidAllocateSharedBitmap(std::move(handle),
+ shared_bitmap_id_);
}
~SoftwarePlaneResource() override {
- layer_tree_frame_sink_->DidDeleteSharedBitmap(shared_bitmap_id_);
+ shared_bitmap_reporter_->DidDeleteSharedBitmap(shared_bitmap_id_);
}
const viz::SharedBitmapId& shared_bitmap_id() const {
@@ -286,7 +286,7 @@ class VideoResourceUpdater::SoftwarePlaneResource
}
private:
- LayerTreeFrameSink* const layer_tree_frame_sink_;
+ viz::SharedBitmapReporter* const shared_bitmap_reporter_;
const viz::SharedBitmapId shared_bitmap_id_;
std::unique_ptr<base::SharedMemory> shared_memory_;
@@ -340,18 +340,22 @@ VideoResourceUpdater::PlaneResource::AsHardware() {
VideoResourceUpdater::VideoResourceUpdater(
viz::ContextProvider* context_provider,
- LayerTreeFrameSink* layer_tree_frame_sink,
+ viz::SharedBitmapReporter* shared_bitmap_reporter,
LayerTreeResourceProvider* resource_provider,
bool use_stream_video_draw_quad,
- bool use_gpu_memory_buffer_resources)
+ bool use_gpu_memory_buffer_resources,
+ bool use_r16_texture,
+ int max_resource_size)
: context_provider_(context_provider),
- layer_tree_frame_sink_(layer_tree_frame_sink),
+ shared_bitmap_reporter_(shared_bitmap_reporter),
resource_provider_(resource_provider),
use_stream_video_draw_quad_(use_stream_video_draw_quad),
use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
+ use_r16_texture_(use_r16_texture),
+ max_resource_size_(max_resource_size),
tracing_id_(g_next_video_resource_updater_id.GetNext()),
weak_ptr_factory_(this) {
- DCHECK(context_provider_ || layer_tree_frame_sink_);
+ DCHECK(context_provider_ || shared_bitmap_reporter_);
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "cc::VideoResourceUpdater", base::ThreadTaskRunnerHandle::Get());
@@ -477,6 +481,8 @@ void VideoResourceUpdater::AppendQuads(viz::RenderPass* render_pass,
frame_resource_multiplier_, frame_bits_per_channel_);
yuv_video_quad->require_overlay =
frame->metadata()->IsTrue(media::VideoFrameMetadata::REQUIRE_OVERLAY);
+ yuv_video_quad->is_protected_video =
+ frame->metadata()->IsTrue(media::VideoFrameMetadata::PROTECTED_VIDEO);
for (viz::ResourceId resource_id : yuv_video_quad->resources) {
resource_provider_->ValidateResource(resource_id);
@@ -543,6 +549,21 @@ VideoResourceUpdater::CreateExternalResourcesFromVideoFrame(
return CreateForSoftwarePlanes(std::move(video_frame));
}
+viz::ResourceFormat VideoResourceUpdater::YuvResourceFormat(
+ int bits_per_channel) {
+ DCHECK(context_provider_);
+ const auto& caps = context_provider_->ContextCapabilities();
+ if (caps.disable_one_component_textures)
+ return viz::RGBA_8888;
+ if (bits_per_channel <= 8)
+ return caps.texture_rg ? viz::RED_8 : viz::LUMINANCE_8;
+ if (use_r16_texture_ && caps.texture_norm16)
+ return viz::R16_EXT;
+ if (caps.texture_half_float_linear)
+ return viz::LUMINANCE_F16;
+ return viz::LUMINANCE_8;
+}
+
VideoResourceUpdater::PlaneResource*
VideoResourceUpdater::RecycleOrAllocateResource(
const gfx::Size& resource_size,
@@ -591,7 +612,7 @@ VideoResourceUpdater::PlaneResource* VideoResourceUpdater::AllocateResource(
DCHECK_EQ(format, viz::ResourceFormat::RGBA_8888);
all_resources_.push_back(std::make_unique<SoftwarePlaneResource>(
- plane_resource_id, plane_size, layer_tree_frame_sink_));
+ plane_resource_id, plane_size, shared_bitmap_reporter_));
} else {
// Video textures get composited into the display frame, the GPU doesn't
// draw to them directly.
@@ -718,7 +739,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
#if defined(OS_ANDROID)
transfer_resource.is_backed_by_surface_texture =
video_frame->metadata()->IsTrue(
- media::VideoFrameMetadata::SURFACE_TEXTURE);
+ media::VideoFrameMetadata::TEXTURE_OWNER);
transfer_resource.wants_promotion_hint = video_frame->metadata()->IsTrue(
media::VideoFrameMetadata::WANTS_PROMOTION_HINT);
#endif
@@ -749,10 +770,9 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
// compositing.
output_resource_format = viz::RGBA_8888;
output_color_space = output_color_space.GetAsFullRangeRGB();
- } else {
+ } else if (!software_compositor()) {
// Can be composited directly from yuv planes.
- output_resource_format =
- resource_provider_->YuvResourceFormat(bits_per_channel);
+ output_resource_format = YuvResourceFormat(bits_per_channel);
}
// If GPU compositing is enabled, but the output resource format
@@ -780,37 +800,43 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
output_color_space = output_color_space.GetAsFullRangeRGB();
}
- // Drop recycled resources that are the wrong format.
- auto can_delete_resource_fn =
- [output_resource_format](const std::unique_ptr<PlaneResource>& resource) {
- return !resource->has_refs() &&
- resource->resource_format() != output_resource_format;
- };
- base::EraseIf(all_resources_, can_delete_resource_fn);
- // TODO(kylechar): Delete resources that are the wrong size for all output
- // planes.
-
- const int max_resource_size = resource_provider_->max_texture_size();
- std::vector<PlaneResource*> plane_resources;
+ std::vector<gfx::Size> outplane_plane_sizes;
+ outplane_plane_sizes.reserve(output_plane_count);
for (size_t i = 0; i < output_plane_count; ++i) {
- gfx::Size output_plane_resource_size =
- SoftwarePlaneDimension(video_frame.get(), software_compositor(), i);
+ outplane_plane_sizes.push_back(
+ SoftwarePlaneDimension(video_frame.get(), software_compositor(), i));
+ const gfx::Size& output_plane_resource_size = outplane_plane_sizes.back();
if (output_plane_resource_size.IsEmpty() ||
- output_plane_resource_size.width() > max_resource_size ||
- output_plane_resource_size.height() > max_resource_size) {
- // This output plane has invalid geometry. Clean up and return an empty
- // external resources.
- for (auto* plane_resource : plane_resources)
- plane_resource->remove_ref();
+ output_plane_resource_size.width() > max_resource_size_ ||
+ output_plane_resource_size.height() > max_resource_size_) {
+ // This output plane has invalid geometry so return an empty external
+ // resources.
return VideoFrameExternalResources();
}
+ }
- PlaneResource* plane_resource = RecycleOrAllocateResource(
- output_plane_resource_size, output_resource_format, output_color_space,
- video_frame->unique_id(), i);
+ // Delete recycled resources that are the wrong format or wrong size.
+ auto can_delete_resource_fn =
+ [output_resource_format,
+ &outplane_plane_sizes](const std::unique_ptr<PlaneResource>& resource) {
+ // Resources that are still being used can't be deleted.
+ if (resource->has_refs())
+ return false;
+
+ return resource->resource_format() != output_resource_format ||
+ !base::ContainsValue(outplane_plane_sizes,
+ resource->resource_size());
+ };
+ base::EraseIf(all_resources_, can_delete_resource_fn);
- plane_resource->add_ref();
- plane_resources.push_back(plane_resource);
+ // Recycle or allocate resources for each video plane.
+ std::vector<PlaneResource*> plane_resources;
+ plane_resources.reserve(output_plane_count);
+ for (size_t i = 0; i < output_plane_count; ++i) {
+ plane_resources.push_back(RecycleOrAllocateResource(
+ outplane_plane_sizes[i], output_resource_format, output_color_space,
+ video_frame->unique_id(), i));
+ plane_resources.back()->add_ref();
}
VideoFrameExternalResources external_resources;
@@ -874,7 +900,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
SoftwarePlaneResource* software_resource = plane_resource->AsSoftware();
external_resources.type = VideoFrameResourceType::RGBA_PREMULTIPLIED;
transferable_resource = viz::TransferableResource::MakeSoftware(
- software_resource->shared_bitmap_id(), 0 /* sequence_number */,
+ software_resource->shared_bitmap_id(),
software_resource->resource_size(),
plane_resource->resource_format());
} else {
@@ -902,7 +928,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
}
const viz::ResourceFormat yuv_resource_format =
- resource_provider_->YuvResourceFormat(bits_per_channel);
+ YuvResourceFormat(bits_per_channel);
DCHECK(yuv_resource_format == viz::LUMINANCE_F16 ||
yuv_resource_format == viz::R16_EXT ||
yuv_resource_format == viz::LUMINANCE_8 ||
diff --git a/chromium/cc/resources/video_resource_updater.h b/chromium/cc/resources/video_resource_updater.h
index 6d152ef2d85..0b3f651bed6 100644
--- a/chromium/cc/resources/video_resource_updater.h
+++ b/chromium/cc/resources/video_resource_updater.h
@@ -38,10 +38,10 @@ class Transform;
namespace viz {
class ContextProvider;
class RenderPass;
+class SharedBitmapReporter;
}
namespace cc {
-class LayerTreeFrameSink;
class LayerTreeResourceProvider;
// Specifies what type of data is contained in the mailboxes, as well as how
@@ -79,22 +79,21 @@ class CC_EXPORT VideoResourceUpdater
: public base::trace_event::MemoryDumpProvider {
public:
// For GPU compositing |context_provider| should be provided and for software
- // compositing |layer_tree_frame_sink| should be provided. If there is a
+ // compositing |shared_bitmap_reporter| should be provided. If there is a
// non-null |context_provider| we assume GPU compositing.
- // TODO(kylechar): Don't use LayerTreeFrameSink for the software compositing
- // path. The UseSurfaceLayerForVideo path isn't compatible with this. We can
- // maybe use mojom::CompositorFrameSink instead.
VideoResourceUpdater(viz::ContextProvider* context_provider,
- LayerTreeFrameSink* layer_tree_frame_sink,
+ viz::SharedBitmapReporter* shared_bitmap_reporter,
LayerTreeResourceProvider* resource_provider,
bool use_stream_video_draw_quad,
- bool use_gpu_memory_buffer_resources);
+ bool use_gpu_memory_buffer_resources,
+ bool use_r16_texture,
+ int max_resource_size);
~VideoResourceUpdater() override;
// For each CompositorFrame the following sequence is expected:
// 1. ObtainFrameResources(): Import resources for the next video frame with
- // LayerTreeResourceProvider. This will reuse existing GPU or SharedBitmap
+ // LayerTreeResourceProvider. This will reuse existing GPU or SharedMemory
// buffers if possible, otherwise it will allocate new ones.
// 2. AppendQuads(): Add DrawQuads to CompositorFrame for video.
// 3. ReleaseFrameResources(): After the CompositorFrame has been submitted,
@@ -117,6 +116,8 @@ class CC_EXPORT VideoResourceUpdater
VideoFrameExternalResources CreateExternalResourcesFromVideoFrame(
scoped_refptr<media::VideoFrame> video_frame);
+ viz::ResourceFormat YuvResourceFormat(int bits_per_channel);
+
private:
class PlaneResource;
class HardwarePlaneResource;
@@ -181,10 +182,13 @@ class CC_EXPORT VideoResourceUpdater
base::trace_event::ProcessMemoryDump* pmd) override;
viz::ContextProvider* const context_provider_;
- LayerTreeFrameSink* const layer_tree_frame_sink_;
+ viz::SharedBitmapReporter* const shared_bitmap_reporter_;
LayerTreeResourceProvider* const resource_provider_;
const bool use_stream_video_draw_quad_;
const bool use_gpu_memory_buffer_resources_;
+ // TODO(crbug.com/759456): Remove after r16 is used without the flag.
+ const bool use_r16_texture_;
+ const int max_resource_size_;
const int tracing_id_;
std::unique_ptr<media::PaintCanvasVideoRenderer> video_renderer_;
uint32_t next_plane_resource_id_ = 1;
diff --git a/chromium/cc/resources/video_resource_updater_unittest.cc b/chromium/cc/resources/video_resource_updater_unittest.cc
index 17b44064587..a26069cdd48 100644
--- a/chromium/cc/resources/video_resource_updater_unittest.cc
+++ b/chromium/cc/resources/video_resource_updater_unittest.cc
@@ -8,11 +8,12 @@
#include <stdint.h>
#include "base/bind.h"
-#include "cc/resources/resource_provider.h"
+#include "cc/resources/layer_tree_resource_provider.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_resource_provider.h"
#include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/video_frame.h"
@@ -21,9 +22,9 @@
namespace cc {
namespace {
-class WebGraphicsContext3DUploadCounter : public viz::TestWebGraphicsContext3D {
+class UploadCounterGLES2Interface : public viz::TestGLES2Interface {
public:
- void texSubImage2D(GLenum target,
+ void TexSubImage2D(GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
@@ -35,26 +36,20 @@ class WebGraphicsContext3DUploadCounter : public viz::TestWebGraphicsContext3D {
++upload_count_;
}
- void texStorage2DEXT(GLenum target,
+ void TexStorage2DEXT(GLenum target,
GLint levels,
GLuint internalformat,
GLint width,
- GLint height) override {
- }
-
- GLuint createTexture() override {
- ++created_texture_count_;
- return TestWebGraphicsContext3D::createTexture();
- }
+ GLint height) override {}
- void deleteTexture(GLuint texture) override {
- --created_texture_count_;
- TestWebGraphicsContext3D::deleteTexture(texture);
+ void GenTextures(GLsizei n, GLuint* textures) override {
+ created_texture_count_ += n;
+ viz::TestGLES2Interface::GenTextures(n, textures);
}
- void deleteTextures(GLsizei count, const GLuint* ids) override {
- created_texture_count_ -= count;
- TestWebGraphicsContext3D::deleteTextures(count, ids);
+ void DeleteTextures(GLsizei n, const GLuint* textures) override {
+ created_texture_count_ -= n;
+ viz::TestGLES2Interface::DeleteTextures(n, textures);
}
int UploadCount() { return upload_count_; }
@@ -71,13 +66,13 @@ class WebGraphicsContext3DUploadCounter : public viz::TestWebGraphicsContext3D {
class VideoResourceUpdaterTest : public testing::Test {
protected:
VideoResourceUpdaterTest() {
- std::unique_ptr<WebGraphicsContext3DUploadCounter> context3d(
- new WebGraphicsContext3DUploadCounter());
+ std::unique_ptr<UploadCounterGLES2Interface> gl(
+ new UploadCounterGLES2Interface());
- context3d_ = context3d.get();
- context3d_->set_support_texture_storage(true);
+ gl_ = gl.get();
+ gl_->set_support_texture_storage(true);
- context_provider_ = viz::TestContextProvider::Create(std::move(context3d));
+ context_provider_ = viz::TestContextProvider::Create(std::move(gl));
context_provider_->BindToCurrentThread();
}
@@ -87,17 +82,17 @@ class VideoResourceUpdaterTest : public testing::Test {
layer_tree_frame_sink_software_ = FakeLayerTreeFrameSink::CreateSoftware();
resource_provider3d_ =
FakeResourceProvider::CreateLayerTreeResourceProvider(
- context_provider_.get(), nullptr, nullptr, high_bit_for_testing_);
+ context_provider_.get());
resource_provider_software_ =
- FakeResourceProvider::CreateLayerTreeResourceProvider(
- nullptr, nullptr, nullptr, high_bit_for_testing_);
+ FakeResourceProvider::CreateLayerTreeResourceProvider(nullptr);
}
std::unique_ptr<VideoResourceUpdater> CreateUpdaterForHardware(
bool use_stream_video_draw_quad = false) {
return std::make_unique<VideoResourceUpdater>(
context_provider_.get(), nullptr, resource_provider3d_.get(),
- use_stream_video_draw_quad, /*use_gpu_memory_buffer_resources=*/false);
+ use_stream_video_draw_quad, /*use_gpu_memory_buffer_resources=*/false,
+ /*use_r16_texture=*/use_r16_texture_, /*max_resource_size=*/10000);
}
std::unique_ptr<VideoResourceUpdater> CreateUpdaterForSoftware() {
@@ -105,15 +100,21 @@ class VideoResourceUpdaterTest : public testing::Test {
nullptr, layer_tree_frame_sink_software_.get(),
resource_provider_software_.get(),
/*use_stream_video_draw_quad=*/false,
- /*use_gpu_memory_buffer_resources=*/false);
+ /*use_gpu_memory_buffer_resources=*/false,
+ /*use_r16_texture=*/false,
+ /*max_resource_size=*/10000);
}
- scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
- const int kDimension = 10;
- gfx::Size size(kDimension, kDimension);
- static uint8_t y_data[kDimension * kDimension] = {0};
- static uint8_t u_data[kDimension * kDimension / 2] = {0};
- static uint8_t v_data[kDimension * kDimension / 2] = {0};
+ // Note that the number of pixels needed for |size| must be less than or equal
+ // to the number of pixels needed for size of 100x100.
+ scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame(
+ const gfx::Size& size = gfx::Size(10, 10)) {
+ constexpr int kMaxDimension = 100;
+ static uint8_t y_data[kMaxDimension * kMaxDimension] = {0};
+ static uint8_t u_data[kMaxDimension * kMaxDimension / 2] = {0};
+ static uint8_t v_data[kMaxDimension * kMaxDimension / 2] = {0};
+
+ CHECK_LE(size.width() * size.height(), kMaxDimension * kMaxDimension);
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::WrapExternalYuvData(
@@ -240,13 +241,13 @@ class VideoResourceUpdaterTest : public testing::Test {
static const gpu::SyncToken kMailboxSyncToken;
- WebGraphicsContext3DUploadCounter* context3d_;
+ UploadCounterGLES2Interface* gl_;
scoped_refptr<viz::TestContextProvider> context_provider_;
std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink_software_;
std::unique_ptr<LayerTreeResourceProvider> resource_provider3d_;
std::unique_ptr<LayerTreeResourceProvider> resource_provider_software_;
gpu::SyncToken release_sync_token_;
- bool high_bit_for_testing_ = false;
+ bool use_r16_texture_ = false;
};
const gpu::SyncToken VideoResourceUpdaterTest::kMailboxSyncToken =
@@ -275,7 +276,7 @@ TEST_F(VideoResourceUpdaterTest, HighBitFrameNoF16) {
class VideoResourceUpdaterTestWithF16 : public VideoResourceUpdaterTest {
public:
VideoResourceUpdaterTestWithF16() : VideoResourceUpdaterTest() {
- context3d_->set_support_texture_half_float_linear(true);
+ gl_->set_support_texture_half_float_linear(true);
}
};
@@ -301,8 +302,8 @@ TEST_F(VideoResourceUpdaterTestWithF16, HighBitFrame) {
class VideoResourceUpdaterTestWithR16 : public VideoResourceUpdaterTest {
public:
VideoResourceUpdaterTestWithR16() : VideoResourceUpdaterTest() {
- high_bit_for_testing_ = true;
- context3d_->set_support_texture_norm16(true);
+ use_r16_texture_ = true;
+ gl_->set_support_texture_norm16(true);
}
};
@@ -361,14 +362,14 @@ TEST_F(VideoResourceUpdaterTest, ReuseResource) {
video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
// Allocate the resources for a YUV video frame.
- context3d_->ResetUploadCount();
+ gl_->ResetUploadCount();
VideoFrameExternalResources resources =
updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
EXPECT_EQ(3u, resources.resources.size());
EXPECT_EQ(3u, resources.release_callbacks.size());
// Expect exactly three texture uploads, one for each plane.
- EXPECT_EQ(3, context3d_->UploadCount());
+ EXPECT_EQ(3, gl_->UploadCount());
// Simulate the ResourceProvider releasing the resources back to the video
// updater.
@@ -376,13 +377,13 @@ TEST_F(VideoResourceUpdaterTest, ReuseResource) {
std::move(release_callback).Run(gpu::SyncToken(), false);
// Allocate resources for the same frame.
- context3d_->ResetUploadCount();
+ gl_->ResetUploadCount();
resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
EXPECT_EQ(3u, resources.resources.size());
EXPECT_EQ(3u, resources.release_callbacks.size());
// The data should be reused so expect no texture uploads.
- EXPECT_EQ(0, context3d_->UploadCount());
+ EXPECT_EQ(0, gl_->UploadCount());
}
TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
@@ -391,23 +392,23 @@ TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
// Allocate the resources for a YUV video frame.
- context3d_->ResetUploadCount();
+ gl_->ResetUploadCount();
VideoFrameExternalResources resources =
updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
EXPECT_EQ(3u, resources.resources.size());
EXPECT_EQ(3u, resources.release_callbacks.size());
// Expect exactly three texture uploads, one for each plane.
- EXPECT_EQ(3, context3d_->UploadCount());
+ EXPECT_EQ(3, gl_->UploadCount());
// Allocate resources for the same frame.
- context3d_->ResetUploadCount();
+ gl_->ResetUploadCount();
resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
EXPECT_EQ(3u, resources.resources.size());
EXPECT_EQ(3u, resources.release_callbacks.size());
// The data should be reused so expect no texture uploads.
- EXPECT_EQ(0, context3d_->UploadCount());
+ EXPECT_EQ(0, gl_->UploadCount());
}
TEST_F(VideoResourceUpdaterTest, SoftwareFrameSoftwareCompositor) {
@@ -473,6 +474,35 @@ TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDeleteSoftwareCompositor) {
EXPECT_EQ(layer_tree_frame_sink_software_->shared_bitmaps(), shared_bitmaps);
}
+TEST_F(VideoResourceUpdaterTest, ChangeResourceSizeSoftwareCompositor) {
+ constexpr gfx::Size kSize1(10, 10);
+ constexpr gfx::Size kSize2(20, 20);
+
+ std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
+
+ // Allocate the resources for a software video frame.
+ VideoFrameExternalResources resources =
+ updater->CreateExternalResourcesFromVideoFrame(
+ CreateTestYUVVideoFrame(kSize1));
+ // Expect exactly one allocated shared bitmap.
+ EXPECT_EQ(1u, layer_tree_frame_sink_software_->shared_bitmaps().size());
+ auto shared_bitmaps = layer_tree_frame_sink_software_->shared_bitmaps();
+
+ // Simulate the ResourceProvider releasing the resource back to the video
+ // updater.
+ std::move(resources.release_callbacks[0]).Run(gpu::SyncToken(), false);
+
+ // Allocate resources for the next frame with a different size.
+ resources = updater->CreateExternalResourcesFromVideoFrame(
+ CreateTestYUVVideoFrame(kSize2));
+
+ // The first resource was released, so it can be reused but it's the wrong
+ // size. We should expect the first shared bitmap to be deleted and a new
+ // shared bitmap to be allocated.
+ EXPECT_EQ(1u, layer_tree_frame_sink_software_->shared_bitmaps().size());
+ EXPECT_NE(layer_tree_frame_sink_software_->shared_bitmaps(), shared_bitmaps);
+}
+
TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes) {
std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
@@ -511,7 +541,7 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_StreamTexture) {
// Note that |use_stream_video_draw_quad| is true for this test.
std::unique_ptr<VideoResourceUpdater> updater =
CreateUpdaterForHardware(true);
- context3d_->ResetTextureCreationCount();
+ gl_->ResetTextureCreationCount();
scoped_refptr<media::VideoFrame> video_frame =
CreateTestStreamTextureHardwareVideoFrame(false);
@@ -522,11 +552,11 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_StreamTexture) {
EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
resources.resources[0].mailbox_holder.texture_target);
EXPECT_EQ(1u, resources.release_callbacks.size());
- EXPECT_EQ(0, context3d_->TextureCreationCount());
+ EXPECT_EQ(0, gl_->TextureCreationCount());
// A copied stream texture should return an RGBA resource in a new
// GL_TEXTURE_2D texture.
- context3d_->ResetTextureCreationCount();
+ gl_->ResetTextureCreationCount();
video_frame = CreateTestStreamTextureHardwareVideoFrame(true);
resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
@@ -534,12 +564,12 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_StreamTexture) {
EXPECT_EQ((GLenum)GL_TEXTURE_2D,
resources.resources[0].mailbox_holder.texture_target);
EXPECT_EQ(1u, resources.release_callbacks.size());
- EXPECT_EQ(1, context3d_->TextureCreationCount());
+ EXPECT_EQ(0, gl_->TextureCreationCount());
}
TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_TextureQuad) {
std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
- context3d_->ResetTextureCreationCount();
+ gl_->ResetTextureCreationCount();
scoped_refptr<media::VideoFrame> video_frame =
CreateTestStreamTextureHardwareVideoFrame(false);
@@ -550,7 +580,7 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_TextureQuad) {
EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
resources.resources[0].mailbox_holder.texture_target);
EXPECT_EQ(1u, resources.release_callbacks.size());
- EXPECT_EQ(0, context3d_->TextureCreationCount());
+ EXPECT_EQ(0, gl_->TextureCreationCount());
}
// Passthrough the sync token returned by the compositor if we don't have an
@@ -646,7 +676,7 @@ TEST_F(VideoResourceUpdaterTest, GenerateSyncTokenOnTextureCopy) {
// of the underlying buffer, that is YUV_420_BIPLANAR.
TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SingleNV12) {
std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
- context3d_->ResetTextureCreationCount();
+ gl_->ResetTextureCreationCount();
scoped_refptr<media::VideoFrame> video_frame = CreateTestHardwareVideoFrame(
media::PIXEL_FORMAT_NV12, GL_TEXTURE_EXTERNAL_OES);
@@ -669,12 +699,12 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SingleNV12) {
EXPECT_EQ(gfx::BufferFormat::YUV_420_BIPLANAR,
resources.resources[0].buffer_format);
- EXPECT_EQ(0, context3d_->TextureCreationCount());
+ EXPECT_EQ(0, gl_->TextureCreationCount());
}
TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_DualNV12) {
std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
- context3d_->ResetTextureCreationCount();
+ gl_->ResetTextureCreationCount();
scoped_refptr<media::VideoFrame> video_frame =
CreateTestYuvHardwareVideoFrame(media::PIXEL_FORMAT_NV12, 2,
GL_TEXTURE_EXTERNAL_OES);
@@ -697,8 +727,10 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_DualNV12) {
EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB,
resources.resources[0].mailbox_holder.texture_target);
EXPECT_EQ(gfx::BufferFormat::RGBA_8888, resources.resources[0].buffer_format);
-
- EXPECT_EQ(0, context3d_->TextureCreationCount());
+ // When TestWebGraphicsContext3D is used, createAndConsumeTextureCHROMIUM will
+ // call createTexture. But this is incorrect, so when this is converted to
+ // TestGLES2Interface, GenTextures will not being called.
+ EXPECT_EQ(0, gl_->TextureCreationCount());
}
} // namespace
diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc
index 20ec6a038fa..dd4d8f8a958 100644
--- a/chromium/cc/scheduler/compositor_timing_history.cc
+++ b/chromium/cc/scheduler/compositor_timing_history.cc
@@ -54,8 +54,6 @@ class CompositorTimingHistory::UMAReporter {
base::TimeDelta duration) = 0;
virtual void AddDrawIntervalWithMainThreadAnimations(
base::TimeDelta duration) = 0;
- virtual void AddDrawIntervalWithMainThreadCompositableAnimations(
- base::TimeDelta duration) = 0;
// Synchronization measurements
virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0;
@@ -198,13 +196,6 @@ class RendererUMAReporter : public CompositorTimingHistory::UMAReporter {
"Scheduling.Renderer.DrawIntervalWithMainThreadAnimations", interval);
}
- void AddDrawIntervalWithMainThreadCompositableAnimations(
- base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.DrawIntervalWithMainThreadCompositableAnimations",
- interval);
- }
-
void AddBeginImplFrameLatency(base::TimeDelta delta) override {
UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
"Scheduling.Renderer.BeginImplFrameLatency", delta);
@@ -325,15 +316,6 @@ class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
"Scheduling.Browser.DrawIntervalWithMainThreadAnimations", interval);
}
- void AddDrawIntervalWithMainThreadCompositableAnimations(
- base::TimeDelta interval) override {
- // Still report, but the data is not meaningful.
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Browser."
- "DrawIntervalWithMainThreadCompositableAnimations",
- interval);
- }
-
void AddBeginImplFrameLatency(base::TimeDelta delta) override {
UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
"Scheduling.Browser.BeginImplFrameLatency", delta);
@@ -428,8 +410,6 @@ class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
base::TimeDelta inverval) override {}
void AddDrawIntervalWithMainThreadAnimations(
base::TimeDelta inverval) override {}
- void AddDrawIntervalWithMainThreadCompositableAnimations(
- base::TimeDelta interval) override {}
void AddBeginImplFrameLatency(base::TimeDelta delta) override {}
void AddBeginMainFrameQueueDurationCriticalDuration(
base::TimeDelta duration) override {}
@@ -883,7 +863,6 @@ void CompositorTimingHistory::DidDraw(
base::TimeTicks impl_frame_time,
size_t composited_animations_count,
size_t main_thread_animations_count,
- size_t main_thread_compositable_animations_count,
bool current_frame_had_raf,
bool next_frame_has_pending_raf) {
DCHECK_NE(base::TimeTicks(), draw_start_time_);
@@ -936,17 +915,8 @@ void CompositorTimingHistory::DidDraw(
draw_end_time - new_active_tree_draw_end_time_prev_;
uma_reporter_->AddDrawIntervalWithMainThreadAnimations(draw_interval);
}
- if (main_thread_compositable_animations_count > 0 &&
- previous_frame_had_main_thread_compositable_animations_) {
- base::TimeDelta draw_interval =
- draw_end_time - new_active_tree_draw_end_time_prev_;
- uma_reporter_->AddDrawIntervalWithMainThreadCompositableAnimations(
- draw_interval);
- }
previous_frame_had_main_thread_animations_ =
main_thread_animations_count > 0;
- previous_frame_had_main_thread_compositable_animations_ =
- main_thread_compositable_animations_count > 0;
// It's possible that two consecutive main frames both run a rAF but are
// separated by idle time (for example: calling requestAnimationFrame from a
// setInterval function, with nothing else producing a main frame
diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h
index 16b03390299..84aa1545eba 100644
--- a/chromium/cc/scheduler/compositor_timing_history.h
+++ b/chromium/cc/scheduler/compositor_timing_history.h
@@ -82,7 +82,6 @@ class CC_EXPORT CompositorTimingHistory {
base::TimeTicks impl_frame_time,
size_t composited_animations_count,
size_t main_thread_animations_count,
- size_t main_thread_compositable_animations_count,
bool current_frame_had_raf,
bool next_frame_has_pending_raf);
void DidSubmitCompositorFrame();
@@ -164,7 +163,6 @@ class CC_EXPORT CompositorTimingHistory {
// Used only for reporting animation targeted UMA.
bool previous_frame_had_composited_animations_ = false;
bool previous_frame_had_main_thread_animations_ = false;
- bool previous_frame_had_main_thread_compositable_animations_ = false;
bool previous_frame_had_raf_ = false;
TreePriority tree_priority_ = SAME_PRIORITY_FOR_BOTH_TREES;
diff --git a/chromium/cc/scheduler/compositor_timing_history_unittest.cc b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
index a086de7af3c..564bc81c8bd 100644
--- a/chromium/cc/scheduler/compositor_timing_history_unittest.cc
+++ b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
@@ -46,7 +46,6 @@ class CompositorTimingHistoryTest : public testing::Test {
void DrawMainFrame(int advance_ms,
int composited_animations_count,
int main_thread_animations_count,
- int main_thread_compositable_animations_count,
bool current_frame_had_raf = false,
bool next_frame_has_pending_raf = false) {
timing_history_.WillBeginMainFrame(true, Now());
@@ -60,14 +59,12 @@ class CompositorTimingHistoryTest : public testing::Test {
AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms));
timing_history_.DidDraw(true, Now(), composited_animations_count,
main_thread_animations_count,
- main_thread_compositable_animations_count,
current_frame_had_raf, next_frame_has_pending_raf);
}
void DrawImplFrame(int advance_ms,
int composited_animations_count,
- int main_thread_animations_count,
- int main_thread_compositable_animations_count) {
+ int main_thread_animations_count) {
timing_history_.WillBeginMainFrame(true, Now());
timing_history_.BeginMainFrameStarted(Now());
timing_history_.BeginMainFrameAborted();
@@ -75,9 +72,8 @@ class CompositorTimingHistoryTest : public testing::Test {
timing_history_.DidActivate();
timing_history_.WillDraw();
AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms));
- timing_history_.DidDraw(
- false, Now(), composited_animations_count, main_thread_animations_count,
- main_thread_compositable_animations_count, false, false);
+ timing_history_.DidDraw(false, Now(), composited_animations_count,
+ main_thread_animations_count, false, false);
}
protected:
@@ -130,7 +126,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(true, Now(), 0, 0, 0, false, false);
+ timing_history_.DidDraw(true, Now(), 0, 0, false, false);
EXPECT_EQ(begin_main_frame_queue_duration,
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
@@ -181,7 +177,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(false, Now(), 0, 0, 0, false, false);
+ timing_history_.DidDraw(false, Now(), 0, 0, false, false);
EXPECT_EQ(base::TimeDelta(),
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
@@ -295,150 +291,142 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
}
-void TestAnimationUMA(
- const base::HistogramTester& histogram_tester,
- base::HistogramBase::Count composited_animation_frames,
- base::HistogramBase::Count main_thread_animation_frames,
- base::HistogramBase::Count main_thread_compositable_animation_frames) {
+void TestAnimationUMA(const base::HistogramTester& histogram_tester,
+ base::HistogramBase::Count composited_animation_frames,
+ base::HistogramBase::Count main_thread_animation_frames) {
histogram_tester.ExpectTotalCount(
"Scheduling.Renderer.DrawIntervalWithCompositedAnimations2",
composited_animation_frames);
histogram_tester.ExpectTotalCount(
"Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2",
main_thread_animation_frames);
- histogram_tester.ExpectTotalCount(
- "Scheduling.Renderer.DrawIntervalWithMainThreadCompositableAnimations2",
- main_thread_compositable_animation_frames);
}
TEST_F(CompositorTimingHistoryTest, AnimationNotReported) {
base::HistogramTester histogram_tester;
// Initial frame has no main-thread animations or rAF.
- DrawMainFrame(123, 0, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 0);
+ TestAnimationUMA(histogram_tester, 0, 0);
// The next frame has one composited and one main thread animation running,
// but as the previous frame had no animation we shouldn't report anything.
- DrawMainFrame(456, 1, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(456, 1, 1);
+ TestAnimationUMA(histogram_tester, 0, 0);
- DrawMainFrame(123, 0, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 0);
+ TestAnimationUMA(histogram_tester, 0, 0);
// The next frame has just one main thread animation running, but again as the
// previous frame had no animation we shouldn't report anything.
- DrawMainFrame(456, 0, 1, 1);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(456, 0, 1);
+ TestAnimationUMA(histogram_tester, 0, 0);
- DrawMainFrame(123, 0, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 0);
+ TestAnimationUMA(histogram_tester, 0, 0);
// The next frame has no main thread animations but did have a rAF callback.
// Again as the previous frame had no visual change we shouldn't report.
- DrawMainFrame(123, 0, 0, 0, true);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 0, true);
+ TestAnimationUMA(histogram_tester, 0, 0);
- DrawMainFrame(123, 0, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 0);
+ TestAnimationUMA(histogram_tester, 0, 0);
// Finally, test the combination of both main thread animations and rAF
// callbacks being called.
- DrawMainFrame(123, 1, 2, 0, true);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 1, 2, true);
+ TestAnimationUMA(histogram_tester, 0, 0);
}
TEST_F(CompositorTimingHistoryTest, ConsecutiveFramesAnimationsReported) {
base::HistogramTester histogram_tester;
- DrawMainFrame(123, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 1, 0);
+ TestAnimationUMA(histogram_tester, 0, 0);
- DrawMainFrame(456, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 1, 0, 0);
+ DrawMainFrame(456, 1, 0);
+ TestAnimationUMA(histogram_tester, 1, 0);
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1);
- DrawMainFrame(321, 0, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 0, 0);
+ DrawMainFrame(321, 0, 1);
+ TestAnimationUMA(histogram_tester, 1, 0);
- DrawMainFrame(654, 0, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 1, 0);
+ DrawMainFrame(654, 0, 1);
+ TestAnimationUMA(histogram_tester, 1, 1);
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2", 654, 1);
- DrawMainFrame(123, 0, 1, 1);
- TestAnimationUMA(histogram_tester, 1, 2, 0);
+ DrawMainFrame(123, 0, 1);
+ TestAnimationUMA(histogram_tester, 1, 2);
- DrawMainFrame(456, 0, 1, 1);
- TestAnimationUMA(histogram_tester, 1, 3, 1);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithMainThreadCompositableAnimations2",
- 456, 1);
+ DrawMainFrame(456, 0, 1);
+ TestAnimationUMA(histogram_tester, 1, 3);
// Main thread and rAF animations are both considered to be part of the same
// animation type.
- DrawMainFrame(789, 0, 0, 0, true, true);
- TestAnimationUMA(histogram_tester, 1, 4, 1);
+ DrawMainFrame(789, 0, 0, true, true);
+ TestAnimationUMA(histogram_tester, 1, 4);
- DrawMainFrame(987, 0, 1, 0, false);
- TestAnimationUMA(histogram_tester, 1, 5, 1);
+ DrawMainFrame(987, 0, 1, false);
+ TestAnimationUMA(histogram_tester, 1, 5);
// However if there is no pending rAF for a frame, we don't count the one
// after it as being linked.
- DrawMainFrame(789, 0, 0, 0, true, false);
- TestAnimationUMA(histogram_tester, 1, 6, 1);
+ DrawMainFrame(789, 0, 0, true, false);
+ TestAnimationUMA(histogram_tester, 1, 6);
- DrawMainFrame(987, 0, 0, 0, true, true);
- TestAnimationUMA(histogram_tester, 1, 6, 1);
+ DrawMainFrame(987, 0, 0, true, true);
+ TestAnimationUMA(histogram_tester, 1, 6);
}
TEST_F(CompositorTimingHistoryTest, InterFrameAnimationsNotReported) {
base::HistogramTester histogram_tester;
- DrawMainFrame(123, 0, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawMainFrame(123, 0, 1);
+ TestAnimationUMA(histogram_tester, 0, 0);
// The previous frame had a main thread animation, where the current one is
// main thread compositable animation, we don't measure the timing from a
// different animation type.
- DrawMainFrame(456, 0, 1, 1);
- TestAnimationUMA(histogram_tester, 0, 1, 0);
+ DrawMainFrame(456, 0, 1);
+ TestAnimationUMA(histogram_tester, 0, 1);
- DrawMainFrame(321, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 1, 0);
+ DrawMainFrame(321, 1, 0);
+ TestAnimationUMA(histogram_tester, 0, 1);
- DrawMainFrame(654, 0, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 1, 0);
+ DrawMainFrame(654, 0, 1);
+ TestAnimationUMA(histogram_tester, 0, 1);
- DrawMainFrame(123, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 1, 0);
+ DrawMainFrame(123, 1, 0);
+ TestAnimationUMA(histogram_tester, 0, 1);
}
TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) {
base::HistogramTester histogram_tester;
- DrawImplFrame(123, 1, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 0, 0);
+ DrawImplFrame(123, 1, 1);
+ TestAnimationUMA(histogram_tester, 0, 0);
- DrawImplFrame(456, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 1, 0, 0);
+ DrawImplFrame(456, 1, 0);
+ TestAnimationUMA(histogram_tester, 1, 0);
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1);
- DrawMainFrame(321, 0, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 0, 0);
+ DrawMainFrame(321, 0, 1);
+ TestAnimationUMA(histogram_tester, 1, 0);
// This frame verifies that we record that there is a composited animation,
// so in the next frame when there is a composited animation, we report it.
- DrawImplFrame(234, 1, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 0, 0);
+ DrawImplFrame(234, 1, 1);
+ TestAnimationUMA(histogram_tester, 1, 0);
// Even though the previous frame had no main thread animation, we report it
// in this frame because the previous main frame had a main thread animation
// with the time between main frame draws.
- DrawMainFrame(654, 1, 1, 0);
- TestAnimationUMA(histogram_tester, 2, 1, 0);
+ DrawMainFrame(654, 1, 1);
+ TestAnimationUMA(histogram_tester, 2, 1);
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 654, 1);
// The recorded time for this main thread animation should be the total time
@@ -446,8 +434,8 @@ TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) {
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2", 888, 1);
- DrawImplFrame(123, 1, 0, 0);
- TestAnimationUMA(histogram_tester, 3, 1, 0);
+ DrawImplFrame(123, 1, 0);
+ TestAnimationUMA(histogram_tester, 3, 1);
histogram_tester.ExpectBucketCount(
"Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 123, 1);
}
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index 352c8649bc6..87db539737f 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -658,7 +658,6 @@ void Scheduler::DrawIfPossible() {
begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time,
client_->CompositedAnimationsCount(),
client_->MainThreadAnimationsCount(),
- client_->MainThreadCompositableAnimationsCount(),
client_->CurrentFrameHadRAF(), client_->NextFrameHasPendingRAF());
}
@@ -677,7 +676,6 @@ void Scheduler::DrawForced() {
begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time,
client_->CompositedAnimationsCount(),
client_->MainThreadAnimationsCount(),
- client_->MainThreadCompositableAnimationsCount(),
client_->CurrentFrameHadRAF(), client_->NextFrameHasPendingRAF());
}
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index 10cb198610e..79ec95b21d4 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -55,7 +55,6 @@ class SchedulerClient {
// Functions used for reporting anmation targeting UMA, crbug.com/758439.
virtual size_t CompositedAnimationsCount() const = 0;
virtual size_t MainThreadAnimationsCount() const = 0;
- virtual size_t MainThreadCompositableAnimationsCount() const = 0;
virtual bool CurrentFrameHadRAF() const = 0;
virtual bool NextFrameHasPendingRAF() const = 0;
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index a4e1fddba04..d1fcefb1c79 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -12,7 +12,6 @@
#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
#include "base/run_loop.h"
#include "base/time/time.h"
@@ -245,7 +244,6 @@ class FakeSchedulerClient : public SchedulerClient,
size_t CompositedAnimationsCount() const override { return 0; }
size_t MainThreadAnimationsCount() const override { return 0; }
- size_t MainThreadCompositableAnimationsCount() const override { return 0; }
bool CurrentFrameHadRAF() const override { return false; }
bool NextFrameHasPendingRAF() const override { return false; }
diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc
index 060eb020d1c..33385afc182 100644
--- a/chromium/cc/tiles/checker_image_tracker.cc
+++ b/chromium/cc/tiles/checker_image_tracker.cc
@@ -209,8 +209,6 @@ void CheckerImageTracker::ClearTracker(bool can_clear_decode_policy_tracking) {
// they should be accompanied with an invalidation during paint.
image_id_to_decode_.clear();
- decoding_mode_map_.clear();
-
if (can_clear_decode_policy_tracking) {
image_async_decode_state_.clear();
} else {
@@ -273,23 +271,12 @@ bool CheckerImageTracker::ShouldCheckerImage(const DrawImage& draw_image,
WhichTree tree) {
const PaintImage& image = draw_image.paint_image();
PaintImage::Id image_id = image.stable_id();
- TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
- image_id);
-
- auto decoding_mode_it = decoding_mode_map_.find(image_id);
- PaintImage::DecodingMode decoding_mode_hint =
- decoding_mode_it == decoding_mode_map_.end()
- ? PaintImage::DecodingMode::kUnspecified
- : decoding_mode_it->second;
+ TRACE_EVENT1("cc.debug", "CheckerImageTracker::ShouldCheckerImage",
+ "image_id", image_id);
- // If we don't have default checker imaging enabled, and the developer did not
- // specify "async" then we don't checker the images. To put it different, we
- // currently only not respect |enable_checker_imaging_| if the value was
- // specified as "async" by the developer.
- if (decoding_mode_hint != PaintImage::DecodingMode::kAsync &&
- !enable_checker_imaging_) {
+ // Checkering of all images is disabled.
+ if (!enable_checker_imaging_)
return false;
- }
// If the image was invalidated on the current sync tree and the tile is
// for the active tree, continue checkering it on the active tree to ensure
@@ -306,6 +293,16 @@ bool CheckerImageTracker::ShouldCheckerImage(const DrawImage& draw_image,
return true;
}
+ auto decoding_mode_it = decoding_mode_map_.find(image_id);
+ PaintImage::DecodingMode decoding_mode_hint =
+ decoding_mode_it == decoding_mode_map_.end()
+ ? PaintImage::DecodingMode::kUnspecified
+ : decoding_mode_it->second;
+
+ // We only checker images if the developer specifies async decoding mode.
+ if (decoding_mode_hint != PaintImage::DecodingMode::kAsync)
+ return false;
+
auto insert_result = image_async_decode_state_.insert(
std::pair<PaintImage::Id, DecodeState>(image_id, DecodeState()));
auto it = insert_result.first;
diff --git a/chromium/cc/tiles/checker_image_tracker_unittest.cc b/chromium/cc/tiles/checker_image_tracker_unittest.cc
index 0b4606f1463..88c3f10cdd6 100644
--- a/chromium/cc/tiles/checker_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/checker_image_tracker_unittest.cc
@@ -112,12 +112,16 @@ class CheckerImageTrackerTest : public testing::Test,
}
auto generator = CreatePaintImageGenerator(gfx::Size(dimension, dimension));
+ auto id = PaintImage::GetNextId();
+ checker_image_tracker_->UpdateImageDecodingHints(
+ {{id, PaintImage::DecodingMode::kAsync}});
return DrawImage(PaintImageBuilder::WithDefault()
- .set_id(PaintImage::GetNextId())
+ .set_id(id)
.set_paint_image_generator(std::move(generator))
.set_animation_type(animation)
.set_completion_state(completion)
.set_is_multipart(is_multipart)
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
.TakePaintImage(),
SkIRect::MakeWH(dimension, dimension),
kNone_SkFilterQuality, SkMatrix::I(),
@@ -379,8 +383,6 @@ TEST_F(CheckerImageTrackerTest, ClearsTracker) {
checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking);
image_decode_queue =
BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE);
- image_decode_queue =
- BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE);
EXPECT_EQ(image_decode_queue.size(), 1U);
// If an image had been decoded and tracker was cleared after it, we should
diff --git a/chromium/cc/tiles/decoded_image_tracker.cc b/chromium/cc/tiles/decoded_image_tracker.cc
index 0f8f0dda1f3..cd2d1eeb0b1 100644
--- a/chromium/cc/tiles/decoded_image_tracker.cc
+++ b/chromium/cc/tiles/decoded_image_tracker.cc
@@ -10,7 +10,11 @@ namespace {
const int kNumFramesToLock = 2;
} // namespace
-DecodedImageTracker::DecodedImageTracker() = default;
+DecodedImageTracker::DecodedImageTracker(ImageController* controller)
+ : image_controller_(controller) {
+ DCHECK(image_controller_);
+}
+
DecodedImageTracker::~DecodedImageTracker() {
for (auto& pair : locked_images_)
image_controller_->UnlockImageDecode(pair.first);
diff --git a/chromium/cc/tiles/decoded_image_tracker.h b/chromium/cc/tiles/decoded_image_tracker.h
index 4b9417ffe88..4321a02d13a 100644
--- a/chromium/cc/tiles/decoded_image_tracker.h
+++ b/chromium/cc/tiles/decoded_image_tracker.h
@@ -24,7 +24,7 @@ namespace cc {
// are silently ignored.
class CC_EXPORT DecodedImageTracker {
public:
- DecodedImageTracker();
+ explicit DecodedImageTracker(ImageController* controller);
~DecodedImageTracker();
// Request that the given image be decoded. This issues a callback upon
@@ -36,18 +36,13 @@ class CC_EXPORT DecodedImageTracker {
void NotifyFrameFinished();
private:
- friend class TileManager;
friend class DecodedImageTrackerTest;
- void set_image_controller(ImageController* controller) {
- image_controller_ = controller;
- }
-
void ImageDecodeFinished(const base::Callback<void(bool)>& callback,
ImageController::ImageDecodeRequestId id,
ImageController::ImageDecodeResult result);
- ImageController* image_controller_ = nullptr;
+ ImageController* image_controller_;
std::vector<std::pair<ImageController::ImageDecodeRequestId, int>>
locked_images_;
diff --git a/chromium/cc/tiles/decoded_image_tracker_unittest.cc b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
index f5bb5a37c65..365f93b6348 100644
--- a/chromium/cc/tiles/decoded_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
@@ -63,9 +63,7 @@ class TestImageController : public ImageController {
class DecodedImageTrackerTest : public testing::Test {
public:
- void SetUp() override {
- decoded_image_tracker_.set_image_controller(image_controller());
- }
+ DecodedImageTrackerTest() : decoded_image_tracker_(&image_controller_) {}
TestImageController* image_controller() { return &image_controller_; }
DecodedImageTracker* decoded_image_tracker() {
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 344515342af..efac77afbf7 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -25,7 +25,6 @@
#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 "skia/ext/texture_handle.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -189,14 +188,16 @@ bool DrawAndScaleImage(const DrawImage& draw_image, SkPixmap* target_pixmap) {
// Returns the GL texture ID backing the given SkImage.
GrGLuint GlIdFromSkImage(SkImage* image) {
DCHECK(image->isTextureBacked());
- GrBackendObject handle =
- image->getTextureHandle(true /* flushPendingGrContextIO */);
- if (!handle)
+ GrBackendTexture backend_texture =
+ image->getBackendTexture(true /* flushPendingGrContextIO */);
+ if (!backend_texture.isValid())
return 0;
- const GrGLTextureInfo* info = skia::GrBackendObjectToGrGLTextureInfo(handle);
- if (!info)
+
+ GrGLTextureInfo info;
+ if (!backend_texture.getGLTextureInfo(&info))
return 0;
- return info->fID;
+
+ return info.fID;
}
// Takes ownership of the backing texture of an SkImage. This allows us to
@@ -209,7 +210,7 @@ sk_sp<SkImage> TakeOwnershipOfSkImageBacking(GrContext* context,
}
GrSurfaceOrigin origin;
- image->getTextureHandle(false /* flushPendingGrContextIO */, &origin);
+ image->getBackendTexture(false /* flushPendingGrContextIO */, &origin);
SkColorType color_type = image->colorType();
if (color_type == kUnknown_SkColorType) {
return nullptr;
@@ -649,12 +650,6 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
if (SkipImage(draw_image))
return TaskResult(false);
- // For non-lazy images a decode isn't necessary.
- // TODO(khushalsagar): We can still have only the upload task to upload ahead
- // of raster.
- if (!draw_image.paint_image().IsLazyGenerated())
- return TaskResult(false);
-
base::AutoLock lock(lock_);
const PaintImage::FrameKey frame_key = draw_image.frame_key();
ImageData* image_data = GetImageDataForDrawImage(draw_image);
@@ -861,34 +856,38 @@ void GpuImageDecodeCache::SetShouldAggressivelyFreeResources(
void GpuImageDecodeCache::ClearCache() {
base::AutoLock lock(lock_);
- for (auto& entry : persistent_cache_) {
- if (entry.second->decode.ref_count != 0 ||
- entry.second->upload.ref_count != 0) {
- // Orphan the entry so it will be deleted once no longer in use.
- entry.second->is_orphaned = true;
- } else if (entry.second->HasUploadedData()) {
- DeleteImage(entry.second.get());
- }
- }
- persistent_cache_.Clear();
+ for (auto it = persistent_cache_.begin(); it != persistent_cache_.end();)
+ it = RemoveFromPersistentCache(it);
+ DCHECK(persistent_cache_.empty());
+ paint_image_entries_.clear();
}
-size_t GpuImageDecodeCache::GetMaximumMemoryLimitBytes() const {
- return max_working_set_bytes_;
-}
+GpuImageDecodeCache::PersistentCache::iterator
+GpuImageDecodeCache::RemoveFromPersistentCache(PersistentCache::iterator it) {
+ lock_.AssertAcquired();
-void GpuImageDecodeCache::NotifyImageUnused(
- const PaintImage::FrameKey& frame_key) {
- auto it = persistent_cache_.Peek(frame_key);
- if (it != persistent_cache_.end()) {
- if (it->second->decode.ref_count != 0 ||
- it->second->upload.ref_count != 0) {
- it->second->is_orphaned = true;
- } else if (it->second->HasUploadedData()) {
+ if (it->second->decode.ref_count != 0 || it->second->upload.ref_count != 0) {
+ // Orphan the image and erase it from the |persisent_cache_|. This ensures
+ // that the image will be deleted once all refs are removed.
+ it->second->is_orphaned = true;
+ } else {
+ // Current entry has no refs. Ensure it is not locked.
+ DCHECK(!it->second->decode.is_locked());
+ DCHECK(!it->second->upload.is_locked());
+
+ // Unlocked images must not be budgeted.
+ DCHECK(!it->second->is_budgeted);
+
+ // Free the uploaded image if it exists.
+ if (it->second->HasUploadedData())
DeleteImage(it->second.get());
- }
- persistent_cache_.Erase(it);
}
+
+ return persistent_cache_.Erase(it);
+}
+
+size_t GpuImageDecodeCache::GetMaximumMemoryLimitBytes() const {
+ return max_working_set_bytes_;
}
bool GpuImageDecodeCache::OnMemoryDump(
@@ -1346,16 +1345,8 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
image_info.minRowBytes());
// Set |pixmap| to the desired colorspace to decode into.
- if (!SupportsColorSpaceConversion()) {
- pixmap.setColorSpace(nullptr);
- } else if (image_data->mode == DecodedDataMode::kCpu) {
- pixmap.setColorSpace(draw_image.target_color_space().ToSkColorSpace());
- } else {
- // For kGpu or kTransferCache images color conversion is handled during
- // upload, so keep the original colorspace here.
- pixmap.setColorSpace(sk_ref_sp(draw_image.paint_image().color_space()));
- }
-
+ pixmap.setColorSpace(
+ ColorSpaceForImageDecode(draw_image, image_data->mode));
if (!DrawAndScaleImage(draw_image, &pixmap)) {
DLOG(ERROR) << "DrawAndScaleImage failed.";
backing_memory->Unlock();
@@ -1499,6 +1490,7 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
"GpuImageDecodeCache::CreateImageData");
lock_.AssertAcquired();
+ WillAddCacheEntry(draw_image);
int mip_level = CalculateUploadScaleMipLevel(draw_image);
SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image, mip_level);
@@ -1514,19 +1506,72 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
}
size_t data_size = image_info.computeMinByteSize();
+
+ // We need to cache the result of color conversion on the cpu if the image
+ // will be color converted during the decode.
+ auto decode_color_space = ColorSpaceForImageDecode(draw_image, mode);
+ const bool cache_color_conversion_on_cpu =
+ decode_color_space &&
+ !SkColorSpace::Equals(decode_color_space.get(),
+ draw_image.paint_image().color_space());
+
// |is_bitmap_backed| specifies whether the image has pixel data which can
// directly be used for the upload. This will be the case for non-lazy images
// used at the original scale. In these cases, we don't internally cache any
// cpu component for the image.
- // However, if the image will be scaled, we consider it a lazy image and cache
- // the scaled result in discardable memory.
- const bool is_bitmap_backed =
- !draw_image.paint_image().IsLazyGenerated() && mip_level == 0;
+ // However, if the image will be scaled or color converts on the cpu, we
+ // consider it a lazy image and cache the scaled result in discardable memory.
+ const bool is_bitmap_backed = !draw_image.paint_image().IsLazyGenerated() &&
+ mip_level == 0 &&
+ !cache_color_conversion_on_cpu;
return base::WrapRefCounted(new ImageData(
mode, data_size, draw_image.target_color_space(),
CalculateDesiredFilterQuality(draw_image), mip_level, is_bitmap_backed));
}
+void GpuImageDecodeCache::WillAddCacheEntry(const DrawImage& draw_image) {
+ lock_.AssertAcquired();
+
+ // Remove any old entries for this image. We keep at-most 2 ContentIds for a
+ // PaintImage (pending and active tree).
+ auto& cached_content_ids =
+ paint_image_entries_[draw_image.paint_image().stable_id()].content_ids;
+ const PaintImage::ContentId new_content_id =
+ draw_image.frame_key().content_id();
+
+ if (cached_content_ids[0] == new_content_id ||
+ cached_content_ids[1] == new_content_id) {
+ return;
+ }
+
+ if (cached_content_ids[0] == PaintImage::kInvalidContentId) {
+ cached_content_ids[0] = new_content_id;
+ return;
+ }
+
+ if (cached_content_ids[1] == PaintImage::kInvalidContentId) {
+ cached_content_ids[1] = new_content_id;
+ return;
+ }
+
+ const PaintImage::ContentId content_id_to_remove =
+ std::min(cached_content_ids[0], cached_content_ids[1]);
+ const PaintImage::ContentId content_id_to_keep =
+ std::max(cached_content_ids[0], cached_content_ids[1]);
+ DCHECK_NE(content_id_to_remove, content_id_to_keep);
+
+ for (auto it = persistent_cache_.begin(); it != persistent_cache_.end();) {
+ if (it->first.content_id() != content_id_to_remove) {
+ ++it;
+ } else {
+ it = RemoveFromPersistentCache(it);
+ }
+ }
+
+ cached_content_ids[0] = content_id_to_keep;
+ cached_content_ids[1] = new_content_id;
+}
+
void GpuImageDecodeCache::DeleteImage(ImageData* image_data) {
if (image_data->HasUploadedData()) {
DCHECK(!image_data->upload.is_locked());
@@ -1737,6 +1782,12 @@ bool GpuImageDecodeCache::IsInInUseCacheForTesting(
return found != in_use_cache_.end();
}
+bool GpuImageDecodeCache::IsInPersistentCacheForTesting(
+ const DrawImage& image) const {
+ auto found = persistent_cache_.Peek(image.frame_key());
+ return found != persistent_cache_.end();
+}
+
sk_sp<SkImage> GpuImageDecodeCache::GetSWImageDecodeForTesting(
const DrawImage& image) {
base::AutoLock lock(lock_);
@@ -1769,6 +1820,20 @@ bool GpuImageDecodeCache::SupportsColorSpaceConversion() const {
}
}
+sk_sp<SkColorSpace> GpuImageDecodeCache::ColorSpaceForImageDecode(
+ const DrawImage& image,
+ DecodedDataMode mode) const {
+ if (!SupportsColorSpaceConversion())
+ return nullptr;
+
+ if (mode == DecodedDataMode::kCpu)
+ return image.target_color_space().ToSkColorSpace();
+
+ // For kGpu or kTransferCache images color conversion is handled during
+ // upload, so keep the original colorspace here.
+ return sk_ref_sp(image.paint_image().color_space());
+}
+
void GpuImageDecodeCache::CheckContextLockAcquiredIfNecessary() {
if (!context_->GetLock())
return;
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h
index ea4fe73dce9..90374d7ab72 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.h
+++ b/chromium/cc/tiles/gpu_image_decode_cache.h
@@ -126,7 +126,6 @@ class CC_EXPORT GpuImageDecodeCache
bool aggressively_free_resources) override;
void ClearCache() override;
size_t GetMaximumMemoryLimitBytes() const override;
- void NotifyImageUnused(const PaintImage::FrameKey& frame_key) override;
// MemoryDumpProvider overrides.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
@@ -160,6 +159,7 @@ class CC_EXPORT GpuImageDecodeCache
void SetImageDecodingFailedForTesting(const DrawImage& image);
bool DiscardableIsLockedForTesting(const DrawImage& image);
bool IsInInUseCacheForTesting(const DrawImage& image) const;
+ bool IsInPersistentCacheForTesting(const DrawImage& image) const;
sk_sp<SkImage> GetSWImageDecodeForTesting(const DrawImage& image);
private:
@@ -385,6 +385,7 @@ class CC_EXPORT GpuImageDecodeCache
scoped_refptr<GpuImageDecodeCache::ImageData> CreateImageData(
const DrawImage& image);
+ void WillAddCacheEntry(const DrawImage& draw_image);
SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image,
int upload_scale_mip_level) const;
@@ -425,6 +426,17 @@ class CC_EXPORT GpuImageDecodeCache
void CheckContextLockAcquiredIfNecessary();
+ sk_sp<SkColorSpace> ColorSpaceForImageDecode(const DrawImage& image,
+ DecodedDataMode mode) const;
+
+ // |persistent_cache_| represents the long-lived cache, keeping a certain
+ // budget of ImageDatas alive even when their ref count reaches zero.
+ using PersistentCache = base::HashingMRUCache<PaintImage::FrameKey,
+ scoped_refptr<ImageData>,
+ PaintImage::FrameKeyHash>;
+ PersistentCache::iterator RemoveFromPersistentCache(
+ PersistentCache::iterator it);
+
const SkColorType color_type_;
const bool use_transfer_cache_ = false;
viz::RasterContextProvider* context_;
@@ -435,13 +447,16 @@ class CC_EXPORT GpuImageDecodeCache
// be accessed without a lock since they are thread safe.
base::Lock lock_;
- // |persistent_cache_| represents the long-lived cache, keeping a certain
- // budget of ImageDatas alive even when their ref count reaches zero.
- using PersistentCache = base::HashingMRUCache<PaintImage::FrameKey,
- scoped_refptr<ImageData>,
- PaintImage::FrameKeyHash>;
PersistentCache persistent_cache_;
+ struct CacheEntries {
+ PaintImage::ContentId content_ids[2] = {PaintImage::kInvalidContentId,
+ PaintImage::kInvalidContentId};
+ };
+ // A map of PaintImage::Id to entries for this image in the
+ // |persistent_cache_|.
+ base::flat_map<PaintImage::Id, CacheEntries> paint_image_entries_;
+
// |in_use_cache_| represents the in-use (short-lived) cache. Entries are
// cleaned up as soon as their ref count reaches zero.
using InUseCache =
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index 2c272ededad..91fc94f17e2 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -1926,38 +1926,6 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {
cache->UnrefImage(draw_image);
}
-TEST_P(GpuImageDecodeCacheTest, RemoveUnusedImage) {
- auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
- std::vector<PaintImage::FrameKey> frame_keys;
-
- for (int i = 0; i < 10; ++i) {
- PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100));
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
- frame_keys.push_back(draw_image.frame_key());
- ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
- draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(result.need_unref);
- EXPECT_TRUE(result.task);
- TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
- TestTileTaskRunner::ProcessTask(result.task.get());
- cache->UnrefImage(draw_image);
- }
-
- // We should now have images in our cache.
- EXPECT_EQ(cache->GetNumCacheEntriesForTesting(), 10u);
-
- // Remove unused ids.
- for (uint32_t i = 0; i < 10; ++i) {
- cache->NotifyImageUnused(frame_keys[i]);
- EXPECT_EQ(cache->GetNumCacheEntriesForTesting(), (10 - i - 1));
- }
-}
-
TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
auto cache = CreateCache();
@@ -2313,6 +2281,56 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
EXPECT_FALSE(cache->GetSWImageDecodeForTesting(draw_image));
}
+TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScaleTask) {
+ auto cache = CreateCache();
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ PaintImage image = CreateBitmapImage(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, DefaultColorSpace());
+ auto result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ EXPECT_TRUE(result.task);
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
+ auto cache = CreateCache();
+ const bool should_cache_sw_image =
+ cache->SupportsColorSpaceConversion() && !use_transfer_cache_;
+
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ PaintImage image = CreateBitmapImage(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());
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ DecodedDrawImage decoded_draw_image =
+ EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EXPECT_TRUE(decoded_draw_image.image());
+ EXPECT_TRUE(decoded_draw_image.is_budgeted());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ // For non-lazy images color converted during scaling, cpu component should be
+ // cached.
+ 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()));
+ }
+}
+
TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
auto cache = CreateCache();
bool is_decomposable = true;
@@ -2337,6 +2355,45 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
EXPECT_EQ(sw_image->height(), 5);
}
+TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
+ auto cache = CreateCache();
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const PaintImage::Id paint_image_id = PaintImage::GetNextId();
+ std::vector<DrawImage> draw_images;
+ std::vector<DecodedDrawImage> decoded_draw_images;
+
+ for (int i = 0; i < 10; ++i) {
+ PaintImage image = CreateDiscardablePaintImage(
+ gfx::Size(10, 10), SkColorSpace::MakeSRGB(), true, paint_image_id);
+ DrawImage draw_image(
+ image, SkIRect::MakeWH(image.width(), image.height()), quality,
+ CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DecodedDrawImage decoded_draw_image =
+ EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+
+ draw_images.push_back(draw_image);
+ decoded_draw_images.push_back(decoded_draw_image);
+
+ if (i == 0)
+ continue;
+
+ // We should only have the last 2 entries in the persistent cache, even
+ // though everything is in the in use cache.
+ EXPECT_EQ(cache->GetNumCacheEntriesForTesting(), 2u);
+ EXPECT_EQ(cache->GetInUseCacheEntriesForTesting(), i + 1u);
+ EXPECT_TRUE(cache->IsInPersistentCacheForTesting(draw_images[i]));
+ EXPECT_TRUE(cache->IsInPersistentCacheForTesting(draw_images[i - 1]));
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ cache->DrawWithImageFinished(draw_images[i], decoded_draw_images[i]);
+ }
+}
+
INSTANTIATE_TEST_CASE_P(
GpuImageDecodeCacheTests,
GpuImageDecodeCacheTest,
diff --git a/chromium/cc/tiles/image_decode_cache.h b/chromium/cc/tiles/image_decode_cache.h
index 557059ca463..a1653f4708d 100644
--- a/chromium/cc/tiles/image_decode_cache.h
+++ b/chromium/cc/tiles/image_decode_cache.h
@@ -138,12 +138,6 @@ class CC_EXPORT ImageDecodeCache {
// locked budget before creating a task.
virtual size_t GetMaximumMemoryLimitBytes() const = 0;
- // Indicate to the cache that the image is no longer going
- // to be used. This means it can be deleted altogether. If the
- // image is locked, then the cache can do its best to clean it
- // up later.
- virtual void NotifyImageUnused(const PaintImage::FrameKey& frame_key) = 0;
-
protected:
void RecordImageMipLevelUMA(int mip_level);
};
diff --git a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
index 278f97b6f4b..c1f7703c5f3 100644
--- a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
@@ -8,14 +8,12 @@
#include <vector>
#include "cc/resources/layer_tree_resource_provider.h"
-#include "cc/resources/resource_provider.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_raster_source.h"
#include "cc/test/fake_resource_provider.h"
#include "cc/trees/layer_tree_settings.h"
#include "components/viz/test/fake_output_surface.h"
-#include "components/viz/test/test_shared_bitmap_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -248,13 +246,12 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
viz::TestContextProvider::Create();
ASSERT_EQ(context_provider->BindToCurrentThread(),
gpu::ContextResult::kSuccess);
- auto shared_bitmap_manager =
- std::make_unique<viz::TestSharedBitmapManager>();
std::unique_ptr<LayerTreeResourceProvider> resource_provider =
FakeResourceProvider::CreateLayerTreeResourceProvider(
- context_provider.get(), shared_bitmap_manager.get());
+ context_provider.get());
- FakePictureLayerTilingClient client(resource_provider.get());
+ FakePictureLayerTilingClient client(resource_provider.get(),
+ context_provider.get());
client.SetTileSize(gfx::Size(256, 256));
gfx::Size layer_bounds(1000, 800);
std::unique_ptr<TestablePictureLayerTilingSet> set =
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index e566d3a1e1b..6a52e91c066 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -586,31 +586,6 @@ size_t SoftwareImageDecodeCache::GetMaximumMemoryLimitBytes() const {
return locked_images_budget_.total_limit_bytes();
}
-void SoftwareImageDecodeCache::NotifyImageUnused(
- const PaintImage::FrameKey& frame_key) {
- base::AutoLock lock(lock_);
-
- auto it = frame_key_to_image_keys_.find(frame_key);
- if (it == frame_key_to_image_keys_.end())
- return;
-
- for (auto key_it = it->second.begin(); key_it != it->second.end();) {
- // This iterates over the CacheKey vector for the given skimage_id,
- // and deletes all entries from decoded_images_ corresponding to the
- // skimage_id.
- auto image_it = decoded_images_.Peek(*key_it);
- // TODO(sohanjg): Find an optimized way to cleanup locked images.
- if (image_it != decoded_images_.end() && image_it->second->ref_count == 0) {
- decoded_images_.Erase(image_it);
- key_it = it->second.erase(key_it);
- } else {
- ++key_it;
- }
- }
- if (it->second.empty())
- frame_key_to_image_keys_.erase(it);
-}
-
void SoftwareImageDecodeCache::OnImageDecodeTaskCompleted(
const CacheKey& key,
DecodeTaskType task_type) {
diff --git a/chromium/cc/tiles/software_image_decode_cache.h b/chromium/cc/tiles/software_image_decode_cache.h
index 47d2287f956..0fa379c2b2f 100644
--- a/chromium/cc/tiles/software_image_decode_cache.h
+++ b/chromium/cc/tiles/software_image_decode_cache.h
@@ -52,7 +52,6 @@ class CC_EXPORT SoftwareImageDecodeCache
bool aggressively_free_resources) override {}
void ClearCache() override;
size_t GetMaximumMemoryLimitBytes() const override;
- void NotifyImageUnused(const PaintImage::FrameKey& frame_key) override;
// Decode the given image and store it in the cache. This is only called by an
// image decode task from a worker thread.
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest.cc b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
index 35ba9ae94c1..c9f8c5a55e0 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
@@ -1584,39 +1584,6 @@ TEST(SoftwareImageDecodeCacheTest, ClearCache) {
EXPECT_EQ(0u, cache.GetNumCacheEntriesForTesting());
}
-TEST(SoftwareImageDecodeCacheTest, RemoveUnusedImage) {
- TestSoftwareImageDecodeCache cache;
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
- std::vector<PaintImage::FrameKey> frame_keys;
-
- for (int i = 0; i < 10; ++i) {
- SCOPED_TRACE(i);
- PaintImage paint_image = CreatePaintImage(100, 100);
- 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());
- frame_keys.push_back(draw_image.frame_key());
- ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
- draw_image, ImageDecodeCache::TracingInfo());
- EXPECT_TRUE(result.need_unref);
- EXPECT_TRUE(result.task);
- TestTileTaskRunner::ProcessTask(result.task.get());
- cache.UnrefImage(draw_image);
- }
-
- // We should now have data image in our cache.
- EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 10u);
-
- // Remove unused ids.
- for (uint32_t i = 0; i < 10; ++i) {
- cache.NotifyImageUnused(frame_keys[i]);
- EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), (10 - i - 1));
- }
-}
-
TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
TestSoftwareImageDecodeCache cache;
std::vector<FrameMetadata> frames = {
@@ -1731,5 +1698,84 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
cache.DrawWithImageFinished(empty_draw_image, empty_decoded_draw_image);
}
+TEST(SoftwareImageDecodeCacheTest, BitmapImageColorConverted) {
+ TestSoftwareImageDecodeCache cache;
+ 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);
+
+ DecodedDrawImage decoded_draw_image =
+ cache.GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.image());
+ // Expect that we allocated a new image.
+ EXPECT_NE(decoded_draw_image.image().get(), paint_image.GetSkImage().get());
+ // Expect that the image color space match the target color space.
+ EXPECT_TRUE(decoded_draw_image.image()->colorSpace());
+ EXPECT_TRUE(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
+ target_color_space.ToSkColorSpace().get()));
+
+ cache.DrawWithImageFinished(draw_image, decoded_draw_image);
+}
+
+TEST(SoftwareImageDecodeCacheTest, BitmapImageNotColorConverted) {
+ TestSoftwareImageDecodeCache cache;
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ 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, DefaultColorSpace());
+
+ DecodedDrawImage decoded_draw_image =
+ cache.GetDecodedImageForDraw(draw_image);
+ // Expect that we did not allocate a new image.
+ EXPECT_EQ(decoded_draw_image.image().get(), paint_image.GetSkImage().get());
+
+ cache.DrawWithImageFinished(draw_image, decoded_draw_image);
+}
+
+// TODO(ccameron): Re-enable this when the root cause of crashes is discovered.
+// https://crbug.com/791828
+TEST(SoftwareImageDecodeCacheTest, DISABLED_ContentIdCaching) {
+ TestSoftwareImageDecodeCache cache;
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+ PaintImage::Id stable_id = 1001;
+
+ for (int i = 0; i < 10; ++i) {
+ // Create several images with the same stable id, but new content ids.
+ PaintImage paint_image = CreateDiscardablePaintImage(
+ gfx::Size(100, 100), nullptr, true, stable_id);
+
+ // Cache two entries of different scales.
+ for (int j = 0; j < 2; ++j) {
+ float scale = j == 0 ? 1.f : 0.5f;
+ DrawImage draw_image(
+ paint_image,
+ SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
+ CreateMatrix(SkSize::Make(scale, scale), is_decomposable),
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DecodedDrawImage decoded_draw_image =
+ cache.GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.image());
+ cache.DrawWithImageFinished(draw_image, decoded_draw_image);
+ }
+
+ // After the first two entries come in, we start evicting old content ids.
+ if (i == 0)
+ EXPECT_LE(cache.GetNumCacheEntriesForTesting(), 2u);
+ else
+ EXPECT_LE(cache.GetNumCacheEntriesForTesting(), 4u);
+ }
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.cc b/chromium/cc/tiles/software_image_decode_cache_utils.cc
index 0a051dbe793..4b6016b4126 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.cc
@@ -152,6 +152,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
DCHECK(!image.paint_image().GetSkImage()->isTextureBacked());
const PaintImage::FrameKey frame_key = image.frame_key();
+ const PaintImage::Id stable_id = image.paint_image().stable_id();
const SkSize& scale = image.scale();
// If the src_rect falls outside of the image, we need to clip it since
@@ -170,8 +171,8 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
// If the target size is empty, then we'll be skipping the decode anyway, so
// the filter quality doesn't matter. Early out instead.
if (target_size.IsEmpty()) {
- return CacheKey(frame_key, kSubrectAndScale, false, src_rect, target_size,
- image.target_color_space());
+ return CacheKey(frame_key, stable_id, kSubrectAndScale, false, src_rect,
+ target_size, image.target_color_space());
}
ProcessingType type = kOriginal;
@@ -232,18 +233,20 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
}
}
- return CacheKey(frame_key, type, is_nearest_neighbor, src_rect, target_size,
- image.target_color_space());
+ return CacheKey(frame_key, stable_id, type, is_nearest_neighbor, src_rect,
+ target_size, image.target_color_space());
}
SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
PaintImage::FrameKey frame_key,
+ PaintImage::Id stable_id,
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
const gfx::Size& target_size,
const gfx::ColorSpace& target_color_space)
: frame_key_(frame_key),
+ stable_id_(stable_id),
type_(type),
is_nearest_neighbor_(is_nearest_neighbor),
src_rect_(src_rect),
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.h b/chromium/cc/tiles/software_image_decode_cache_utils.h
index 875a8896f3e..7be7315d02d 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.h
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.h
@@ -64,6 +64,7 @@ class SoftwareImageDecodeCacheUtils {
bool operator!=(const CacheKey& other) const { return !(*this == other); }
const PaintImage::FrameKey& frame_key() const { return frame_key_; }
+ PaintImage::Id stable_id() const { return stable_id_; }
ProcessingType type() const { return type_; }
bool is_nearest_neighbor() const { return is_nearest_neighbor_; }
gfx::Rect src_rect() const { return src_rect_; }
@@ -88,6 +89,7 @@ class SoftwareImageDecodeCacheUtils {
private:
CacheKey(PaintImage::FrameKey frame_key,
+ PaintImage::Id stable_id,
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
@@ -95,6 +97,10 @@ class SoftwareImageDecodeCacheUtils {
const gfx::ColorSpace& target_color_space);
PaintImage::FrameKey frame_key_;
+ // The stable id is does not factor into the cache key's value for hashing
+ // and comparison (as it is redundant). It is only used to look up other
+ // cache entries of the same stable id.
+ PaintImage::Id stable_id_;
ProcessingType type_;
bool is_nearest_neighbor_;
gfx::Rect src_rect_;
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index 33324a69a7f..dfebdf4cab6 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -359,6 +359,7 @@ TileManager::TileManager(
did_oom_on_last_assign_(false),
image_controller_(origin_task_runner,
std::move(image_worker_task_runner)),
+ decoded_image_tracker_(&image_controller_),
checker_image_tracker_(&image_controller_,
this,
tile_manager_settings_.enable_checker_imaging,
@@ -1267,10 +1268,8 @@ void TileManager::OnRasterTaskCompleted(
}
TileDrawInfo& draw_info = tile->draw_info();
- bool needs_swizzle =
- raster_buffer_provider_->IsResourceSwizzleRequired(!tile->is_opaque());
- bool is_premultiplied =
- raster_buffer_provider_->IsResourcePremultiplied(!tile->is_opaque());
+ 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);
@@ -1285,13 +1284,6 @@ void TileManager::OnRasterTaskCompleted(
}
}
-void TileManager::SetDecodedImageTracker(
- DecodedImageTracker* decoded_image_tracker) {
- // TODO(vmpstr): If the tile manager needs to request out-of-raster decodes,
- // it should retain and use |decoded_image_tracker| here.
- decoded_image_tracker->set_image_controller(&image_controller_);
-}
-
std::unique_ptr<Tile> TileManager::CreateTile(const Tile::CreateInfo& info,
int layer_id,
int source_frame_number,
@@ -1519,7 +1511,7 @@ void TileManager::NeedsInvalidationForCheckerImagedTiles() {
viz::ResourceFormat TileManager::DetermineResourceFormat(
const Tile* tile) const {
- return raster_buffer_provider_->GetResourceFormat(!tile->is_opaque());
+ return raster_buffer_provider_->GetResourceFormat();
}
std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
@@ -1558,6 +1550,11 @@ void TileManager::CheckPendingGpuWorkAndIssueSignals() {
const ResourcePool::InUsePoolResource& resource =
tile->draw_info().GetResource();
+ // Update requirements first so that if the tile has become required
+ // it will force a redraw.
+ if (pending_tile_requirements_dirty_)
+ tile->tiling()->UpdateRequiredStatesOnTile(tile);
+
if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY ||
raster_buffer_provider_->IsResourceReadyToDraw(resource)) {
tile->draw_info().set_resource_ready_for_draw();
@@ -1569,8 +1566,6 @@ void TileManager::CheckPendingGpuWorkAndIssueSignals() {
// TODO(ericrk): If a tile in our list no longer has valid tile priorities,
// it may still report that it is required, and unnecessarily delay
// activation. crbug.com/687265
- if (pending_tile_requirements_dirty_)
- tile->tiling()->UpdateRequiredStatesOnTile(tile);
if (tile->required_for_activation())
required_for_activation.push_back(&resource);
if (tile->required_for_draw())
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index 32e9a1ea563..2b79c939ada 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -194,7 +194,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
ResourcePool::InUsePoolResource resource =
resource_pool_->AcquireResource(
tiles[i]->desired_texture_size(),
- raster_buffer_provider_->GetResourceFormat(false),
+ raster_buffer_provider_->GetResourceFormat(),
client_->GetRasterColorSpace().color_space);
raster_buffer_provider_->AcquireBufferForRaster(resource, 0, 0);
// The raster here never really happened, cuz tests. So just add an
@@ -260,8 +260,6 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
ResourcePool::InUsePoolResource resource,
bool was_canceled);
- void SetDecodedImageTracker(DecodedImageTracker* decoded_image_tracker);
-
// CheckerImageTrackerClient implementation.
void NeedsInvalidationForCheckerImagedTiles() override;
@@ -278,6 +276,9 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
CheckerImageTracker& checker_image_tracker() {
return checker_image_tracker_;
}
+ DecodedImageTracker& decoded_image_tracker() {
+ return decoded_image_tracker_;
+ }
const std::vector<DrawImage>& decode_tasks_for_testing(Tile::Id id) {
return scheduled_draw_images_[id];
@@ -414,6 +415,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
bool did_oom_on_last_assign_;
ImageController image_controller_;
+ DecodedImageTracker decoded_image_tracker_;
CheckerImageTracker checker_image_tracker_;
RasterTaskCompletionStats raster_task_completion_stats_;
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 8c9a5f4f19a..9c437b15b86 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -1365,8 +1365,6 @@ TEST_F(TileManagerTilePriorityQueueTest,
EXPECT_FALSE(queue->IsEmpty());
EXPECT_TRUE(queue->Top().tile()->required_for_draw());
EXPECT_EQ(gfx::Size(256, 256), queue->Top().tile()->desired_texture_size());
- EXPECT_EQ(viz::RGBA_8888,
- host_impl()->resource_provider()->best_texture_format());
ManagedMemoryPolicy policy = host_impl()->ActualManagedMemoryPolicy();
policy.bytes_limit_when_visible =
@@ -1570,7 +1568,7 @@ class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
RasterBufferProvider::PlaybackToMemory(
pixels_, viz::RGBA_8888, size_, /*stride=*/0, raster_source,
raster_full_rect, /*playback_rect=*/raster_full_rect, transform,
- gfx::ColorSpace(), playback_settings);
+ gfx::ColorSpace(), /*gpu_compositing=*/true, playback_settings);
}
private:
@@ -1723,6 +1721,11 @@ TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) {
class PixelInspectTileManagerTest : public TileManagerTest {
public:
+ ~PixelInspectTileManagerTest() override {
+ // Ensure that the host impl doesn't outlive |raster_buffer_provider_|.
+ TakeHostImpl();
+ }
+
void SetUp() override {
TileManagerTest::SetUp();
// Use a RasterBufferProvider that will let us inspect pixels.
@@ -2291,7 +2294,6 @@ TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
run_loop.Quit();
return 1;
}));
- host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
run_loop.Run();
}
@@ -2321,7 +2323,6 @@ TEST_F(TileManagerReadyToDrawTest, NonSmoothActivationDoesNotWaitOnCallback) {
// will cause a test failure.
base::RunLoop run_loop;
- host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
.WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
@@ -2356,7 +2357,6 @@ TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
run_loop.Quit();
return 1;
}));
- host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
run_loop.Run();
}
@@ -2386,7 +2386,6 @@ TEST_F(TileManagerReadyToDrawTest, NonSmoothDrawDoesNotWaitOnCallback) {
// will cause a test failure.
base::RunLoop run_loop;
- host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
.WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
@@ -2401,7 +2400,6 @@ TEST_F(TileManagerReadyToDrawTest, NoCallbackWhenAlreadyReadyToDraw) {
SetupTreesWithPendingTreeTiles();
base::RunLoop run_loop;
- host_impl()->tile_manager()->DidModifyTilePriorities();
host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
.WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
@@ -2413,6 +2411,92 @@ TEST_F(TileManagerReadyToDrawTest, NoCallbackWhenAlreadyReadyToDraw) {
EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}
+TEST_F(TileManagerReadyToDrawTest, TilePrioritiesUpdated) {
+ // Use smoothness as that's a mode in which we wait on resources to be
+ // ready instead of marking them ready immediately.
+ host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
+ gfx::Size very_small(1, 1);
+ host_impl()->SetViewportSize(very_small);
+
+ gfx::Size layer_bounds(1000, 1000);
+ SetupDefaultTrees(layer_bounds);
+
+ // Run until all tile tasks are complete, but don't let any draw callbacks
+ // finish.
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+
+ // Until we activate our ready to draw callback, treat all resources as not
+ // ready to draw.
+ EXPECT_CALL(*mock_raster_buffer_provider(),
+ IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, _))
+ .WillRepeatedly(Return(1));
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ }
+
+ // Inspect the current state of tiles in this world of cpu done but gpu
+ // not ready yet.
+ size_t orig_num_required = 0;
+ size_t orig_num_prepaint = 0;
+ std::vector<Tile*> prepaint_tiles;
+ for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) {
+ if (tile->draw_info().has_resource()) {
+ if (tile->is_prepaint()) {
+ orig_num_prepaint++;
+ prepaint_tiles.push_back(tile);
+ } else {
+ orig_num_required++;
+ }
+ }
+ }
+
+ // Verify that there exist some prepaint tiles here.
+ EXPECT_GT(orig_num_prepaint, 0u);
+ EXPECT_GT(orig_num_required, 0u);
+
+ host_impl()->SetViewportSize(layer_bounds);
+ host_impl()->active_tree()->UpdateDrawProperties();
+ host_impl()->pending_tree()->UpdateDrawProperties();
+
+ // Rerun prepare tiles.
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ }
+
+ // Make sure tiles priorities are updated.
+ size_t final_num_required = 0;
+ size_t final_num_prepaint = 0;
+ bool found_one_prepaint_to_required_transition = false;
+ for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) {
+ if (tile->draw_info().has_resource()) {
+ if (tile->is_prepaint()) {
+ final_num_prepaint++;
+ } else {
+ final_num_required++;
+ if (std::find(prepaint_tiles.begin(), prepaint_tiles.end(), tile) !=
+ prepaint_tiles.end()) {
+ found_one_prepaint_to_required_transition = true;
+ }
+ }
+ }
+ }
+
+ // Tile priorities should be updated and we should have more required
+ // and fewer prepaint now that the viewport has changed.
+ EXPECT_GT(final_num_required, orig_num_required);
+ EXPECT_LT(final_num_prepaint, orig_num_prepaint);
+ EXPECT_TRUE(found_one_prepaint_to_required_transition);
+}
+
void UpdateVisibleRect(FakePictureLayerImpl* layer,
const gfx::Rect visible_rect) {
PictureLayerTilingSet* tiling_set = layer->tilings();
@@ -2495,6 +2579,13 @@ TEST_F(TileManagerReadyToDrawTest, ReadyToDrawRespectsRequirementChange) {
EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}
+PaintImage MakeCheckerablePaintImage(const gfx::Size& size) {
+ auto image = CreateDiscardablePaintImage(size);
+ return PaintImageBuilder::WithCopy(image)
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
+ .TakePaintImage();
+}
+
class CheckerImagingTileManagerTest : public TestLayerTreeHostBase {
public:
class MockImageGenerator : public FakePaintImageGenerator {
@@ -2554,7 +2645,6 @@ class CheckerImagingTileManagerTest : public TestLayerTreeHostBase {
TEST_F(CheckerImagingTileManagerTest,
NoImageDecodeDependencyForCheckeredTiles) {
const gfx::Size layer_bounds(512, 512);
- SetupDefaultTrees(layer_bounds);
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
@@ -2565,6 +2655,7 @@ TEST_F(CheckerImagingTileManagerTest,
PaintImage image = PaintImageBuilder::WithDefault()
.set_id(PaintImage::GetNextId())
.set_paint_image_generator(generator)
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
.TakePaintImage();
recording_source->add_draw_image(image, gfx::Point(0, 0));
@@ -2572,13 +2663,12 @@ TEST_F(CheckerImagingTileManagerTest,
scoped_refptr<RasterSource> raster_source =
recording_source->CreateRasterSource();
- std::unique_ptr<PictureLayerImpl> layer_impl = PictureLayerImpl::Create(
- host_impl()->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK);
- layer_impl->set_contributes_to_drawn_render_surface(true);
- PictureLayerTilingSet* tiling_set = layer_impl->picture_layer_tiling_set();
+ Region invalidation((gfx::Rect(layer_bounds)));
+ SetupPendingTree(raster_source, layer_bounds, invalidation);
- PictureLayerTiling* tiling =
- tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
+ PictureLayerTilingSet* tiling_set =
+ pending_layer()->picture_layer_tiling_set();
+ PictureLayerTiling* tiling = tiling_set->tiling_at(0);
tiling->set_resolution(HIGH_RESOLUTION);
tiling->CreateAllTilesForTesting();
tiling->SetTilePriorityRectsForTesting(
@@ -2615,8 +2705,7 @@ TEST_F(EmptyCacheTileManagerTest, AtRasterOnScreenTileRasterTasks) {
recording_source->set_fill_with_nonsolid_color(true);
int dimension = 500;
- PaintImage image =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ PaintImage image = MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
recording_source->add_draw_image(image, gfx::Point(0, 0));
recording_source->Rerecord();
@@ -2652,8 +2741,7 @@ TEST_F(EmptyCacheTileManagerTest, AtRasterPrepaintTileRasterTasksSkipped) {
recording_source->set_fill_with_nonsolid_color(true);
int dimension = 500;
- PaintImage image =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ PaintImage image = MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
recording_source->add_draw_image(image, gfx::Point(0, 0));
recording_source->Rerecord();
@@ -2690,11 +2778,11 @@ TEST_F(CheckerImagingTileManagerTest, BuildsImageDecodeQueueAsExpected) {
int dimension = 450;
PaintImage image1 =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
PaintImage image2 =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
PaintImage image3 =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
recording_source->add_draw_image(image1, gfx::Point(0, 0));
recording_source->add_draw_image(image2, gfx::Point(600, 0));
recording_source->add_draw_image(image3, gfx::Point(0, 600));
@@ -2851,7 +2939,7 @@ TEST_F(CheckerImagingTileManagerTest,
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
recording_source->set_fill_with_nonsolid_color(true);
- PaintImage image = CreateDiscardablePaintImage(gfx::Size(512, 512));
+ PaintImage image = MakeCheckerablePaintImage(gfx::Size(512, 512));
recording_source->add_draw_image(image, gfx::Point(0, 0));
recording_source->Rerecord();
scoped_refptr<RasterSource> raster_source =
@@ -2890,7 +2978,7 @@ TEST_F(CheckerImagingTileManagerTest,
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
recording_source->set_fill_with_nonsolid_color(true);
- PaintImage image = CreateDiscardablePaintImage(gfx::Size(512, 512));
+ PaintImage image = MakeCheckerablePaintImage(gfx::Size(512, 512));
recording_source->add_draw_image(image, gfx::Point(0, 0));
recording_source->Rerecord();
scoped_refptr<RasterSource> raster_source =
@@ -2975,9 +3063,9 @@ TEST_F(CheckerImagingTileManagerMemoryTest, AddsAllNowTilesToImageDecodeQueue) {
int dimension = 450;
PaintImage image1 =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
PaintImage image2 =
- CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
+ MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
recording_source->add_draw_image(image1, gfx::Point(0, 515));
recording_source->add_draw_image(image2, gfx::Point(515, 515));
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index d3c1958a13c..b888d085203 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -506,11 +506,12 @@ static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees,
float page_scale_factor,
float device_scale_factor,
gfx::Transform device_transform) {
- if (property_trees->transform_tree.page_scale_factor() == page_scale_factor)
+ if (property_trees->transform_tree.page_scale_factor() == page_scale_factor ||
+ !page_scale_layer) {
return;
+ }
property_trees->transform_tree.set_page_scale_factor(page_scale_factor);
- DCHECK(page_scale_layer);
DCHECK_GE(page_scale_layer->transform_tree_index(),
TransformTree::kRootNodeId);
TransformNode* node = property_trees->transform_tree.Node(
@@ -648,7 +649,7 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees,
const EffectNode* effect_node =
effect_tree.Node(render_surface->EffectTreeIndex());
// The draw transform of root render surface is identity tranform.
- if (transform_node->id == TransformTree::kRootNodeId) {
+ if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) {
render_surface->SetDrawTransform(gfx::Transform());
return;
}
@@ -1004,7 +1005,7 @@ void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
}
void ComputeMaskDrawProperties(LayerImpl* mask_layer,
- const PropertyTrees* property_trees) {
+ PropertyTrees* property_trees) {
// Mask draw properties are used only for rastering, so most of the draw
// properties computed for other layers are not needed.
// Draw transform of a mask layer has to be a 2d scale.
@@ -1016,8 +1017,17 @@ void ComputeMaskDrawProperties(LayerImpl* mask_layer,
mask_layer->draw_properties().screen_space_transform =
ScreenSpaceTransformInternal(mask_layer,
property_trees->transform_tree);
+
+ ConditionalClip clip = LayerClipRect(property_trees, mask_layer);
+ // is_clipped should be set before visible rect computation as it is used
+ // there.
+ mask_layer->draw_properties().is_clipped = clip.is_clipped;
+ mask_layer->draw_properties().clip_rect =
+ gfx::ToEnclosingRect(clip.clip_rect);
+ // Calculate actual visible layer rect for mask layers, since we could have
+ // tiled mask layers and the tile manager would need this info for rastering.
mask_layer->draw_properties().visible_layer_rect =
- gfx::Rect(mask_layer->bounds());
+ LayerVisibleRect(property_trees, mask_layer);
mask_layer->draw_properties().opacity = 1;
}
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index 45ed01f6e88..6c843521df6 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -59,7 +59,7 @@ ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
PropertyTrees* property_trees);
void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer,
- const PropertyTrees* property_trees);
+ PropertyTrees* property_trees);
void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
RenderSurfaceImpl* render_surface);
diff --git a/chromium/cc/trees/latency_info_swap_promise.cc b/chromium/cc/trees/latency_info_swap_promise.cc
index 6ebf5352014..9b376030ed5 100644
--- a/chromium/cc/trees/latency_info_swap_promise.cc
+++ b/chromium/cc/trees/latency_info_swap_promise.cc
@@ -44,8 +44,7 @@ void LatencyInfoSwapPromise::DidSwap() {}
SwapPromise::DidNotSwapAction LatencyInfoSwapPromise::DidNotSwap(
DidNotSwapReason reason) {
- latency_.AddLatencyNumber(DidNotSwapReasonToLatencyComponentType(reason), 0,
- 0);
+ latency_.AddLatencyNumber(DidNotSwapReasonToLatencyComponentType(reason), 0);
// TODO(miletus): Turn this back on once per-event LatencyInfo tracking
// is enabled in GPU side.
// DCHECK(latency_.terminated);
diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc
index 7bca0d6ebf0..99ec2c686a4 100644
--- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc
+++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc
@@ -21,7 +21,7 @@ bool AddRenderingScheduledComponent(ui::LatencyInfo* latency_info,
: ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT;
if (latency_info->FindLatency(type, 0, nullptr))
return false;
- latency_info->AddLatencyNumber(type, 0, 0);
+ latency_info->AddLatencyNumber(type, 0);
return true;
}
@@ -31,8 +31,7 @@ bool AddForwardingScrollUpdateToMainComponent(ui::LatencyInfo* latency_info) {
nullptr))
return false;
latency_info->AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, 0,
- latency_info->trace_id());
+ ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, 0);
return true;
}
@@ -70,29 +69,13 @@ void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() {
void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() {
if (AddForwardingScrollUpdateToMainComponent(latency_)) {
- int64_t new_sequence_number = 0;
- for (ui::LatencyInfo::LatencyMap::const_iterator it =
- latency_->latency_components().begin();
- it != latency_->latency_components().end(); ++it) {
- if (it->first.first == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT) {
- new_sequence_number =
- ((static_cast<int64_t>(base::PlatformThread::CurrentId()) << 32) ^
- (reinterpret_cast<uint64_t>(this) << 32)) |
- (it->second.sequence_number & 0xffffffff);
- if (new_sequence_number == it->second.sequence_number)
- return;
- break;
- }
- }
- if (!new_sequence_number)
- return;
ui::LatencyInfo new_latency;
new_latency.CopyLatencyFrom(
*latency_,
ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT);
new_latency.AddLatencyNumberWithTraceName(
ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, 0,
- new_sequence_number, "ScrollUpdate");
+ "ScrollUpdate");
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(new_latency));
host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(
diff --git a/chromium/cc/trees/layer_tree_frame_sink.cc b/chromium/cc/trees/layer_tree_frame_sink.cc
index 5a1fb748c7b..e1a1b803b72 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink.cc
@@ -43,13 +43,11 @@ LayerTreeFrameSink::LayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- viz::SharedBitmapManager* shared_bitmap_manager)
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager)
: context_provider_(std::move(context_provider)),
worker_context_provider_(std::move(worker_context_provider)),
compositor_task_runner_(std::move(compositor_task_runner)),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
- shared_bitmap_manager_(shared_bitmap_manager),
weak_ptr_factory_(this) {
DETACH_FROM_THREAD(thread_checker_);
}
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index f61c7a6c019..7f550dc9fe8 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -11,15 +11,15 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "cc/cc_export.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
-#include "components/viz/common/quads/shared_bitmap.h"
#include "components/viz/common/resources/returned_resource.h"
+#include "components/viz/common/resources/shared_bitmap_reporter.h"
#include "gpu/command_buffer/common/texture_in_use_response.h"
-#include "mojo/public/cpp/system/buffer.h"
#include "ui/gfx/color_space.h"
namespace gpu {
@@ -29,21 +29,20 @@ class GpuMemoryBufferManager;
namespace viz {
class CompositorFrame;
class LocalSurfaceId;
-class SharedBitmapManager;
struct BeginFrameAck;
} // namespace viz
namespace cc {
class LayerTreeFrameSinkClient;
-class LayerTreeHostImpl;
// An interface for submitting CompositorFrames to a display compositor
// which will compose frames from multiple clients to show on screen to the
// user.
// If a context_provider() is present, frames should be submitted with
// OpenGL resources (created with the context_provider()). If not, then
-// SharedBitmap resources should be used.
-class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
+// SharedMemory resources should be used.
+class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
+ public viz::ContextLostObserver {
public:
struct Capabilities {
Capabilities() = default;
@@ -74,8 +73,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
scoped_refptr<viz::ContextProvider> context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- viz::SharedBitmapManager* shared_bitmap_manager);
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
~LayerTreeFrameSink() override;
@@ -101,7 +99,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
const Capabilities& capabilities() const { return capabilities_; }
// The viz::ContextProviders may be null if frames should be submitted with
- // software SharedBitmap resources.
+ // software SharedMemory resources.
viz::ContextProvider* context_provider() const {
return context_provider_.get();
}
@@ -111,13 +109,6 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const {
return gpu_memory_buffer_manager_;
}
- viz::SharedBitmapManager* shared_bitmap_manager() const {
- return shared_bitmap_manager_;
- }
-
- // Generate hit test region list based on LayerTreeHostImpl, the data will be
- // submitted with compositor frame.
- virtual void UpdateHitTestData(const LayerTreeHostImpl* host_impl) {}
// If supported, this sets the viz::LocalSurfaceId the LayerTreeFrameSink will
// use to submit a CompositorFrame.
@@ -137,13 +128,10 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
// the client did not lead to a CompositorFrame submission.
virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack) = 0;
- // Associates a SharedBitmapId with a shared buffer handle.
- virtual void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
- const viz::SharedBitmapId& id) = 0;
-
- // Disassociates a SharedBitmapId previously passed to
- // DidAllocateSharedBitmap.
- virtual void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) = 0;
+ // viz::SharedBitmapReporter implementation.
+ void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
+ const viz::SharedBitmapId& id) override = 0;
+ void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0;
protected:
class ContextLostForwarder;
@@ -158,7 +146,6 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
scoped_refptr<viz::RasterContextProvider> worker_context_provider_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
- viz::SharedBitmapManager* shared_bitmap_manager_;
std::unique_ptr<ContextLostForwarder> worker_context_lost_forwarder_;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index a463b770007..d774db56e35 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "components/viz/common/resources/returned_resource.h"
@@ -19,6 +20,7 @@ class Transform;
namespace viz {
class BeginFrameSource;
+struct HitTestRegionList;
}
namespace cc {
@@ -32,6 +34,12 @@ class CC_EXPORT LayerTreeFrameSinkClient {
// binding to the client and then call again with a null while detaching.
virtual void SetBeginFrameSource(viz::BeginFrameSource* source) = 0;
+ // Builds and returns a HitTestRegionList from the active LayerTreeImpl. To be
+ // called during SubmitCompositorFrame().
+ // TODO(danakj): Just pass it into SubmitCompositorFrame(), with a
+ // LayerTreeSetting to enable it or not.
+ virtual base::Optional<viz::HitTestRegionList> BuildHitTestData() = 0;
+
// Returns resources sent to SubmitCompositorFrame to be reused or freed.
virtual void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) = 0;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
index 8ac72b45da5..781effb7740 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_frame_sink.h"
+#include "base/single_thread_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
#include "components/viz/common/quads/compositor_frame.h"
@@ -25,7 +26,6 @@ class StubLayerTreeFrameSink : public LayerTreeFrameSink {
: LayerTreeFrameSink(std::move(context_provider),
std::move(worker_context_provider),
std::move(compositor_task_runner),
- nullptr,
nullptr) {}
void SubmitCompositorFrame(viz::CompositorFrame frame) override {
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index d8bf091317a..b47182219c0 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -159,7 +159,7 @@ void LayerTreeHost::SetUIResourceManagerForTesting(
}
void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::InitializeForReal");
+ TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
DCHECK(task_runner_provider_);
proxy_ = std::move(proxy);
@@ -174,7 +174,7 @@ 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_);
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::~LayerTreeHostInProcess");
+ TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
// Clear any references into the LayerTreeHost.
mutator_host_->SetMutatorHostClient(nullptr);
@@ -280,25 +280,12 @@ void LayerTreeHost::RequestMainFrameUpdate(VisualStateUpdate requested_update) {
// This function commits the LayerTreeHost to an impl tree. When modifying
// this function, keep in mind that the function *runs* on the impl thread! Any
// code that is logically a main thread operation, e.g. deletion of a Layer,
-// should be delayed until the LayerTreeHostInProcess::CommitComplete, which
-// will run after the commit, but on the main thread.
+// should be delayed until the LayerTreeHost::CommitComplete, which will run
+// after the commit, but on the main thread.
void LayerTreeHost::FinishCommitOnImplThread(
LayerTreeHostImpl* host_impl) {
DCHECK(task_runner_provider_->IsImplThread());
- bool is_new_trace;
- TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
- if (is_new_trace &&
- frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
- root_layer()) {
- // We'll be dumping layer trees as part of trace, so make sure
- // PushPropertiesTo() propagates layer debug info to the impl side --
- // otherwise this won't happen for the layers that remain unchanged since
- // tracing started.
- LayerTreeHostCommon::CallFunctionForEveryLayer(
- this, [](Layer* layer) { layer->SetNeedsPushProperties(); });
- }
-
LayerTreeImpl* sync_tree = host_impl->sync_tree();
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync);
@@ -341,7 +328,7 @@ void LayerTreeHost::FinishCommitOnImplThread(
}
{
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::PushProperties");
+ TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
PushPropertyTreesTo(sync_tree);
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kSyncedPropertyTrees);
@@ -377,7 +364,7 @@ void LayerTreeHost::FinishCommitOnImplThread(
// TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state.
sync_tree->UpdatePropertyTreeAnimationFromMainThread();
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties");
+ TRACE_EVENT0("cc", "LayerTreeHost::AnimationHost::PushProperties");
DCHECK(host_impl->mutator_host());
mutator_host_->PushPropertiesTo(host_impl->mutator_host());
@@ -427,13 +414,29 @@ void LayerTreeHost::PushPropertyTreesTo(LayerTreeImpl* tree_impl) {
void LayerTreeHost::WillCommit() {
swap_promise_manager_.WillCommit();
client_->WillCommit();
+
+ if (frame_viewer_instrumentation::IsTracingLayerTreeSnapshots()) {
+ bool is_new_trace;
+ TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
+ if (is_new_trace) {
+ // We'll be dumping layer trees as part of trace, so make sure
+ // PushPropertiesTo() propagates layer debug info to the impl side --
+ // otherwise this won't happen for the layers that remain unchanged since
+ // tracing started.
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ this, [](Layer* layer) { layer->SetNeedsPushProperties(); });
+ }
+
+ for (Layer* layer : LayersThatShouldPushProperties())
+ layer->UpdateDebugInfo();
+ }
}
void LayerTreeHost::UpdateDeferCommitsInternal() {
proxy_->SetDeferCommits(defer_commits_ ||
(settings_.enable_surface_synchronization &&
- !local_surface_id_.is_valid()));
+ !local_surface_id_from_parent_.is_valid()));
}
bool LayerTreeHost::IsUsingLayerLists() const {
@@ -451,7 +454,7 @@ void LayerTreeHost::CommitComplete() {
void LayerTreeHost::SetLayerTreeFrameSink(
std::unique_ptr<LayerTreeFrameSink> surface) {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::SetLayerTreeFrameSink");
+ TRACE_EVENT0("cc", "LayerTreeHost::SetLayerTreeFrameSink");
DCHECK(surface);
DCHECK(!new_layer_tree_frame_sink_);
@@ -514,7 +517,7 @@ LayerTreeHost::CreateLayerTreeHostImpl(
}
void LayerTreeHost::DidLoseLayerTreeFrameSink() {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::DidLoseLayerTreeFrameSink");
+ TRACE_EVENT0("cc", "LayerTreeHost::DidLoseLayerTreeFrameSink");
DCHECK(task_runner_provider_->IsMainThread());
SetNeedsCommit();
}
@@ -598,9 +601,9 @@ void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
return;
has_gpu_rasterization_trigger_ = has_trigger;
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::SetHasGpuRasterizationTrigger",
- TRACE_EVENT_SCOPE_THREAD, "has_trigger", has_gpu_rasterization_trigger_);
+ TRACE_EVENT_INSTANT1("cc", "LayerTreeHost::SetHasGpuRasterizationTrigger",
+ TRACE_EVENT_SCOPE_THREAD, "has_trigger",
+ has_gpu_rasterization_trigger_);
}
void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(
@@ -745,8 +748,8 @@ void LayerTreeHost::RecordGpuRasterizationHistogram(
}
bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
- TRACE_EVENT1("cc", "LayerTreeHostInProcess::DoUpdateLayers",
- "source_frame_number", SourceFrameNumber());
+ TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number",
+ SourceFrameNumber());
UpdateHudLayer(debug_state_.ShowHudInfo());
@@ -777,11 +780,9 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
{
base::AutoReset<bool> update_property_trees(&in_update_property_trees_,
true);
- TRACE_EVENT0("cc",
- "LayerTreeHostInProcess::UpdateLayers::BuildPropertyTrees");
- TRACE_EVENT0(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees");
+ TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+ "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
PropertyTrees* property_trees = &property_trees_;
if (!IsUsingLayerLists()) {
// In SPv2 the property trees should have been built by the
@@ -791,15 +792,15 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
outer_viewport_scroll_layer(), overscroll_elasticity_layer(),
elastic_overscroll_, page_scale_factor_, device_scale_factor_,
gfx::Rect(device_viewport_size_), identity_transform, property_trees);
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::UpdateLayers_BuiltPropertyTrees",
- TRACE_EVENT_SCOPE_THREAD, "property_trees",
- property_trees->AsTracedValue());
+ TRACE_EVENT_INSTANT1("cc",
+ "LayerTreeHost::UpdateLayers_BuiltPropertyTrees",
+ TRACE_EVENT_SCOPE_THREAD, "property_trees",
+ property_trees->AsTracedValue());
} else {
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::UpdateLayers_ReceivedPropertyTrees",
- TRACE_EVENT_SCOPE_THREAD, "property_trees",
- property_trees->AsTracedValue());
+ TRACE_EVENT_INSTANT1("cc",
+ "LayerTreeHost::UpdateLayers_ReceivedPropertyTrees",
+ TRACE_EVENT_SCOPE_THREAD, "property_trees",
+ property_trees->AsTracedValue());
}
draw_property_utils::UpdatePropertyTrees(this, property_trees);
@@ -1054,9 +1055,8 @@ void LayerTreeHost::SetEventListenerProperties(
void LayerTreeHost::SetViewportSizeAndScale(
const gfx::Size& device_viewport_size,
float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id) {
- if (settings_.enable_surface_synchronization)
- SetLocalSurfaceId(local_surface_id);
+ const viz::LocalSurfaceId& local_surface_id_from_parent) {
+ SetLocalSurfaceIdFromParent(local_surface_id_from_parent);
bool changed = false;
if (device_viewport_size_ != device_viewport_size) {
@@ -1083,7 +1083,9 @@ void LayerTreeHost::SetViewportSizeAndScale(
#if defined(OS_MACOSX)
// TODO(ccameron): This check is not valid on Aura or Mus yet, but should
// be.
- CHECK(!has_pushed_local_surface_id_ || !local_surface_id_.is_valid());
+ CHECK(!has_pushed_local_surface_id_from_parent_ ||
+ new_local_surface_id_request_ ||
+ !local_surface_id_from_parent_.is_valid());
#endif
}
}
@@ -1180,16 +1182,34 @@ void LayerTreeHost::SetContentSourceId(uint32_t id) {
SetNeedsCommit();
}
-void LayerTreeHost::SetLocalSurfaceId(
- const viz::LocalSurfaceId& local_surface_id) {
- if (local_surface_id_ == local_surface_id)
+void LayerTreeHost::SetLocalSurfaceIdFromParent(
+ const viz::LocalSurfaceId& local_surface_id_from_parent) {
+ if (local_surface_id_from_parent_ == local_surface_id_from_parent)
return;
- local_surface_id_ = local_surface_id;
- has_pushed_local_surface_id_ = false;
+ local_surface_id_from_parent_ = local_surface_id_from_parent;
+ has_pushed_local_surface_id_from_parent_ = false;
UpdateDeferCommitsInternal();
SetNeedsCommit();
}
+void LayerTreeHost::RequestNewLocalSurfaceId() {
+ // If surface synchronization is enabled, then we can still request a new
+ // 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());
+ if (new_local_surface_id_request_)
+ return;
+ new_local_surface_id_request_ = true;
+ SetNeedsCommit();
+}
+
+bool LayerTreeHost::TakeNewLocalSurfaceIdRequest() {
+ bool new_local_surface_id_request = new_local_surface_id_request_;
+ new_local_surface_id_request_ = false;
+ return new_local_surface_id_request;
+}
+
void LayerTreeHost::RegisterLayer(Layer* layer) {
DCHECK(!LayerById(layer->id()));
DCHECK(!in_paint_layer_contents_);
@@ -1375,8 +1395,11 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->set_content_source_id(content_source_id_);
- tree_impl->set_local_surface_id(local_surface_id_);
- has_pushed_local_surface_id_ = true;
+ if (TakeNewLocalSurfaceIdRequest())
+ tree_impl->RequestNewLocalSurfaceId();
+
+ tree_impl->SetLocalSurfaceIdFromParent(local_surface_id_from_parent_);
+ has_pushed_local_surface_id_from_parent_ = true;
if (pending_page_scale_animation_) {
tree_impl->SetPendingPageScaleAnimation(
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index 9aecadafd1e..2fbf3e6c021 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -292,9 +292,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);
+ void SetViewportSizeAndScale(
+ const gfx::Size& device_viewport_size,
+ float device_scale_factor,
+ const viz::LocalSurfaceId& local_surface_id_from_parent);
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
@@ -337,9 +338,20 @@ 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 SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);
- const viz::LocalSurfaceId& local_surface_id() const {
- return local_surface_id_;
+ 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_;
+ }
+
+ // Requests the allocation of a new LocalSurfaceId on the compositor thread.
+ void RequestNewLocalSurfaceId();
+
+ // Returns the current state of the new LocalSurfaceId request and resets
+ // the state.
+ bool TakeNewLocalSurfaceIdRequest();
+ bool new_local_surface_id_request_for_testing() const {
+ return new_local_surface_id_request_;
}
void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space);
@@ -418,7 +430,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
LayerListReverseIterator<Layer> rbegin();
LayerListReverseIterator<Layer> rend();
- // LayerTreeHostInProcess interface to Proxy.
+ // LayerTreeHost interface to Proxy.
void WillBeginMainFrame();
void DidBeginMainFrame();
void BeginMainFrame(const viz::BeginFrameArgs& args);
@@ -636,9 +648,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_;
+ viz::LocalSurfaceId local_surface_id_from_parent_;
// Used to detect surface invariant violations.
- bool has_pushed_local_surface_id_ = false;
+ bool has_pushed_local_surface_id_from_parent_ = false;
+ bool new_local_surface_id_request_ = false;
bool defer_commits_ = false;
SkColor background_color_ = SK_ColorWHITE;
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index f411b4efca1..e599a6b4c1d 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -40,7 +40,8 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest {
void ReadTestFile(const std::string& name) {
base::FilePath test_data_dir;
- ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
+ ASSERT_TRUE(
+ base::PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
}
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 910862ce9a8..df0758ace5d 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -16,6 +16,8 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/containers/adapters.h"
#include "base/containers/flat_map.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
@@ -23,6 +25,7 @@
#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 "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
@@ -82,6 +85,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gpu/texture_allocation.h"
+#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/quads/frame_deadline.h"
@@ -90,6 +94,7 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
+#include "components/viz/common/resources/platform_color.h"
#include "components/viz/common/traced_value.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
@@ -107,6 +112,53 @@
namespace cc {
namespace {
+// Used to accommodate finite precision when comparing scaled viewport and
+// content widths. While this value may seem large, width=device-width on an N7
+// V1 saw errors of ~0.065 between computed window and content widths.
+const float kMobileViewportWidthEpsilon = 0.15f;
+
+bool HasFixedPageScale(LayerTreeImpl* active_tree) {
+ return active_tree->min_page_scale_factor() ==
+ active_tree->max_page_scale_factor();
+}
+
+bool HasMobileViewport(LayerTreeImpl* active_tree) {
+ float window_width_dip = active_tree->current_page_scale_factor() *
+ active_tree->ScrollableViewportSize().width();
+ float content_width_css = active_tree->ScrollableSize().width();
+ return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
+}
+
+bool IsMobileOptimized(LayerTreeImpl* active_tree) {
+ bool has_mobile_viewport = HasMobileViewport(active_tree);
+ bool has_fixed_page_scale = HasFixedPageScale(active_tree);
+ return has_fixed_page_scale || has_mobile_viewport;
+}
+
+viz::ResourceFormat TileRasterBufferFormat(
+ const LayerTreeSettings& settings,
+ viz::ContextProvider* context_provider,
+ bool use_gpu_rasterization) {
+ // Software compositing always uses the native skia RGBA N32 format, but we
+ // just call it RGBA_8888 everywhere even though it can be BGRA ordering,
+ // because we don't need to communicate the actual ordering as the code all
+ // assumes the native skia format.
+ if (!context_provider)
+ return viz::RGBA_8888;
+
+ // RGBA4444 overrides the defaults if specified, but only for gpu compositing.
+ // It is always supported on platforms where it is specified.
+ if (settings.use_rgba_4444)
+ return viz::RGBA_4444;
+ // Otherwise we use BGRA textures if we can but it depends on the context
+ // capabilities, and we have different preferences when rastering to textures
+ // vs uploading textures.
+ const gpu::Capabilities& caps = context_provider->ContextCapabilities();
+ if (use_gpu_rasterization)
+ return viz::PlatformColor::BestSupportedRenderBufferFormat(caps);
+ return viz::PlatformColor::BestSupportedTextureFormat(caps);
+}
+
// Small helper class that saves the current viewport location as the user sees
// it and resets to the same location.
class ViewportAnchor {
@@ -212,7 +264,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(
: client_(client),
task_runner_provider_(task_runner_provider),
current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
- layer_tree_frame_sink_(nullptr),
need_update_gpu_rasterization_status_(false),
content_has_slow_paths_(false),
content_has_non_aa_paint_(false),
@@ -294,7 +345,9 @@ LayerTreeHostImpl::LayerTreeHostImpl(
this, settings.top_controls_show_threshold,
settings.top_controls_hide_threshold);
- tile_manager_.SetDecodedImageTracker(&decoded_image_tracker_);
+ memory_pressure_listener_.reset(
+ new base::MemoryPressureListener(base::BindRepeating(
+ &LayerTreeHostImpl::OnMemoryPressure, base::Unretained(this))));
}
LayerTreeHostImpl::~LayerTreeHostImpl() {
@@ -882,8 +935,8 @@ bool LayerTreeHostImpl::HasDamage() const {
// If we have a new LocalSurfaceId, we must always submit a CompositorFrame
// because the parent is blocking on us.
bool local_surface_id_changed =
- settings_.enable_surface_synchronization &&
- (last_draw_local_surface_id_ != active_tree->local_surface_id());
+ last_draw_local_surface_id_ !=
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
return root_surface_has_visible_damage ||
active_tree_->property_trees()->effect_tree.HasCopyRequests() ||
@@ -1448,6 +1501,7 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
void LayerTreeHostImpl::DidModifyTilePriorities() {
// Mark priorities as dirty and schedule a PrepareTiles().
tile_priorities_dirty_ = true;
+ tile_manager_.DidModifyTilePriorities();
client_->SetNeedsPrepareTilesOnImplThread();
}
@@ -1730,8 +1784,10 @@ void LayerTreeHostImpl::ReclaimResources(
// If we're not visible, we likely released resources, so we want to
// aggressively flush here to make sure those DeleteTextures make it to the
// GPU process to free up the memory.
- if (!visible_)
- resource_provider_->FlushPendingDeletions();
+ if (!visible_ && layer_tree_frame_sink_->context_provider()) {
+ auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
+ gl->ShallowFlushCHROMIUM();
+ }
}
void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform,
@@ -1844,8 +1900,39 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata() {
gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
metadata.root_background_color = active_tree_->background_color();
metadata.is_scroll_offset_at_top = active_tree_->TotalScrollOffset().y() == 0;
+ metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
+ active_tree_->device_scale_factor();
+ metadata.viewport_size_in_pixels = device_viewport_size();
+ metadata.top_controls_height =
+ browser_controls_offset_manager_->TopControlsHeight();
+ metadata.top_controls_shown_ratio =
+ browser_controls_offset_manager_->TopControlsShownRatio();
+ metadata.bottom_controls_height =
+ browser_controls_offset_manager_->BottomControlsHeight();
+ metadata.bottom_controls_shown_ratio =
+ browser_controls_offset_manager_->BottomControlsShownRatio();
+
+ bool allocate_new_local_surface_id =
+ last_draw_render_frame_metadata_ &&
+ (last_draw_render_frame_metadata_->top_controls_height !=
+ metadata.top_controls_height ||
+ last_draw_render_frame_metadata_->top_controls_shown_ratio !=
+ metadata.top_controls_shown_ratio ||
+ last_draw_render_frame_metadata_->bottom_controls_height !=
+ metadata.bottom_controls_height ||
+ last_draw_render_frame_metadata_->bottom_controls_shown_ratio !=
+ metadata.bottom_controls_shown_ratio);
+
+ viz::LocalSurfaceId local_surface_id =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
+ if (local_surface_id.is_valid()) {
+ if (allocate_new_local_surface_id)
+ local_surface_id = child_local_surface_id_allocator_.GenerateId();
+ metadata.local_surface_id = local_surface_id;
+ }
active_tree_->GetViewportSelection(&metadata.selection);
+ metadata.is_mobile_optimized = IsMobileOptimized(active_tree_.get());
return metadata;
}
@@ -1923,32 +2010,32 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
active_tree()->FinishSwapPromises(&metadata, &frame_token_allocator_);
if (render_frame_metadata_observer_) {
- RenderFrameMetadata render_frame_metadata = MakeRenderFrameMetadata();
+ last_draw_render_frame_metadata_ = MakeRenderFrameMetadata();
render_frame_metadata_observer_->OnRenderFrameSubmission(
- std::move(render_frame_metadata));
+ *last_draw_render_frame_metadata_);
}
metadata.latency_info.emplace_back(ui::SourceEventType::FRAME);
ui::LatencyInfo& new_latency_info = metadata.latency_info.back();
if (CommitToActiveTree()) {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, 0, 0, frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, 0, frame_time, 1);
} else {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, 0, 0, frame_time,
+ ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, 0, frame_time,
1);
base::TimeTicks draw_time = base::TimeTicks::Now();
for (auto& latency : metadata.latency_info) {
latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, 0, draw_time, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, draw_time, 1);
}
}
ui::LatencyInfo::TraceIntermediateFlowEvents(metadata.latency_info,
"SwapBuffers");
// Collect all resource ids in the render passes into a single array.
- ResourceProvider::ResourceIdArray resources;
+ std::vector<viz::ResourceId> resources;
for (const auto& render_pass : frame->render_passes) {
for (auto* quad : render_pass->quad_list) {
for (viz::ResourceId resource_id : quad->resources)
@@ -1962,8 +2049,9 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
viz::CompositorFrame compositor_frame;
compositor_frame.metadata = std::move(metadata);
- resource_provider_->PrepareSendToParent(resources,
- &compositor_frame.resource_list);
+ resource_provider_->PrepareSendToParent(
+ resources, &compositor_frame.resource_list,
+ layer_tree_frame_sink_->context_provider());
compositor_frame.render_pass_list = std::move(frame->render_passes);
// TODO(fsamuel): Once all clients get their viz::LocalSurfaceId from their
// parent, the viz::LocalSurfaceId should hang off CompositorFrameMetadata.
@@ -1974,11 +2062,12 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
// 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().is_valid());
+ active_tree()->local_surface_id_from_parent().is_valid());
layer_tree_frame_sink_->SetLocalSurfaceId(
- active_tree()->local_surface_id());
- last_draw_local_surface_id_ = active_tree()->local_surface_id();
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
}
+ last_draw_local_surface_id_ =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
if (const char* client_name = GetClientNameForMetrics()) {
size_t total_quad_count = 0;
for (const auto& pass : compositor_frame.render_pass_list)
@@ -2102,9 +2191,13 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
*supports_disable_msaa = caps.multisample_compatibility;
if (!caps.msaa_is_slow && !caps.avoid_stencil_buffers) {
// Skia may blacklist MSAA independently of Chrome. Query Skia for its max
- // supported sample count.
- SkColorType color_type =
- ResourceFormatToClosestSkColorType(settings_.preferred_tile_format);
+ // supported sample count. Assume gpu compositing + gpu raster for this, as
+ // that is what we are hoping to use.
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, layer_tree_frame_sink_->context_provider(),
+ /*use_gpu_rasterization=*/true);
+ SkColorType color_type = ResourceFormatToClosestSkColorType(
+ /*gpu_compositing=*/true, tile_format);
*max_msaa_samples =
gr_context->maxSurfaceSampleCountForColorType(color_type);
}
@@ -2244,7 +2337,7 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
void LayerTreeHostImpl::DidFinishImplFrame() {
impl_thread_phase_ = ImplThreadPhase::IDLE;
current_begin_frame_tracker_.Finish();
- decoded_image_tracker_.NotifyFrameFinished();
+ tile_manager_.decoded_image_tracker().NotifyFrameFinished();
}
void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
@@ -2302,6 +2395,100 @@ void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
single_thread_synchronous_task_graph_runner_->RunUntilIdle();
}
+static uint32_t GetFlagsForSurfaceLayer(const SurfaceLayerImpl* layer) {
+ uint32_t flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch;
+ const auto& surface_id = layer->primary_surface_id();
+ if (layer->is_clipped()) {
+ flags |= viz::HitTestRegionFlags::kHitTestAsk;
+ }
+ if (surface_id.local_surface_id().is_valid()) {
+ flags |= viz::HitTestRegionFlags::kHitTestChildSurface;
+ } else {
+ flags |= viz::HitTestRegionFlags::kHitTestMine;
+ }
+ return flags;
+}
+
+static void PopulateHitTestRegion(viz::HitTestRegion* hit_test_region,
+ const LayerImpl* layer,
+ uint32_t flags,
+ 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->rect = rect;
+ // The transform of hit test region maps a point from parent hit test region
+ // to the local space. This is the inverse of screen space transform. Because
+ // hit test query wants the point in target to be in Pixel space, we
+ // counterscale the transform here. Note that the rect is scaled by dsf, so
+ // the point and the rect are still in the same space.
+ gfx::Transform surface_to_root_transform = layer->ScreenSpaceTransform();
+ surface_to_root_transform.Scale(SK_MScalar1 / device_scale_factor,
+ SK_MScalar1 / device_scale_factor);
+ // TODO(sunxd): Avoid losing precision by not using inverse if possible.
+ bool ok = surface_to_root_transform.GetInverse(&hit_test_region->transform);
+ // Note: If |ok| is false, the |transform| is set to the identity before
+ // returning, which is what we want.
+ ALLOW_UNUSED_LOCAL(ok);
+}
+
+base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
+ if (!settings_.build_hit_test_data)
+ return {};
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list(base::in_place);
+ hit_test_region_list->flags = viz::HitTestRegionFlags::kHitTestMine |
+ viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch;
+ hit_test_region_list->bounds = DeviceViewport();
+ hit_test_region_list->transform = DrawTransform();
+
+ float device_scale_factor = active_tree()->device_scale_factor();
+
+ Region overlapping_region;
+ for (const auto* layer : base::Reversed(*active_tree())) {
+ if (!layer->should_hit_test())
+ continue;
+
+ if (layer->is_surface_layer()) {
+ const auto* surface_layer = static_cast<const SurfaceLayerImpl*>(layer);
+
+ if (!surface_layer->surface_hit_testable()) {
+ overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), gfx::Rect(surface_layer->bounds())));
+ continue;
+ }
+
+ gfx::Rect content_rect(
+ gfx::ScaleToEnclosingRect(gfx::Rect(surface_layer->bounds()),
+ device_scale_factor, device_scale_factor));
+
+ 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))
+ flag |= viz::HitTestRegionFlags::kHitTestAsk;
+ auto surface_id = surface_layer->primary_surface_id();
+ hit_test_region_list->regions.emplace_back();
+ PopulateHitTestRegion(&hit_test_region_list->regions.back(), layer, flag,
+ content_rect, surface_id, device_scale_factor);
+ continue;
+ }
+ // TODO(sunxd): Submit all overlapping layer bounds as hit test regions.
+ overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), gfx::Rect(layer->bounds())));
+ }
+
+ return hit_test_region_list;
+}
+
void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
// Check that we haven't already detected context loss because we get it via
// two paths: compositor context loss on the compositor thread and worker
@@ -2310,8 +2497,6 @@ void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
if (!has_valid_layer_tree_frame_sink_)
return;
has_valid_layer_tree_frame_sink_ = false;
- if (resource_provider_)
- resource_provider_->DidLoseContextProvider();
client_->DidLoseLayerTreeFrameSinkOnImplThread();
}
@@ -2502,6 +2687,14 @@ void LayerTreeHostImpl::ActivateSyncTree() {
// Activation can change the root scroll offset, so inform the synchronous
// input handler.
UpdateRootLayerStateForSynchronousInputHandler();
+
+ // Update the child's LocalSurfaceId.
+ if (active_tree()->local_surface_id_from_parent().is_valid()) {
+ child_local_surface_id_allocator_.UpdateFromParent(
+ active_tree()->local_surface_id_from_parent());
+ if (active_tree()->TakeNewLocalSurfaceIdRequest())
+ child_local_surface_id_allocator_.GenerateId();
+ }
}
void LayerTreeHostImpl::ActivateStateForImages() {
@@ -2509,6 +2702,30 @@ void LayerTreeHostImpl::ActivateStateForImages() {
tile_manager_.DidActivateSyncTree();
}
+void LayerTreeHostImpl::OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ // Only work for low-end devices for now.
+ if (!base::SysInfo::IsLowEndDevice())
+ return;
+
+ switch (level) {
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+ ReleaseTileResources();
+ ReleaseTreeResources();
+ ClearUIResources();
+ if (image_decode_cache_) {
+ image_decode_cache_->SetShouldAggressivelyFreeResources(true);
+ image_decode_cache_->SetShouldAggressivelyFreeResources(false);
+ }
+ if (resource_pool_)
+ resource_pool_->OnPurgeMemory();
+ break;
+ }
+}
+
void LayerTreeHostImpl::SetVisible(bool visible) {
DCHECK(task_runner_provider_->IsImplThread());
@@ -2599,20 +2816,21 @@ void LayerTreeHostImpl::RecreateTileResources() {
void LayerTreeHostImpl::CreateTileManagerResources() {
raster_buffer_provider_ = CreateRasterBufferProvider();
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, layer_tree_frame_sink_->context_provider(),
+ use_gpu_rasterization_);
+
if (use_gpu_rasterization_) {
- int max_texture_size = layer_tree_frame_sink_->context_provider()
- ->ContextCapabilities()
- .max_texture_size;
image_decode_cache_ = std::make_unique<GpuImageDecodeCache>(
layer_tree_frame_sink_->worker_context_provider(),
use_oop_rasterization_,
- viz::ResourceFormatToClosestSkColorType(
- settings_.preferred_tile_format),
- settings_.decoded_image_working_set_budget_bytes, max_texture_size);
+ viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
+ tile_format),
+ settings_.decoded_image_working_set_budget_bytes, max_texture_size_);
} else {
+ bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
- viz::ResourceFormatToClosestSkColorType(
- settings_.preferred_tile_format),
+ viz::ResourceFormatToClosestSkColorType(gpu_compositing, tile_format),
settings_.decoded_image_working_set_budget_bytes);
}
@@ -2643,18 +2861,22 @@ LayerTreeHostImpl::CreateRasterBufferProvider() {
if (!compositor_context_provider)
return std::make_unique<BitmapRasterBufferProvider>(layer_tree_frame_sink_);
+ const gpu::Capabilities& caps =
+ compositor_context_provider->ContextCapabilities();
viz::RasterContextProvider* worker_context_provider =
layer_tree_frame_sink_->worker_context_provider();
+
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, compositor_context_provider, use_gpu_rasterization_);
+
if (use_gpu_rasterization_) {
DCHECK(worker_context_provider);
int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0;
return std::make_unique<GpuRasterBufferProvider>(
compositor_context_provider, worker_context_provider,
- resource_provider_.get(),
settings_.resource_settings.use_gpu_memory_buffer_resources,
- msaa_sample_count, settings_.preferred_tile_format,
- settings_.max_gpu_raster_tile_size,
+ msaa_sample_count, tile_format, settings_.max_gpu_raster_tile_size,
settings_.unpremultiply_and_dither_low_bit_depth_tiles,
use_oop_rasterization_);
}
@@ -2670,21 +2892,18 @@ LayerTreeHostImpl::CreateRasterBufferProvider() {
if (use_zero_copy) {
return std::make_unique<ZeroCopyRasterBufferProvider>(
- resource_provider_.get(),
layer_tree_frame_sink_->gpu_memory_buffer_manager(),
- compositor_context_provider, settings_.preferred_tile_format);
+ compositor_context_provider, tile_format);
}
const int max_copy_texture_chromium_size =
- compositor_context_provider->ContextCapabilities()
- .max_copy_texture_chromium_size;
+ caps.max_copy_texture_chromium_size;
return std::make_unique<OneCopyRasterBufferProvider>(
GetTaskRunner(), compositor_context_provider, worker_context_provider,
- resource_provider_.get(), max_copy_texture_chromium_size,
- settings_.use_partial_raster,
+ layer_tree_frame_sink_->gpu_memory_buffer_manager(),
+ max_copy_texture_chromium_size, settings_.use_partial_raster,
settings_.resource_settings.use_gpu_memory_buffer_resources,
- settings_.max_staging_buffer_usage_in_bytes,
- settings_.preferred_tile_format);
+ settings_.max_staging_buffer_usage_in_bytes, tile_format);
}
void LayerTreeHostImpl::SetLayerTreeMutator(
@@ -2711,7 +2930,7 @@ void LayerTreeHostImpl::QueueImageDecode(int request_id,
image.GetKeyForFrame(image.frame_index()).ToString());
// Optimistically specify the current raster color space, since we assume that
// it won't change.
- decoded_image_tracker_.QueueImageDecode(
+ tile_manager_.decoded_image_tracker().QueueImageDecode(
image, GetRasterColorSpace().color_space,
base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
base::Unretained(this), request_id));
@@ -2795,6 +3014,11 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
ClearUIResources();
resource_provider_ = nullptr;
+ if (layer_tree_frame_sink_->context_provider()) {
+ auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
+ gl->Finish();
+ }
+
// Release any context visibility before we destroy the LayerTreeFrameSink.
SetContextVisibility(false);
@@ -2824,27 +3048,23 @@ bool LayerTreeHostImpl::InitializeRenderer(
layer_tree_frame_sink_ = layer_tree_frame_sink;
has_valid_layer_tree_frame_sink_ = true;
- resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
- layer_tree_frame_sink_->context_provider(),
- layer_tree_frame_sink_->shared_bitmap_manager(),
- layer_tree_frame_sink_->gpu_memory_buffer_manager(),
- layer_tree_frame_sink_->capabilities().delegated_sync_points_required,
- settings_.resource_settings);
- if (!layer_tree_frame_sink_->context_provider()) {
- // This ResourcePool will vend software resources.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), GetTaskRunner(),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kSoftware,
- settings_.disallow_non_exact_resource_reuse);
+
+ auto* context_provider = layer_tree_frame_sink_->context_provider();
+ if (context_provider) {
+ max_texture_size_ =
+ context_provider->ContextCapabilities().max_texture_size;
} else {
- // The ResourcePool will vend gpu resources.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), GetTaskRunner(),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- settings_.disallow_non_exact_resource_reuse);
+ // Pick an arbitrary limit here similar to what hardware might.
+ max_texture_size_ = 16 * 1024;
}
- if (features::IsVizHitTestingSurfaceLayerEnabled())
- layer_tree_frame_sink_->UpdateHitTestData(this);
+
+ resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
+ layer_tree_frame_sink_->context_provider(),
+ layer_tree_frame_sink_->capabilities().delegated_sync_points_required);
+ resource_pool_ = std::make_unique<ResourcePool>(
+ resource_provider_.get(), layer_tree_frame_sink_->context_provider(),
+ GetTaskRunner(), ResourcePool::kDefaultExpirationDelay,
+ settings_.disallow_non_exact_resource_reuse);
// TODO(piman): Make oop raster always supported: http://crbug.com/786591
use_oop_rasterization_ = settings_.enable_oop_rasterization;
@@ -3128,9 +3348,15 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
if (!scrolling_node) {
- scroll_status.thread = SCROLL_IGNORED;
- if (settings_.is_layer_tree_for_subframe)
+ if (settings_.is_layer_tree_for_subframe) {
+ TRACE_EVENT_INSTANT0("cc", "Ignored - No ScrollNode (OOPIF)",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_UNKNOWN;
+ } else {
+ TRACE_EVENT_INSTANT0("cc", "Ignroed - No ScrollNode",
+ TRACE_EVENT_SCOPE_THREAD);
+ scroll_status.thread = SCROLL_IGNORED;
+ }
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNoScrollingLayer;
return scroll_status;
@@ -3140,6 +3366,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
browser_controls_offset_manager_->ScrollBegin();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ScrollBeginImpl",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ scrolling_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(scrolling_node);
// TODO(majidvp): get rid of wheel_scrolling_ and set is_direct_manipulation
// in input_handler_proxy instead.
@@ -3152,6 +3381,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
// If the CurrentlyScrollingNode doesn't exist after distributing scroll
// delta, no scroller can scroll in the given delta hint direction(s).
if (!active_tree_->CurrentlyScrollingNode()) {
+ TRACE_EVENT_INSTANT0("cc", "Ignored - Didnt Scroll",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = InputHandler::SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3211,6 +3442,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
if (layer_impl) {
if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) {
+ TRACE_EVENT_INSTANT0("cc", "Failed Hit Test", TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_UNKNOWN;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kFailedHitTest;
@@ -3277,6 +3509,7 @@ bool LayerTreeHostImpl::IsInitialScrollHitTestReliable(
InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
ScrollState* scroll_state) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollAnimatedBegin");
InputHandler::ScrollStatus scroll_status;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3288,6 +3521,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
if (ScrollAnimationUpdateTarget(scroll_node, delta, base::TimeDelta())) {
scroll_status.thread = SCROLL_ON_IMPL_THREAD;
} else {
+ TRACE_EVENT_INSTANT0("cc", "Failed to create animation",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3377,6 +3612,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta,
base::TimeDelta delayed_by) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollAnimated");
InputHandler::ScrollStatus scroll_status;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3403,6 +3639,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
if (ScrollAnimationUpdateTarget(scroll_node, delta, delayed_by)) {
scroll_status.thread = SCROLL_ON_IMPL_THREAD;
} else {
+ TRACE_EVENT_INSTANT0("cc", "Failed to update animation",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3479,10 +3717,13 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
}
scroll_state.set_is_ending(true);
ScrollEndImpl(&scroll_state);
- if (settings_.is_layer_tree_for_subframe &&
- scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
- // If we get to here, we shouldn't return SCROLL_ON_IMPL_THREAD as otherwise
- // we'll mark the scroll as handled and the scroll won't bubble.
+ if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
+ // Update scroll_status.thread to SCROLL_IGNORED when there is no ongoing
+ // scroll animation, we can scroll on impl thread and yet, we couldn't
+ // create a new scroll animation. This happens when the scroller has hit its
+ // extent.
+ TRACE_EVENT_INSTANT0("cc", "Ignored - Scroller at extent",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3746,8 +3987,13 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) {
}
}
}
- active_tree_->SetCurrentlyScrollingNode(
- current_scroll_chain.empty() ? nullptr : current_scroll_chain.back());
+
+ scroll_node =
+ current_scroll_chain.empty() ? nullptr : current_scroll_chain.back();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode DistributeScrollDelta",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ scroll_node ? false : true);
+ active_tree_->SetCurrentlyScrollingNode(scroll_node);
scroll_state->set_scroll_chain_and_layer_tree(current_scroll_chain,
active_tree());
scroll_state->DistributeToScrollChainDescendant();
@@ -3803,8 +4049,27 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
DCHECK(scroll_state);
TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
- ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
+ auto& scroll_tree = active_tree_->property_trees()->scroll_tree;
+
+ ElementId provided_element =
+ scroll_state->data()->current_native_scrolling_element();
+ const auto* provided_scroll_node =
+ scroll_tree.FindNodeFromElementId(provided_element);
+
+ // If the currently scrolling node is not set, set it with
+ // |provided_scroll_node|.
ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+ if (scroll_node) {
+ // If |provided_scroll_node| is not null, make sure it matches
+ // |scroll_node|.
+ DCHECK(!provided_scroll_node || scroll_node == provided_scroll_node);
+ } else {
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ScrollBy",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ provided_scroll_node ? false : true);
+ active_tree_->SetCurrentlyScrollingNode(provided_scroll_node);
+ scroll_node = scroll_tree.CurrentlyScrollingNode();
+ }
if (!scroll_node)
return InputHandlerScrollResult();
@@ -3825,13 +4090,15 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
scroll_state->set_delta_consumed_for_scroll_sequence(
did_lock_scrolling_layer_);
scroll_state->set_is_direct_manipulation(!wheel_scrolling_);
- scroll_state->set_current_native_scrolling_node(
- active_tree()->property_trees()->scroll_tree.CurrentlyScrollingNode());
+ scroll_state->set_current_native_scrolling_node(scroll_node);
DistributeScrollDelta(scroll_state);
ScrollNode* current_scrolling_node =
scroll_state->current_native_scrolling_node();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ApplyDelta",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ current_scrolling_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(current_scrolling_node);
did_lock_scrolling_layer_ =
scroll_state->delta_consumed_for_scroll_sequence();
@@ -3898,10 +4165,10 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
UpdateRootLayerStateForSynchronousInputHandler();
}
- scroll_result.current_offset = ScrollOffsetToVector2dF(
- scroll_tree.current_scroll_offset(scroll_node->element_id));
+ scroll_result.current_visual_offset =
+ ScrollOffsetToVector2dF(GetVisualScrollOffset(*scroll_node));
float scale_factor = active_tree()->current_page_scale_factor();
- scroll_result.current_offset.Scale(scale_factor);
+ scroll_result.current_visual_offset.Scale(scale_factor);
// Run animations which need to respond to updated scroll offset.
mutator_host_->TickScrollAnimations(
@@ -3917,6 +4184,9 @@ void LayerTreeHostImpl::RequestUpdateForSynchronousInputHandler() {
void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_offset) {
+ TRACE_EVENT2("cc",
+ "LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset",
+ "offset_x", root_offset.x(), "offset_y", root_offset.y());
bool changed = active_tree_->DistributeRootScrollOffset(root_offset);
if (!changed)
return;
@@ -3936,9 +4206,7 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
return false;
const SnapContainerData& data = scroll_node->snap_container_data.value();
- ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
- gfx::ScrollOffset current_position =
- scroll_tree.current_scroll_offset(scroll_node->element_id);
+ gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
gfx::ScrollOffset snap_position;
if (!data.FindSnapPosition(current_position, did_scroll_x_for_scroll_gesture_,
@@ -3947,12 +4215,43 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
return false;
}
- ScrollAnimationCreate(
- scroll_node, ScrollOffsetToVector2dF(snap_position - current_position),
- base::TimeDelta());
+ gfx::Vector2dF delta =
+ ScrollOffsetToVector2dF(snap_position - current_position);
+ bool scrolls_main_viewport_scroll_layer =
+ scroll_node == ViewportMainScrollNode();
+ if (scrolls_main_viewport_scroll_layer) {
+ // Flash the overlay scrollbar even if the scroll dalta is 0.
+ if (settings_.scrollbar_flash_after_any_scroll_update) {
+ FlashAllScrollbars(false);
+ } else {
+ ScrollbarAnimationController* animation_controller =
+ ScrollbarAnimationControllerForElementId(scroll_node->element_id);
+ if (animation_controller)
+ animation_controller->WillUpdateScroll();
+ }
+ gfx::Vector2dF scaled_delta(delta);
+ scaled_delta.Scale(active_tree()->current_page_scale_factor());
+ viewport()->ScrollAnimated(scaled_delta, base::TimeDelta());
+ } else {
+ ScrollAnimationCreate(scroll_node, delta, base::TimeDelta());
+ }
return true;
}
+gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset(
+ const ScrollNode& scroll_node) const {
+ const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
+
+ bool scrolls_main_viewport_scroll_layer =
+ viewport()->MainScrollLayer() &&
+ viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node.id;
+
+ if (scrolls_main_viewport_scroll_layer)
+ return viewport()->TotalScrollOffset();
+ else
+ return scroll_tree.current_scroll_offset(scroll_node.element_id);
+}
+
bool LayerTreeHostImpl::GetSnapFlingInfo(
const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* initial_offset,
@@ -3966,9 +4265,8 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
gfx::Vector2dF natural_displacement_in_content =
gfx::ScaleVector2d(natural_displacement_in_viewport, 1.f / scale_factor);
- const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
- *initial_offset = ScrollOffsetToVector2dF(
- scroll_tree.current_scroll_offset(scroll_node->element_id));
+ *initial_offset =
+ ScrollOffsetToVector2dF(GetVisualScrollOffset(*scroll_node));
bool did_scroll_x = did_scroll_x_for_scroll_gesture_ ||
natural_displacement_in_content.x() != 0;
@@ -3989,6 +4287,7 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
}
void LayerTreeHostImpl::ClearCurrentlyScrollingNode() {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ClearCurrentlyScrollingNode");
active_tree_->ClearCurrentlyScrollingNode();
did_lock_scrolling_layer_ = false;
scroll_affects_scroll_handler_ = false;
@@ -4118,6 +4417,9 @@ void LayerTreeHostImpl::PinchGestureBegin() {
client_->RenewTreePriority();
pinch_gesture_end_should_clear_scrolling_node_ = !CurrentlyScrollingNode();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode PinchGestureBegin",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ OuterViewportScrollNode() ? false : true);
active_tree_->SetCurrentlyScrollingNode(OuterViewportScrollNode());
browser_controls_offset_manager_->PinchBegin();
}
@@ -4530,9 +4832,16 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
return;
}
- viz::ResourceFormat format = resource_provider_->best_texture_format();
+ viz::ResourceFormat format;
switch (bitmap.GetFormat()) {
case UIResourceBitmap::RGBA8:
+ if (layer_tree_frame_sink_->context_provider()) {
+ const gpu::Capabilities& caps =
+ layer_tree_frame_sink_->context_provider()->ContextCapabilities();
+ format = viz::PlatformColor::BestSupportedTextureFormat(caps);
+ } else {
+ format = viz::RGBA_8888;
+ }
break;
case UIResourceBitmap::ALPHA_8:
format = viz::ALPHA_8;
@@ -4548,13 +4857,12 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// UIResources are assumed to be rastered in SRGB.
const gfx::ColorSpace& color_space = gfx::ColorSpace::CreateSRGB();
- int max_texture_size = resource_provider_->max_texture_size();
- if (source_size.width() > max_texture_size ||
- source_size.height() > max_texture_size) {
+ if (source_size.width() > max_texture_size_ ||
+ source_size.height() > max_texture_size_) {
// Must resize the bitmap to fit within the max texture size.
scaled = true;
int edge = std::max(source_size.width(), source_size.height());
- float scale = static_cast<float>(max_texture_size - 1) / edge;
+ float scale = static_cast<float>(max_texture_size_ - 1) / edge;
DCHECK_LT(scale, 1.f);
upload_size = gfx::ScaleToCeiledSize(source_size, scale, scale);
}
@@ -4680,7 +4988,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
shared_memory.get(), upload_size, format);
layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(memory_handle),
shared_bitmap_id);
- transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id, 0,
+ transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id,
upload_size, format);
}
transferable.color_space = color_space;
@@ -4976,6 +5284,7 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged(
}
void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollOffsetAnimationFinished");
// TODO(majidvp): We should pass in the original starting scroll position here
ScrollStateData scroll_state_data;
ScrollState scroll_state(scroll_state_data);
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 82d50cc888b..3f93eb51e60 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -17,6 +17,7 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/sequenced_task_runner.h"
#include "base/time/time.h"
#include "cc/base/synced_property.h"
@@ -41,11 +42,13 @@
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/managed_memory_policy.h"
#include "cc/trees/mutator_host_client.h"
+#include "cc/trees/render_frame_metadata.h"
#include "cc/trees/task_runner_provider.h"
#include "cc/trees/ukm_manager.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/gpu/context_cache_controller.h"
#include "components/viz/common/quads/render_pass.h"
+#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "ui/gfx/geometry/rect.h"
@@ -75,7 +78,6 @@ class PendingTreeDurationHistogramTimer;
class PendingTreeRasterDurationHistogramTimer;
class RasterTilePriorityQueue;
class RasterBufferProvider;
-class RenderFrameMetadata;
class RenderFrameMetadataObserver;
class RenderingStatsInstrumentation;
class ResourcePool;
@@ -425,6 +427,7 @@ class CC_EXPORT LayerTreeHostImpl
void SetExternalTilePriorityConstraints(
const gfx::Rect& viewport_rect,
const gfx::Transform& transform) override;
+ base::Optional<viz::HitTestRegionList> BuildHitTestData() override;
void DidLoseLayerTreeFrameSink() override;
void DidReceiveCompositorFrameAck() override;
void DidPresentCompositorFrame(uint32_t presentation_token,
@@ -449,6 +452,7 @@ class CC_EXPORT LayerTreeHostImpl
LayerTreeFrameSink* layer_tree_frame_sink() const {
return layer_tree_frame_sink_;
}
+ int max_texture_size() const { return max_texture_size_; }
void ReleaseLayerTreeFrameSink();
std::string LayerListAsJson() const;
@@ -531,7 +535,9 @@ class CC_EXPORT LayerTreeHostImpl
ManagedMemoryPolicy ActualManagedMemoryPolicy() const;
void SetViewportSize(const gfx::Size& device_viewport_size);
- gfx::Size device_viewport_size() const { return device_viewport_size_; }
+ const gfx::Size& device_viewport_size() const {
+ return device_viewport_size_;
+ }
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
gfx::Rect viewport_visible_rect() const { return viewport_visible_rect_; }
@@ -596,6 +602,10 @@ class CC_EXPORT LayerTreeHostImpl
virtual bool IsUIResourceOpaque(UIResourceId uid) const;
+ // This method gets the scroll offset for a regular scroller, or the combined
+ // visual and layout offsets of the viewport.
+ gfx::ScrollOffset GetVisualScrollOffset(const ScrollNode& scroll_node) const;
+
bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* initial_offset,
gfx::Vector2dF* target_offset) const override;
@@ -851,6 +861,9 @@ class CC_EXPORT LayerTreeHostImpl
// active tree.
void ActivateStateForImages();
+ void OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level);
+
std::unordered_map<UIResourceId, UIResourceData> ui_resource_map_;
// UIResources are held here once requested to be deleted until they are
// released from the display compositor, then the backing can be deleted.
@@ -861,7 +874,14 @@ class CC_EXPORT LayerTreeHostImpl
// associated with them anymore, as that is freed at the time of eviction.
std::set<UIResourceId> evicted_ui_resources_;
- LayerTreeFrameSink* layer_tree_frame_sink_;
+ // These are valid when has_valid_layer_tree_frame_sink_ is true.
+ //
+ // A pointer used for communicating with and submitting output to the display
+ // compositor.
+ LayerTreeFrameSink* layer_tree_frame_sink_ = nullptr;
+ // The maximum size (either width or height) that any texture can be. Also
+ // holds a reasonable value for software compositing bitmaps.
+ int max_texture_size_ = 0;
// The following scoped variables must not outlive the
// |layer_tree_frame_sink_|.
@@ -921,7 +941,6 @@ class CC_EXPORT LayerTreeHostImpl
const bool is_synchronous_single_threaded_;
TileManager tile_manager_;
- DecodedImageTracker decoded_image_tracker_;
gfx::Vector2dF accumulated_root_overscroll_;
@@ -1053,10 +1072,14 @@ class CC_EXPORT LayerTreeHostImpl
uint32_t last_presentation_token_ = 0u;
viz::LocalSurfaceId last_draw_local_surface_id_;
+ base::Optional<RenderFrameMetadata> last_draw_render_frame_metadata_;
+ viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
const int default_color_space_id_;
const gfx::ColorSpace default_color_space_;
+ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
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 4c4570ee4d7..b7fdefd87dc 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -10,14 +10,17 @@
#include <cmath>
#include <utility>
+#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/transform_operations.h"
@@ -69,11 +72,13 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/service/display/gl_renderer.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
+#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -180,7 +185,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void DidActivateSyncTree() override {
// Make sure the active tree always has a valid LocalSurfaceId.
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
}
void WillPrepareTiles() override {}
@@ -242,7 +247,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool init = host_impl_->InitializeRenderer(layer_tree_frame_sink_.get());
host_impl_->SetViewportSize(gfx::Size(10, 10));
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
// Set the viz::BeginFrameArgs so that methods which use it are able to.
host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
@@ -1063,15 +1068,23 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
status.main_thread_scrolling_reasons);
}
+class LostGLES2Interface : public viz::TestGLES2Interface {
+ public:
+ LostGLES2Interface() = default;
+
+ void InitializeTestContext() override {
+ LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
+ }
+};
+
TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
- std::unique_ptr<TestWebGraphicsContext3D> context_owned =
- TestWebGraphicsContext3D::Create();
- context_owned->set_context_lost(true);
+ auto gl_owned = std::make_unique<LostGLES2Interface>();
// Initialization will fail.
- EXPECT_FALSE(CreateHostImpl(
- DefaultSettings(),
- FakeLayerTreeFrameSink::Create3d(std::move(context_owned))));
+ EXPECT_FALSE(
+ CreateHostImpl(DefaultSettings(),
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned))));
SetupScrollAndContentsLayers(gfx::Size(100, 100));
@@ -1643,7 +1656,7 @@ TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) {
InputHandlerScrollResult result =
host_impl_->ScrollBy(UpdateState(scroll_position, delta).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), overflow->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), result.current_offset);
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), result.current_visual_offset);
gfx::Vector2dF initial_offset, target_offset;
EXPECT_TRUE(host_impl_->GetSnapFlingInfo(gfx::Vector2dF(10, 10),
@@ -2589,8 +2602,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 1234);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
@@ -3532,7 +3544,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->DidBecomeActive();
host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain();
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
DrawFrame();
@@ -4884,11 +4896,9 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
bool tile_missing,
bool had_incomplete_tile,
bool animating,
- ResourceProvider* resource_provider,
scoped_refptr<AnimationTimeline> timeline) {
return base::WrapUnique(new MissingTextureAnimatingLayer(
- tree_impl, id, tile_missing, had_incomplete_tile, animating,
- resource_provider, timeline));
+ tree_impl, id, tile_missing, had_incomplete_tile, animating, timeline));
}
void AppendQuads(viz::RenderPass* render_pass,
@@ -4906,7 +4916,6 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
bool tile_missing,
bool had_incomplete_tile,
bool animating,
- ResourceProvider* resource_provider,
scoped_refptr<AnimationTimeline> timeline)
: DidDrawCheckLayer(tree_impl, id),
tile_missing_(tile_missing),
@@ -4946,8 +4955,7 @@ static void CreateLayerFromState(
static int layer_id = 2;
root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create(
root->layer_tree_impl(), layer_id++, state.has_missing_tile,
- state.has_incomplete_tile, state.is_animating,
- root->layer_tree_impl()->resource_provider(), timeline));
+ state.has_incomplete_tile, state.is_animating, timeline));
auto* layer =
static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
if (state.has_copy_request)
@@ -6692,9 +6700,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) {
EXPECT_EQ(gfx::ScrollOffset(0, 50), child_layer->CurrentScrollOffset());
host_impl_->DidFinishImplFrame();
- // Second ScrollAnimated should still latch to the grand_child_layer.
+ // Second ScrollAnimated should still latch to the grand_child_layer. Since it
+ // is already at its extent and no scrolling happens, the scroll result must
+ // be ignored.
EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
+ InputHandler::SCROLL_IGNORED,
host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, -100)).thread);
begin_frame_args.frame_time =
@@ -8364,15 +8374,10 @@ class BlendStateCheckLayer : public LayerImpl {
quads_appended_(false),
quad_rect_(5, 5, 5, 5),
quad_visible_rect_(5, 5, 5, 5) {
- if (tree_impl->context_provider()) {
- resource_id_ = resource_provider->CreateGpuTextureResource(
- gfx::Size(1, 1), viz::ResourceTextureHint::kDefault, viz::RGBA_8888,
- gfx::ColorSpace());
- } else {
- resource_id_ = resource_provider->CreateBitmapResource(
- gfx::Size(1, 1), gfx::ColorSpace(), viz::RGBA_8888);
- }
- resource_provider->AllocateForTesting(resource_id_);
+ resource_id_ = resource_provider->ImportResource(
+ viz::TransferableResource::MakeSoftware(
+ viz::SharedBitmap::GenerateId(), gfx::Size(1, 1), viz::RGBA_8888),
+ viz::SingleReleaseCallback::Create(base::DoNothing()));
SetBounds(gfx::Size(10, 10));
SetDrawsContent(true);
}
@@ -9053,10 +9058,11 @@ class FakeDrawableLayerImpl : public LayerImpl {
// submitted to the LayerTreeFrameSink, where it should request to swap only
// the sub-buffer that is damaged.
TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_have_post_sub_buffer(true);
scoped_refptr<viz::TestContextProvider> context_provider(
- viz::TestContextProvider::Create());
+ viz::TestContextProvider::Create(std::move(gl_owned)));
context_provider->BindToCurrentThread();
- context_provider->TestContext3d()->set_have_post_sub_buffer(true);
std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink(
FakeLayerTreeFrameSink::Create3d(context_provider));
@@ -9090,7 +9096,7 @@ 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()->set_local_surface_id(
+ layer_tree_host_impl->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
TestFrameData frame;
@@ -9190,11 +9196,10 @@ class FakeLayerWithQuads : public LayerImpl {
};
TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ viz::TestGLES2Interface* gl = gl_owned.get();
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink(
- FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
std::unique_ptr<LayerImpl> root_layer =
@@ -9215,27 +9220,21 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
- EXPECT_GT(context3d->NumTextures(), 0u);
+ EXPECT_GT(gl->NumTextures(), 0u);
// Kill the layer tree.
host_impl_->active_tree()->DetachLayers();
// There should be no textures left in use after.
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
}
-class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
- public:
- MOCK_METHOD1(useProgram, void(GLuint program));
- MOCK_METHOD4(drawElements,
- void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
-};
TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
@@ -9548,8 +9547,7 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) {
AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr);
// Gpu compositing.
- layer_tree_frame_sink_ =
- FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create());
+ layer_tree_frame_sink_ = FakeLayerTreeFrameSink::Create3d();
host_impl_->SetVisible(true);
host_impl_->InitializeRenderer(layer_tree_frame_sink_.get());
{
@@ -9712,58 +9710,58 @@ TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) {
}
TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ viz::TestGLES2Interface* gl = gl_owned.get();
+
std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink =
- FakeLayerTreeFrameSink::Create3d();
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned));
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
UIResourceId ui_resource_id = 1;
bool is_opaque = false;
UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
// Multiple requests with the same id is allowed. The previous texture is
// deleted.
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id2);
EXPECT_NE(id1, id2);
// Deleting invalid UIResourceId is allowed and does not change state.
host_impl_->DeleteUIResource(-1);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
// Should return zero for invalid UIResourceId. Number of textures should
// not change.
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
host_impl_->DeleteUIResource(ui_resource_id);
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
// Should not change state for multiple deletion on one UIResourceId
host_impl_->DeleteUIResource(ui_resource_id);
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
}
TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
- context3d->set_support_compressed_texture_etc1(true);
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_support_compressed_texture_etc1(true);
+ viz::TestGLES2Interface* gl = gl_owned.get();
+
CreateHostImpl(DefaultSettings(),
- FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
gfx::Size size(4, 4);
// SkImageInfo has no support for ETC1. The |info| below contains the right
@@ -9776,7 +9774,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
UIResourceBitmap bitmap(std::move(pixel_ref), size);
UIResourceId ui_resource_id = 1;
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
}
@@ -9854,9 +9852,8 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
constexpr double refresh_rate = 60.0;
auto layer_tree_frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
context_provider, viz::TestContextProvider::CreateWorker(), nullptr,
- nullptr, viz::RendererSettings(),
- base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite,
- disable_display_vsync, refresh_rate);
+ viz::RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
layer_tree_frame_sink->SetClient(&test_client);
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
@@ -10257,8 +10254,7 @@ TEST_F(LayerTreeHostImplLatencyInfoRendererTest,
// component attached via LatencyInfoSwapPromise.
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
@@ -10313,8 +10309,7 @@ TEST_F(LayerTreeHostImplLatencyInfoUITest,
// component attached via LatencyInfoSwapPromise.
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
@@ -11626,6 +11621,52 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) {
EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
}
+// TODO(gyuyoung): OnMemoryPressure disabled on ASAN, TSAN, Android, windows
+// due to the test failure. Will be handled on
+// http://crbug.com/839687.
+#if defined(OS_WIN) || defined(OS_ANDROID) || defined(ADDRESS_SANITIZER) || \
+ defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
+ defined(LEAK_SANITIZER)
+#define MAYBE_OnMemoryPressure DISABLED_OnMemoryPressure
+#else
+#define MAYBE_OnMemoryPressure OnMemoryPressure
+#endif
+
+TEST_F(LayerTreeHostImplTest, MAYBE_OnMemoryPressure) {
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableLowEndDeviceMode);
+
+ const gfx::Size viewport_size(100, 100);
+ host_impl_->SetViewportSize(viewport_size);
+ host_impl_->CreatePendingTree();
+ scoped_refptr<FakeRasterSource> raster_source(
+ FakeRasterSource::CreateFilled(viewport_size));
+ std::unique_ptr<FakePictureLayerImpl> layer(
+ FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
+ 11, raster_source));
+ layer->SetBounds(viewport_size);
+ layer->SetDrawsContent(true);
+ host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+ host_impl_->ActivateSyncTree();
+ const gfx::Transform draw_transform;
+ host_impl_->OnDraw(draw_transform, gfx::Rect(viewport_size), false);
+
+ std::unique_ptr<base::ProcessMetrics> metric(
+ base::ProcessMetrics::CreateCurrentProcessMetrics());
+ size_t current_memory_usage = metric->GetMallocUsage();
+
+ base::MemoryPressureListener::SimulatePressureNotification(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+ base::RunLoop().RunUntilIdle();
+
+ size_t memory_usage_after_memory_pressure = metric->GetMallocUsage();
+
+ // Memory usage after the memory pressure should be less than previous one.
+ EXPECT_LT(memory_usage_after_memory_pressure, current_memory_usage);
+ EXPECT_FALSE(host_impl_->use_gpu_rasterization());
+}
+
// We will force the touch event handler to be passive if we touch on a layer
// which is the current scrolling layer.
TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) {
@@ -13464,8 +13505,7 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnLayerTreeFrameSinkChange) {
host_impl_->SetVisible(true);
// InitializeRenderer with a gpu-raster enabled output surface.
- auto gpu_raster_layer_tree_frame_sink =
- FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create());
+ auto gpu_raster_layer_tree_frame_sink = FakeLayerTreeFrameSink::Create3d();
host_impl_->InitializeRenderer(gpu_raster_layer_tree_frame_sink.get());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
@@ -13743,7 +13783,10 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_size);
PaintImage checkerable_image =
- CreateDiscardablePaintImage(gfx::Size(500, 500));
+ PaintImageBuilder::WithCopy(
+ CreateDiscardablePaintImage(gfx::Size(500, 500)))
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
+ .TakePaintImage();
recording_source->add_draw_image(checkerable_image, gfx::Point(0, 0));
SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
@@ -13773,6 +13816,11 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) {
root->SetDrawsContent(true);
pending_tree->BuildPropertyTreesForTesting();
+ // Update the decoding state map for the tracker so it knows the correct
+ // decoding preferences for the image.
+ host_impl_->tile_manager()->checker_image_tracker().UpdateImageDecodingHints(
+ raster_source->TakeDecodingModeMap());
+
// CompleteCommit which should perform a PrepareTiles, adding tilings for the
// root layer, each one having a raster task.
host_impl_->CommitComplete();
@@ -14251,5 +14299,211 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
EXPECT_TRUE(selection_2.end.visible());
}
+// Tests ScrollBy() to see if the method sets the scroll tree's currently
+// scrolling node and the ScrollState properly.
+TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) {
+ SetupScrollAndContentsLayers(gfx::Size(100, 100));
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ // Create a ScrollState object with no scrolling element.
+ ScrollStateData scroll_state_data;
+ scroll_state_data.set_current_native_scrolling_element(ElementId());
+ std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data));
+
+ ScrollTree& scroll_tree =
+ host_impl_->active_tree()->property_trees()->scroll_tree;
+
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point()).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
+
+ ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+ EXPECT_TRUE(scroll_node);
+
+ host_impl_->ScrollBy(scroll_state.get());
+
+ // Check to see the scroll tree's currently scrolling node is
+ // still the same. |scroll_state|'s scrolling node should match
+ // it.
+ EXPECT_EQ(scroll_node, scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_node(),
+ scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_element(),
+ scroll_tree.CurrentlyScrollingNode()->element_id);
+
+ // Set the scroll tree's currently scrolling node to null. Calling
+ // ScrollBy() should set the node to the one inside |scroll_state|.
+ host_impl_->active_tree()->SetCurrentlyScrollingNode(nullptr);
+ EXPECT_FALSE(scroll_tree.CurrentlyScrollingNode());
+
+ host_impl_->ScrollBy(scroll_state.get());
+
+ EXPECT_EQ(scroll_node, scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_node(),
+ scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_element(),
+ scroll_tree.CurrentlyScrollingNode()->element_id);
+}
+
+class HitTestRegionListGeneratingLayerTreeHostImplTest
+ : public LayerTreeHostImplTest {
+ public:
+ bool CreateHostImpl(
+ const LayerTreeSettings& settings,
+ std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) override {
+ // Enable hit test data generation with the CompositorFrame.
+ LayerTreeSettings new_settings = settings;
+ new_settings.build_hit_test_data = true;
+ return CreateHostImplWithTaskRunnerProvider(
+ new_settings, std::move(layer_tree_frame_sink), &task_runner_provider_);
+ }
+};
+
+// When disabled, no HitTestRegionList should be generated.
+// Test to ensure that hit test data is created correctly from the active layer
+// tree.
+TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) {
+ // Setup surface layers in LayerTreeHostImpl.
+ host_impl_->CreatePendingTree();
+ host_impl_->ActivateSyncTree();
+ host_impl_->SetViewportSize(gfx::Size(1024, 768));
+
+ std::unique_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl_->active_tree(), 1);
+ std::unique_ptr<SurfaceLayerImpl> surface_child =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 3);
+
+ surface_child->SetPosition(gfx::PointF(50, 50));
+ surface_child->SetBounds(gfx::Size(100, 100));
+ surface_child->SetDrawsContent(true);
+ surface_child->SetSurfaceHitTestable(true);
+
+ root->test_properties()->AddChild(std::move(surface_child));
+ host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list =
+ host_impl_->BuildHitTestData();
+ EXPECT_FALSE(hit_test_region_list);
+}
+
+// Test to ensure that hit test data is created correctly from the active layer
+// tree.
+TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) {
+ // Setup surface layers in LayerTreeHostImpl.
+ host_impl_->CreatePendingTree();
+ host_impl_->ActivateSyncTree();
+
+ // The structure of the layer tree:
+ // +-Root (1024x768)
+ // +---intermediate_layer (200, 300), 200x200
+ // +-----surface_child1 (50, 50), 100x100, Rotate(45)
+ // +---surface_child2 (450, 300), 100x100
+ // +---overlapping_layer (500, 350), 200x200
+ std::unique_ptr<LayerImpl> intermediate_layer =
+ LayerImpl::Create(host_impl_->active_tree(), 2);
+ std::unique_ptr<SurfaceLayerImpl> surface_child1 =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 3);
+ std::unique_ptr<SurfaceLayerImpl> surface_child2 =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 4);
+ std::unique_ptr<LayerImpl> overlapping_layer =
+ LayerImpl::Create(host_impl_->active_tree(), 5);
+
+ host_impl_->SetViewportSize(gfx::Size(1024, 768));
+
+ intermediate_layer->SetPosition(gfx::PointF(200, 300));
+ intermediate_layer->SetBounds(gfx::Size(200, 200));
+
+ surface_child1->SetPosition(gfx::PointF(50, 50));
+ surface_child1->SetBounds(gfx::Size(100, 100));
+ gfx::Transform rotate;
+ rotate.Rotate(45);
+ surface_child1->test_properties()->transform = rotate;
+ surface_child1->SetDrawsContent(true);
+ surface_child1->SetSurfaceHitTestable(true);
+
+ surface_child2->SetPosition(gfx::PointF(450, 300));
+ surface_child2->SetBounds(gfx::Size(100, 100));
+ surface_child2->SetDrawsContent(true);
+ surface_child2->SetSurfaceHitTestable(true);
+
+ overlapping_layer->SetPosition(gfx::PointF(500, 350));
+ overlapping_layer->SetBounds(gfx::Size(200, 200));
+ overlapping_layer->SetDrawsContent(true);
+
+ viz::LocalSurfaceId child_local_surface_id(2,
+ base::UnguessableToken::Create());
+ viz::FrameSinkId frame_sink_id(2, 0);
+ viz::SurfaceId child_surface_id(frame_sink_id, child_local_surface_id);
+ surface_child1->SetPrimarySurfaceId(child_surface_id, base::nullopt);
+ surface_child2->SetPrimarySurfaceId(child_surface_id, base::nullopt);
+
+ std::unique_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl_->active_tree(), 1);
+ host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
+ intermediate_layer->test_properties()->AddChild(std::move(surface_child1));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(intermediate_layer));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(surface_child2));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(overlapping_layer));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ constexpr gfx::Rect kFrameRect(0, 0, 1024, 768);
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list =
+ host_impl_->BuildHitTestData();
+ // Generating HitTestRegionList should have been enabled for this test.
+ ASSERT_TRUE(hit_test_region_list);
+
+ // Since surface_child2 draws in front of surface_child1, it should also be in
+ // the front of the hit test region list.
+ uint32_t expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestMine;
+ EXPECT_EQ(expected_flags, hit_test_region_list->flags);
+ EXPECT_EQ(kFrameRect, hit_test_region_list->bounds);
+ EXPECT_EQ(2u, hit_test_region_list->regions.size());
+
+ EXPECT_EQ(child_surface_id.frame_sink_id(),
+ hit_test_region_list->regions[1].frame_sink_id);
+ expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestChildSurface;
+ EXPECT_EQ(expected_flags, hit_test_region_list->regions[1].flags);
+ gfx::Transform child1_transform;
+ child1_transform.Rotate(-45);
+ child1_transform.Translate(-250, -350);
+ EXPECT_TRUE(child1_transform.ApproximatelyEqual(
+ hit_test_region_list->regions[1].transform));
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ hit_test_region_list->regions[1].rect.ToString());
+
+ EXPECT_EQ(child_surface_id.frame_sink_id(),
+ hit_test_region_list->regions[0].frame_sink_id);
+ expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestChildSurface |
+ viz::HitTestRegionFlags::kHitTestAsk;
+ EXPECT_EQ(expected_flags, hit_test_region_list->regions[0].flags);
+ gfx::Transform child2_transform;
+ child2_transform.Translate(-450, -300);
+ EXPECT_TRUE(child2_transform.ApproximatelyEqual(
+ hit_test_region_list->regions[0].transform));
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ hit_test_region_list->regions[0].rect.ToString());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 92765547065..871e1a10a17 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -59,9 +59,8 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
return std::make_unique<viz::TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
- refresh_rate);
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
}
void BeginTest() override {
@@ -140,7 +139,8 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
void ReadTestFile(const std::string& name) {
base::FilePath test_data_dir;
- ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
+ ASSERT_TRUE(
+ base::PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
}
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index c0706014c1a..378d4338879 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -37,8 +37,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
-#if defined(OS_WIN)
- // Windows has 436 pixels off by 1: crbug.com/259915
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
+ // Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
@@ -79,9 +79,14 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
5.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
// Windows has 5.9325% pixels by at most 2: crbug.com/259922
float percentage_pixels_large_error = 6.0f;
+#else
+ // Loongson has 8.685% pixels by at most 2: crbug.com/819110
+ float percentage_pixels_large_error = 8.7f;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 2.f;
int large_error_allowed = 2;
@@ -141,12 +146,17 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 116 pixels off by at most 2: crbug.com/225027
float percentage_pixels_large_error = 0.3f; // 116px / (200*200), rounded up
+ int large_error_allowed = 2;
+#else
+ float percentage_pixels_large_error = 0.25f; // 96px / (200*200), rounded up
+ int large_error_allowed = 1;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 2;
int small_error_allowed = 0;
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
@@ -414,12 +424,21 @@ class ImageScaledBackgroundFilter : public LayerTreeHostFiltersPixelTest {
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
filter->SetBackgroundFilters(filters);
+#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 153 pixels off by at most 2: crbug.com/225027
float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
+ int large_error_allowed = 2;
+#elif defined(_MIPS_ARCH_LOONGSON)
+ // Loongson has 2 pixels off by at most 2: crbug.com/819075
+ float percentage_pixels_large_error = 0.005f; // 2px / (200*200)
+ int large_error_allowed = 2;
+#else
+ float percentage_pixels_large_error = 0.0325f; // 13px / (200*200)
+ int large_error_allowed = 1;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 2;
int small_error_allowed = 0;
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
@@ -726,8 +745,8 @@ class RotatedDropShadowFilterTest : public LayerTreeHostFiltersPixelTest {
background->AddChild(child);
-#if defined(OS_WIN)
- // Windows has 3 pixels off by 1: crbug.com/259915
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
+ // Windows and ARM64 have 3 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 0.00333334f; // 3px / (300*300)
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
@@ -941,9 +960,15 @@ class BlurFilterWithClip : public LayerTreeHostFiltersPixelTest {
// Force the allocation a larger textures.
set_enlarge_texture_amount(gfx::Size(50, 50));
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 1880 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 4.7f; // 1880px / (200*200)
+#else
+ // Differences in floating point calculation on ARM means a small percentage
+ // of pixels will have small differences.
+ float percentage_pixels_large_error = 2.76f; // 1104px / (200*200)
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
int large_error_allowed = 2;
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 02e0e7bf246..6a6cfa4d11e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -312,13 +312,13 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
float average_error_allowed_in_bad_pixels = 100.0f;
int large_error_allowed = 256;
int small_error_allowed = 0;
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
true, // discard_alpha
percentage_pixels_large_error,
percentage_pixels_small_error,
average_error_allowed_in_bad_pixels,
large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
RunPixelResourceTest(background,
base::FilePath(
@@ -363,13 +363,13 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
float average_error_allowed_in_bad_pixels = 256.0f;
int large_error_allowed = 256;
int small_error_allowed = 0;
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
true, // discard_alpha
percentage_pixels_large_error,
percentage_pixels_small_error,
average_error_allowed_in_bad_pixels,
large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
RunPixelResourceTest(background,
base::FilePath(
@@ -428,13 +428,21 @@ class LayerTreeHostMaskAsBlendingPixelTest
average_error_allowed_in_bad_pixels = 3.5f;
large_error_allowed = 15;
small_error_allowed = 1;
+ } else {
+#if defined(ARCH_CPU_ARM64)
+ // Differences in floating point calculation on ARM means a small
+ // percentage of pixels will be off by 1.
+ percentage_pixels_error = 0.112f;
+ average_error_allowed_in_bad_pixels = 1.f;
+ large_error_allowed = 1;
+#endif
}
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
false, // discard_alpha
percentage_pixels_error, percentage_pixels_small_error,
average_error_allowed_in_bad_pixels, large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
}
static scoped_refptr<Layer> CreateCheckerboardLayer(const gfx::Size& bounds) {
@@ -714,6 +722,59 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
"mask_as_blending_rotated_circle_underflow.png")));
}
+TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
+ MaskOfLayerWithBackgroundFilterAndBlend) {
+ scoped_refptr<SolidColorLayer> background =
+ CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE);
+
+ gfx::Size picture_bounds(128, 128);
+ CheckerContentLayerClient picture_client_vertical(picture_bounds,
+ SK_ColorGREEN, true);
+ scoped_refptr<PictureLayer> picture_vertical =
+ PictureLayer::Create(&picture_client_vertical);
+ picture_vertical->SetBounds(picture_bounds);
+ picture_vertical->SetIsDrawable(true);
+
+ CheckerContentLayerClient picture_client_horizontal(picture_bounds,
+ SK_ColorMAGENTA, false);
+ scoped_refptr<PictureLayer> picture_horizontal =
+ PictureLayer::Create(&picture_client_horizontal);
+ picture_horizontal->SetBounds(picture_bounds);
+ picture_horizontal->SetIsDrawable(true);
+ picture_horizontal->SetContentsOpaque(false);
+ picture_horizontal->SetBlendMode(SkBlendMode::kMultiply);
+
+ FilterOperations filters;
+ filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
+ picture_horizontal->SetBackgroundFilters(filters);
+
+ background->AddChild(picture_vertical);
+ background->AddChild(picture_horizontal);
+
+ gfx::Size mask_bounds(128, 128);
+ CircleContentLayerClient mask_client(mask_bounds);
+ scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
+ mask->SetBounds(mask_bounds);
+ mask->SetIsDrawable(true);
+ mask->SetLayerMaskType(mask_type_);
+ picture_horizontal->SetMaskLayer(mask.get());
+
+ float percentage_pixels_large_error = 0.062f; // 0.062%, ~10px / (128*128)
+ float percentage_pixels_small_error = 0.0f;
+ float average_error_allowed_in_bad_pixels = 200.0f;
+ int large_error_allowed = 256;
+ int small_error_allowed = 0;
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
+ true, // discard_alpha
+ percentage_pixels_large_error, percentage_pixels_small_error,
+ average_error_allowed_in_bad_pixels, large_error_allowed,
+ small_error_allowed);
+
+ RunPixelResourceTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "mask_of_background_filter_and_blend.png")));
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index a4f98ae353a..b251df562ab 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -150,7 +150,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, HugeTransformScale) {
background->AddChild(layer);
scoped_refptr<TestInProcessContextProvider> context(
- new TestInProcessContextProvider(nullptr, false));
+ new TestInProcessContextProvider(/*enable_oop_rasterization=*/false));
context->BindToCurrentThread();
int max_texture_size = 0;
context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index bf42914b95d..eabe1909a4f 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -60,13 +60,13 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest {
case PARTIAL_GPU_LOW_BIT_DEPTH:
settings->gpu_rasterization_forced = true;
settings->use_partial_raster = true;
- settings->preferred_tile_format = viz::RGBA_4444;
+ settings->use_rgba_4444 = true;
settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
break;
case FULL_GPU_LOW_BIT_DEPTH:
settings->gpu_rasterization_forced = true;
settings->use_partial_raster = false;
- settings->preferred_tile_format = viz::RGBA_4444;
+ settings->use_rgba_4444 = true;
settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
break;
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index acbd577abcd..e66bf23fa85 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -65,6 +65,7 @@
#include "components/viz/service/display/output_surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -460,14 +461,14 @@ class LayerTreeHostContextCacheTest : public LayerTreeHostTest {
// Create the main viz::ContextProvider with a MockContextSupport.
auto main_support = std::make_unique<MockContextSupport>();
mock_main_context_support_ = main_support.get();
- auto test_main_context_provider = viz::TestContextProvider::Create(
- viz::TestWebGraphicsContext3D::Create(), std::move(main_support));
+ auto test_main_context_provider =
+ viz::TestContextProvider::Create(std::move(main_support));
// Create the main viz::ContextProvider with a MockContextSupport.
auto worker_support = std::make_unique<MockContextSupport>();
mock_worker_context_support_ = worker_support.get();
- auto test_worker_context_provider = viz::TestContextProvider::CreateWorker(
- viz::TestWebGraphicsContext3D::Create(), std::move(worker_support));
+ auto test_worker_context_provider =
+ viz::TestContextProvider::CreateWorker(std::move(worker_support));
// At init, visibility is set to true, so SetAggressivelyFreeResources will
// be disabled.
@@ -563,7 +564,8 @@ class LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous
}
};
-SINGLE_AND_MULTI_THREAD_TEST_F(
+// Android Webview only runs in multi-threaded compositing mode.
+MULTI_THREAD_TEST_F(
LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous);
// Test if the LTH successfully frees main and worker resources when the
@@ -1231,9 +1233,12 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
}
}
+ void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ PostSetNeedsCommitToMainThread();
+ }
+
void DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl* impl) override {
int frame_number = impl->active_tree()->source_frame_number();
-
// Frames 0 and 1 invalidate because the early damage check is not enabled
// during this setup. But frames 1 and 2 are not damaged, so the early
// check should prevent frame 2 from invalidating.
@@ -1250,8 +1255,6 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
EndTest();
return;
}
-
- PostSetNeedsCommitToMainThread();
}
void AfterTest() override {
@@ -1269,9 +1272,7 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
// This behavior is specific to Android WebView, which only uses
// multi-threaded compositor.
-// Flaky on Win7 Tests (dbg)(1). https://crbug.com/813578
-// Flaky on linux_chromium_tsan_rel_ng. https://crbug.com/822473
-// MULTI_THREAD_TEST_F(LayerTreeHostTestEarlyDamageCheckStops);
+MULTI_THREAD_TEST_F(LayerTreeHostTestEarlyDamageCheckStops);
// Verify CanDraw() is false until first commit.
class LayerTreeHostTestCantDrawBeforeCommit : public LayerTreeHostTest {
@@ -2241,7 +2242,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());
+ layer_tree_host()->local_surface_id_from_parent());
break;
default:
// No extra commits.
@@ -2286,7 +2287,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());
+ layer_tree_host()->local_surface_id_from_parent());
}
}
@@ -3811,7 +3812,6 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
OnDrawLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const viz::RendererSettings& renderer_settings,
base::SingleThreadTaskRunner* task_runner,
@@ -3820,7 +3820,6 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
base::Closure invalidate_callback)
: TestLayerTreeFrameSink(std::move(compositor_context_provider),
std::move(worker_context_provider),
- shared_bitmap_manager,
gpu_memory_buffer_manager,
renderer_settings,
task_runner,
@@ -3862,8 +3861,8 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
base::Unretained(this));
auto frame_sink = std::make_unique<OnDrawLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), false /* synchronous_composite */, refresh_rate,
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ false /* synchronous_composite */, refresh_rate,
std::move(on_draw_callback));
layer_tree_frame_sink_ = frame_sink.get();
return std::move(frame_sink);
@@ -5710,19 +5709,22 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
void SetVisibleFalseAndQueueSwapPromise() {
layer_tree_host()->SetVisible(false);
- std::unique_ptr<SwapPromise> swap_promise(
- new TestSwapPromise(&swap_promise_result_));
+ auto swap_promise =
+ std::make_unique<TestSwapPromise>(&swap_promise_result_);
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise));
}
void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
const viz::BeginFrameArgs& args) override {
- MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
- SetVisibleFalseAndQueueSwapPromise,
- base::Unretained(this)));
+ if (!sent_queue_request_) {
+ sent_queue_request_ = true;
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
+ SetVisibleFalseAndQueueSwapPromise,
+ base::Unretained(this)));
+ }
}
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
@@ -5742,11 +5744,10 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
}
TestSwapPromiseResult swap_promise_result_;
+ bool sent_queue_request_ = false;
};
-// Flaky: https://crbug.com/657910
-// SINGLE_AND_MULTI_THREAD_TEST_F(
-// LayerTreeHostTestBreakSwapPromiseForVisibility);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
public:
@@ -5895,41 +5896,43 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
LayerTreeHostTest::SetupTree();
ui_resource_ =
FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
- client_.set_bounds(layer_tree_host()->root_layer()->bounds());
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ if (TestEnded())
+ return;
+
host_impl->EvictAllUIResources();
// Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
// mode. Active tree should require high-res to draw after entering this
// mode to ensure that high-res tiles are also required for a pending tree
// to be activated.
EXPECT_TRUE(host_impl->RequiresHighResToDraw());
+
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &LayerTreeHostTestHighResRequiredAfterEvictingUIResources::
+ DeleteResourceAndEndTest,
+ base::Unretained(this)));
}
- void DidCommit() override {
- int frame = layer_tree_host()->SourceFrameNumber();
- switch (frame) {
- case 1:
- PostSetNeedsCommitToMainThread();
- break;
- case 2:
- ui_resource_ = nullptr;
- EndTest();
- break;
- }
+ void DeleteResourceAndEndTest() {
+ // This must be destroyed before the test ends and tears down the
+ // LayerTreeHost. It causes another commit+activation though, which
+ // may run before the test exits.
+ ui_resource_ = nullptr;
+ EndTest();
}
void AfterTest() override {}
- FakeContentLayerClient client_;
std::unique_ptr<FakeScopedUIResource> ui_resource_;
};
-// This test is flaky, see http://crbug.com/386199
-// MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
+MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
protected:
@@ -6323,10 +6326,6 @@ class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
: will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
void BeginTest() override {
- // Test terminates when a main frame is no longer expected so request that
- // this message is actually sent.
- layer_tree_host()->RequestBeginMainFrameNotExpected(true);
-
PostSetNeedsCommitToMainThread();
}
@@ -6341,27 +6340,20 @@ class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
did_finish_impl_frame_count_++;
EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
- // Request a number of commits to cause multiple impl frames. We expect to
- // get one more impl frames than the number of commits requested because
- // after a commit it takes one frame to become idle.
- if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
- PostSetNeedsCommitToMainThread();
+ // Trigger a new impl frame until we are done testing.
+ if (did_finish_impl_frame_count_ < kExpectedNumImplFrames)
+ PostSetNeedsRedrawToMainThread();
+ else
+ EndTest();
}
- void BeginMainFrameNotExpectedSoon() override { EndTest(); }
-
void AfterTest() override {
EXPECT_GT(will_begin_impl_frame_count_, 0);
EXPECT_GT(did_finish_impl_frame_count_, 0);
EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
- // TODO(mithro): Figure out why the multithread version of this test
- // sometimes has one more frame then expected. Possibly related to
- // http://crbug.com/443185
- if (!HasImplThread()) {
- EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
- EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
- }
+ EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
+ EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
}
private:
@@ -6593,9 +6585,8 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
return std::make_unique<viz::TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
- refresh_rate);
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
}
void BeginTest() override {
@@ -7400,478 +7391,6 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
-class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 50x50, but it has a child that causes
- // the surface bounds to be larger. It also has a parent that clips the
- // masked layer and its surface.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size layer_size(100, 100);
- content_layer->SetBounds(layer_size);
-
- gfx::Size mask_size(100, 100);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
- mask_layer_id_ = mask_layer->id();
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
- outer_viewport_scroll_layer->SetBounds(layer_size);
- CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer,
- gfx::Size(50, 50), gfx::Size(50, 50),
- layer_tree_host());
- layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true);
- outer_viewport_scroll_layer->AddChild(content_layer);
-
- client_.set_bounds(root->bounds());
- outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
- 50.f / texture_size.width(), 50.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin);
-
-class LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin);
-
-class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 50x50, but it has a child that causes
- // the surface bounds to be larger. It also has a parent that clips the
- // masked layer and its surface.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<Layer> clipping_layer = Layer::Create();
- root->AddChild(clipping_layer);
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- clipping_layer->AddChild(content_layer);
-
- scoped_refptr<FakePictureLayer> content_child_layer =
- FakePictureLayer::Create(&client_);
- content_layer->AddChild(content_child_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::PointF clipping_origin(20.f, 10.f);
- gfx::Size clipping_size(10, 20);
- clipping_layer->SetBounds(clipping_size);
- clipping_layer->SetPosition(clipping_origin);
- clipping_layer->SetMasksToBounds(true);
-
- gfx::Size layer_size(50, 50);
- content_layer->SetBounds(layer_size);
- content_layer->SetPosition(gfx::PointF() -
- clipping_origin.OffsetFromOrigin());
-
- gfx::Size child_size(50, 50);
- content_child_layer->SetBounds(child_size);
- content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
-
- gfx::Size mask_size(50, 50);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
- mask_layer_id_ = mask_layer->id();
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- // The surface is clipped to 10x20.
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
- render_pass_quad->rect.ToString());
- // The masked layer is 50x50, but the surface size is 10x20. So the texture
- // coords in the mask are scaled by 10/50 and 20/50.
- // The surface is clipped to (20,10) so the mask texture coords are offset
- // by 20/50 and 10/50
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
- 10.f / texture_size.width(), 20.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer);
-
-class LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer);
-
-class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // Root
- // |
- // +-- Scaling Layer (adds a 2x scale)
- // |
- // +-- Content Layer
- // +--Mask
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<Layer> scaling_layer = Layer::Create();
- root->AddChild(scaling_layer);
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- scaling_layer->AddChild(content_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 10), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 10, 100, 90), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size scaling_layer_size(50, 50);
- scaling_layer->SetBounds(scaling_layer_size);
- gfx::Transform scale;
- scale.Scale(2.f, 2.f);
- scaling_layer->SetTransform(scale);
-
- content_layer->SetBounds(scaling_layer_size);
-
- mask_layer->SetBounds(scaling_layer_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- // Check that the tree scaling is correctly taken into account for the
- // mask, that should fully map onto the quad.
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- break;
- case 1:
- // Applying a DSF should change the render surface size, but won't
- // affect which part of the mask is used.
- EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- break;
- }
- return draw_result;
- }
-
- void DidCommit() override {
- 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());
- break;
- }
- }
-
- void AfterTest() override {}
-
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerWithScaling
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestSingleTextureMaskLayerWithScaling);
-
-class LayerTreeTestMultiTextureMaskLayerWithScaling
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureMaskLayerWithScaling);
-
-class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 100x100, but is allocated a 120x150 texture.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- root->AddChild(content_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size layer_size(100, 100);
- content_layer->SetBounds(layer_size);
-
- gfx::Size mask_size(100, 100);
- gfx::Size mask_texture_size(120, 150);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
- mask_layer->set_fixed_tile_size(mask_texture_size);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- // The surface is 100x100
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
- render_pass_quad->rect.ToString());
- // The mask layer is 100x100, but is backed by a 120x150 image.
- EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize);
-
class LayerTreeTestPageScaleFlags : public LayerTreeTest {
protected:
void SetupTree() override {
@@ -7993,6 +7512,25 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
+// Makes sure that presentation-time requests are correctly propagated to the
+// frame's metadata.
+class LayerTreeHostTestPresentationTimeRequest : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override {
+ layer_tree_host()->RequestPresentationTimeForNextFrame(base::DoNothing());
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void DisplayReceivedCompositorFrameOnThread(
+ const viz::CompositorFrame& frame) override {
+ EXPECT_NE(0u, frame.metadata.presentation_token);
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTimeRequest);
+
// Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink.
class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
protected:
@@ -8001,7 +7539,7 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
}
void BeginTest() override {
- expected_local_surface_id_ = allocator_.GenerateId();
+ expected_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_);
}
@@ -8010,7 +7548,7 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
DrawResult draw_result) override {
EXPECT_EQ(DRAW_SUCCESS, draw_result);
EXPECT_EQ(expected_local_surface_id_,
- host_impl->active_tree()->local_surface_id());
+ host_impl->active_tree()->local_surface_id_from_parent());
return draw_result;
}
@@ -8025,9 +7563,56 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
viz::LocalSurfaceId expected_local_surface_id_;
viz::ParentLocalSurfaceIdAllocator allocator_;
};
-
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
+// Makes sure that viz::LocalSurfaceId allocation requests propagate all the way
+// to LayerTreeFrameSink.
+class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
+ protected:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_surface_synchronization = true;
+ }
+
+ void BeginTest() override {
+ expected_parent_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
+ PostSetLocalSurfaceIdToMainThread(expected_parent_local_surface_id_);
+ PostRequestNewLocalSurfaceIdToMainThread();
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ 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());
+ return draw_result;
+ }
+
+ void DisplayReceivedLocalSurfaceIdOnThread(
+ const viz::LocalSurfaceId& local_surface_id) override {
+ 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);
+ EXPECT_EQ(child_local_surface_id, local_surface_id);
+ }
+
+ // This gets called after DispllayReceivedLocalSurfaceIdOnThread.
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+ // Verify that the request bit doesn't stick after we submit a frame.
+ EXPECT_FALSE(
+ host_impl->active_tree()->new_local_surface_id_request_for_testing());
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ viz::LocalSurfaceId expected_parent_local_surface_id_;
+ viz::ParentLocalSurfaceIdAllocator allocator_;
+};
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestNewLocalSurfaceId);
+
// The GPU image decode controller hands images off to Skia for rasterization.
// When used with large images, the images in question could be deleted before
// Skia was done with them, causing a crash. This test performs an end-to-end
@@ -8144,6 +7729,20 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameMetadata);
class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
protected:
+ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ const viz::RendererSettings& renderer_settings,
+ double refresh_rate,
+ scoped_refptr<viz::ContextProvider> compositor_context_provider,
+ scoped_refptr<viz::RasterContextProvider> worker_context_provider)
+ override {
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_have_extension_egl_image(true);
+ auto provider = viz::TestContextProvider::Create(std::move(gl_owned));
+ return LayerTreeTest::CreateLayerTreeFrameSink(
+ renderer_settings, refresh_rate, std::move(provider),
+ std::move(worker_context_provider));
+ }
+
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
@@ -8154,15 +7753,12 @@ class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
viz::RenderPass* child_pass =
AddRenderPass(&frame->render_passes, 2, gfx::Rect(3, 3, 10, 10),
gfx::Transform(), FilterOperations());
- gpu::SyncToken mailbox_sync_token;
- AddOneOfEveryQuadType(child_pass, host_impl->resource_provider(), 0,
- &mailbox_sync_token);
+ AddOneOfEveryQuadType(child_pass, host_impl->resource_provider(), 0);
viz::RenderPass* pass =
AddRenderPass(&frame->render_passes, 1, gfx::Rect(3, 3, 10, 10),
gfx::Transform(), FilterOperations());
- AddOneOfEveryQuadType(pass, host_impl->resource_provider(), child_pass->id,
- &mailbox_sync_token);
+ AddOneOfEveryQuadType(pass, host_impl->resource_provider(), child_pass->id);
return draw_result;
}
@@ -8293,11 +7889,9 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override {
if (one_commit_done_)
return;
- EXPECT_TRUE(
+ EXPECT_FALSE(
impl->tile_manager()->checker_image_tracker().ShouldCheckerImage(
image_, WhichTree::PENDING_TREE));
- // Reset the tracker as if it has never seen this image.
- impl->tile_manager()->checker_image_tracker().ClearTracker(true);
}
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index f71c658c3fa..929c6658fe8 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -60,6 +60,9 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
content_layer_client_.set_fill_with_nonsolid_color(true);
PaintImage checkerable_image =
CreateDiscardablePaintImage(gfx::Size(450, 450));
+ checkerable_image = PaintImageBuilder::WithCopy(checkerable_image)
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
+ .TakePaintImage();
content_layer_client_.add_draw_image(checkerable_image, gfx::Point(0, 0),
PaintFlags());
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 024ca0204ab..f3ec645e85a 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -34,6 +34,7 @@
#include "cc/trees/single_thread_proxy.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/test/test_context_provider.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
@@ -56,7 +57,6 @@ class LayerTreeHostContextTest : public LayerTreeTest {
public:
LayerTreeHostContextTest()
: LayerTreeTest(),
- context3d_(nullptr),
times_to_fail_create_(0),
times_to_lose_during_commit_(0),
times_to_lose_during_draw_(0),
@@ -72,15 +72,15 @@ class LayerTreeHostContextTest : public LayerTreeTest {
void LoseContext() {
// CreateDisplayLayerTreeFrameSink happens on a different thread, so lock
- // context3d_ to make sure we don't set it to null after recreating it
+ // gl_ to make sure we don't set it to null after recreating it
// there.
- base::AutoLock lock(context3d_lock_);
+ base::AutoLock lock(gl_lock_);
// For sanity-checking tests, they should only call this when the
// context is not lost.
- CHECK(context3d_);
- context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
- context3d_ = nullptr;
+ CHECK(gl_);
+ gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
+ gl_ = nullptr;
}
std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
@@ -89,26 +89,26 @@ class LayerTreeHostContextTest : public LayerTreeTest {
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider)
override {
- base::AutoLock lock(context3d_lock_);
+ base::AutoLock lock(gl_lock_);
- std::unique_ptr<viz::TestWebGraphicsContext3D> compositor_context3d =
- viz::TestWebGraphicsContext3D::Create();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
if (context_should_support_io_surface_) {
- compositor_context3d->set_have_extension_io_surface(true);
- compositor_context3d->set_have_extension_egl_image(true);
+ gl_owned->set_have_extension_io_surface(true);
+ gl_owned->set_have_extension_egl_image(true);
}
- context3d_ = compositor_context3d.get();
+ gl_ = gl_owned.get();
+
+ auto provider = viz::TestContextProvider::Create(std::move(gl_owned));
if (times_to_fail_create_) {
--times_to_fail_create_;
ExpectCreateToFail();
- context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
+ gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
}
return LayerTreeTest::CreateLayerTreeFrameSink(
- renderer_settings, refresh_rate,
- viz::TestContextProvider::Create(std::move(compositor_context3d)),
+ renderer_settings, refresh_rate, std::move(provider),
std::move(worker_context_provider));
}
@@ -158,10 +158,10 @@ class LayerTreeHostContextTest : public LayerTreeTest {
void ExpectCreateToFail() { ++times_to_expect_create_failed_; }
protected:
- // Protects use of context3d_ so LoseContext and
+ // Protects use of gl_ so LoseContext and
// CreateDisplayLayerTreeFrameSink can both use it on different threads.
- base::Lock context3d_lock_;
- viz::TestWebGraphicsContext3D* context3d_;
+ base::Lock gl_lock_;
+ viz::TestGLES2Interface* gl_ = nullptr;
int times_to_fail_create_;
int times_to_lose_during_commit_;
@@ -887,7 +887,7 @@ class LayerTreeHostContextTestDontUseLostResources
shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
child_resource_provider_ =
FakeResourceProvider::CreateLayerTreeResourceProvider(
- child_context_provider_.get(), shared_bitmap_manager_.get());
+ child_context_provider_.get());
}
static void EmptyReleaseCallback(const gpu::SyncToken& sync_token,
@@ -1008,7 +1008,7 @@ class LayerTreeHostContextTestDontUseLostResources
if (host_impl->active_tree()->source_frame_number() == 2) {
// Lose the context after draw on the second commit. This will cause
// a third commit to recover.
- context3d_->set_times_bind_texture_succeeds(0);
+ gl_->set_times_bind_texture_succeeds(0);
}
return draw_result;
}
@@ -1042,7 +1042,7 @@ class LayerTreeHostContextTestDontUseLostResources
scoped_refptr<viz::TestContextProvider> child_context_provider_;
std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_;
- std::unique_ptr<ResourceProvider> child_resource_provider_;
+ std::unique_ptr<LayerTreeResourceProvider> child_resource_provider_;
scoped_refptr<VideoFrame> color_video_frame_;
scoped_refptr<VideoFrame> hw_video_frame_;
@@ -1345,8 +1345,9 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
UIResourceId test_id1_;
};
-// http://crbug.com/803532 : Flaky on Win 7 (dbg).
-#if defined(NDEBUG) || !defined(OS_WIN)
+// http://crbug.com/803532 : Flaky on Win 7 (dbg) and linux tsan
+#if (defined(NDEBUG) || !defined(OS_WIN)) && \
+ (!defined(THREAD_SANITIZER) || !defined(OS_LINUX))
SINGLE_THREAD_TEST_F(UIResourceLostBeforeCommit);
#endif
MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit);
@@ -1479,7 +1480,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, bool visible) override {
if (!visible) {
// All resources should have been evicted.
- ASSERT_EQ(0u, context3d_->NumTextures());
+ ASSERT_EQ(0u, gl_->NumTextures());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource3_->id()));
@@ -1499,7 +1500,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 1:
// The first two resources should have been created on LTHI after the
// commit.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1507,7 +1508,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
EXPECT_TRUE(impl->CanDraw());
// Evict all UI resources. This will trigger a commit.
impl->EvictAllUIResources();
- ASSERT_EQ(0u, context3d_->NumTextures());
+ ASSERT_EQ(0u, gl_->NumTextures());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1516,7 +1517,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
break;
case 2:
// The first two resources should have been recreated.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(2, ui_resource_->resource_create_count);
EXPECT_EQ(1, ui_resource_->lost_resource_count);
@@ -1528,7 +1529,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 3:
// The first resource should have been recreated after visibility was
// restored.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(3, ui_resource_->resource_create_count);
EXPECT_EQ(2, ui_resource_->lost_resource_count);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index edc62a8e36a..fcc95241448 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -1049,63 +1049,6 @@ class LayerTreeHostCopyRequestTestCreatesTexture
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestCreatesTexture);
-class LayerTreeHostCopyRequestTestProvideTexture
- : public LayerTreeHostCopyRequestTestCountTextures {
- protected:
- void BeginTest() override {
- external_context_provider_ = viz::TestContextProvider::Create();
- EXPECT_EQ(external_context_provider_->BindToCurrentThread(),
- gpu::ContextResult::kSuccess);
- LayerTreeHostCopyRequestTestCountTextures::BeginTest();
- }
-
- void CopyOutputCallback(std::unique_ptr<viz::CopyOutputResult> result) {
- EXPECT_FALSE(result->IsEmpty());
- EXPECT_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
- ASSERT_NE(nullptr, result->GetTextureResult());
-
- std::unique_ptr<viz::SingleReleaseCallback> release_callback =
- result->TakeTextureOwnership();
- ASSERT_TRUE(release_callback);
- release_callback->Run(gpu::SyncToken(), false);
- }
-
- void RequestCopy(Layer* layer) override {
- // Request a copy to a provided texture. This should not create a new
- // texture.
- std::unique_ptr<viz::CopyOutputRequest> request =
- std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
- base::BindOnce(
- &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback,
- base::Unretained(this)));
-
- gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL();
- gpu::Mailbox mailbox;
- gl->GenMailboxCHROMIUM(mailbox.name);
-
- gl->GenSyncTokenCHROMIUM(sync_token_.GetData());
-
- request->SetMailbox(mailbox, sync_token_);
- EXPECT_TRUE(request->has_mailbox());
-
- copy_layer_->RequestCopyOfOutput(std::move(request));
- }
-
- void AfterTest() override {
- // Expect the compositor to have waited for the sync point provided with the
- // mailbox.
- EXPECT_EQ(sync_token_, waited_sync_token_after_readback_);
- // Except the copy to have *not* made another texture.
- EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
- }
-
- scoped_refptr<viz::TestContextProvider> external_context_provider_;
- gpu::SyncToken sync_token_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestProvideTexture);
-
class LayerTreeHostCopyRequestTestDestroyBeforeCopy
: public LayerTreeHostCopyRequestTest {
protected:
diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
new file mode 100644
index 00000000000..b1615f0eb7e
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
@@ -0,0 +1,666 @@
+// 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/trees/layer_tree_host.h"
+
+#include "cc/test/fake_picture_layer.h"
+#include "cc/test/fake_recording_source.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "components/viz/common/quads/render_pass_draw_quad.h"
+
+namespace cc {
+namespace {
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
+ : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size layer_size(100, 100);
+ content_layer->SetBounds(layer_size);
+
+ gfx::Size mask_size(100, 100);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
+ outer_viewport_scroll_layer->SetBounds(layer_size);
+ CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer,
+ gfx::Size(50, 50), gfx::Size(50, 50),
+ layer_tree_host());
+ layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true);
+ outer_viewport_scroll_layer->AddChild(content_layer);
+
+ client_.set_bounds(root->bounds());
+ outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
+ rect_in_target_space.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
+ 50.f / texture_size.width(), 50.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> clipping_layer = Layer::Create();
+ root->AddChild(clipping_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ clipping_layer->AddChild(content_layer);
+
+ scoped_refptr<FakePictureLayer> content_child_layer =
+ FakePictureLayer::Create(&client_);
+ content_layer->AddChild(content_child_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::PointF clipping_origin(20.f, 10.f);
+ gfx::Size clipping_size(10, 20);
+ clipping_layer->SetBounds(clipping_size);
+ clipping_layer->SetPosition(clipping_origin);
+ clipping_layer->SetMasksToBounds(true);
+
+ gfx::Size layer_size(50, 50);
+ content_layer->SetBounds(layer_size);
+ content_layer->SetPosition(gfx::PointF() -
+ clipping_origin.OffsetFromOrigin());
+
+ gfx::Size child_size(50, 50);
+ content_child_layer->SetBounds(child_size);
+ content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
+
+ gfx::Size mask_size(50, 50);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is clipped to 10x20.
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
+ rect_in_target_space.ToString());
+ // The masked layer is 50x50, but the surface size is 10x20. So the texture
+ // coords in the mask are scaled by 10/50 and 20/50.
+ // The surface is clipped to (20,10) so the mask texture coords are offset
+ // by 20/50 and 10/50
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
+ 10.f / texture_size.width(), 20.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
+ : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> clipping_scaling_layer = Layer::Create();
+ root->AddChild(clipping_scaling_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ clipping_scaling_layer->AddChild(content_layer);
+
+ scoped_refptr<FakePictureLayer> content_child_layer =
+ FakePictureLayer::Create(&client_);
+ content_layer->AddChild(content_child_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Transform scale;
+ scale.Scale(2, 2);
+ gfx::PointF clipping_origin(20.f, 10.f);
+ gfx::Size clipping_size(10, 20);
+ clipping_scaling_layer->SetBounds(clipping_size);
+ clipping_scaling_layer->SetPosition(clipping_origin);
+ // This changes scale between contributing layer and render surface to 2.
+ clipping_scaling_layer->SetTransform(scale);
+ clipping_scaling_layer->SetMasksToBounds(true);
+
+ gfx::Size layer_size(50, 50);
+ content_layer->SetBounds(layer_size);
+ content_layer->SetPosition(gfx::PointF() -
+ clipping_origin.OffsetFromOrigin());
+
+ gfx::Size child_size(50, 50);
+ content_child_layer->SetBounds(child_size);
+ content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
+
+ gfx::Size mask_size(50, 50);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ // Setting will change transform on mask layer will make it not adjust
+ // raster scale, which will remain 1. This means the mask_layer and render
+ // surface will have a scale of 2 during draw time.
+ mask_layer->SetHasWillChangeTransformHint(true);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is clipped to 10x20, and then scaled by 2, which ends up
+ // being 20x40.
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(),
+ rect_in_target_space.ToString());
+ gfx::Rect visible_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->visible_rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(),
+ visible_rect_in_target_space.ToString());
+ // The masked layer is 50x50, but the surface size is 10x20. So the texture
+ // coords in the mask are scaled by 10/50 and 20/50.
+ // The surface is clipped to (20,10) so the mask texture coords are offset
+ // by 20/50 and 10/50
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
+ 10.f / texture_size.width(), 20.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled);
+
+class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // Root
+ // |
+ // +-- Scaling Layer (adds a 2x scale)
+ // |
+ // +-- Content Layer
+ // +--Mask
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> scaling_layer = Layer::Create();
+ root->AddChild(scaling_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ scaling_layer->AddChild(content_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 10), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 10, 100, 90), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size scaling_layer_size(50, 50);
+ scaling_layer->SetBounds(scaling_layer_size);
+ gfx::Transform scale;
+ scale.Scale(2.f, 2.f);
+ scaling_layer->SetTransform(scale);
+
+ content_layer->SetBounds(scaling_layer_size);
+
+ mask_layer->SetBounds(scaling_layer_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ // Check that the tree scaling is correctly taken into account for the
+ // mask, that should fully map onto the quad.
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ render_pass_quad->rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ break;
+ case 1:
+ // Applying a DSF should change the render surface size, but won't
+ // affect which part of the mask is used.
+ EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
+ render_pass_quad->rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ break;
+ }
+ return draw_result;
+ }
+
+ void DidCommit() override {
+ 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());
+ break;
+ }
+ }
+
+ void AfterTest() override {}
+
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerWithScaling_Untiled
+ : public LayerTreeTestMaskLayerWithScaling {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Untiled);
+
+class LayerTreeTestMaskLayerWithScaling_Tiled
+ : public LayerTreeTestMaskLayerWithScaling {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Tiled);
+
+class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 100x100, but is allocated a 120x150 texture.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ root->AddChild(content_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size layer_size(100, 100);
+ content_layer->SetBounds(layer_size);
+
+ gfx::Size mask_size(100, 100);
+ gfx::Size mask_texture_size(120, 150);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
+ mask_layer->set_fixed_tile_size(mask_texture_size);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is 100x100
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ render_pass_quad->rect.ToString());
+ // The mask layer is 100x100, but is backed by a 120x150 image.
+ EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskWithNonExactTextureSize_Untiled
+ : public LayerTreeTestMaskWithNonExactTextureSize {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskWithNonExactTextureSize_Untiled);
+
+class LayerTreeTestMaskWithNonExactTextureSize_Tiled
+ : public LayerTreeTestMaskWithNonExactTextureSize {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize_Tiled);
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index 40aeeb1acb3..205d1f2c648 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -41,14 +41,16 @@ class LayerTreeHostPictureTestTwinLayer
}
void BeginTest() override {
- activates_ = 0;
+ // Commit and activate to produce a pending (recycled) layer and an active
+ // layer.
PostSetNeedsCommitToMainThread();
}
void DidCommit() override {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
- // Activate while there are pending and active twins in place.
+ // Activate reusing an existing recycled pending layer, to an already
+ // existing active layer.
layer_tree_host()->SetNeedsCommit();
break;
case 2:
@@ -66,12 +68,9 @@ class LayerTreeHostPictureTestTwinLayer
break;
}
case 4:
- // Active while there are pending and active twins again.
+ // Activate while there are pending and active twins again.
layer_tree_host()->SetNeedsCommit();
break;
- case 5:
- EndTest();
- break;
}
}
@@ -131,11 +130,14 @@ class LayerTreeHostPictureTestTwinLayer
}
++activates_;
+ if (activates_ == 5)
+ EndTest();
}
- void AfterTest() override { EXPECT_EQ(5, activates_); }
+ void AfterTest() override {}
+
+ int activates_ = 0;
- int activates_;
int picture_id1_;
int picture_id2_;
};
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index 68982f6f0cf..dc45563a2c7 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1250,7 +1250,7 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
layer_tree_host()
->inner_viewport_scroll_layer()
->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kNonFastScrollableRegion);
+ MainThreadScrollingReason::kScrollbarScrolling);
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1268,7 +1268,7 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
scroll_tree, inner_scroll_node);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
- EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
+ EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
status.main_thread_scrolling_reasons);
status = impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index fa670feff83..a6b06c59e26 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -468,8 +468,11 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->elastic_overscroll()->PushPendingToActive();
target_tree->set_content_source_id(content_source_id());
+ target_tree->set_request_presentation_time(request_presentation_time());
- target_tree->set_local_surface_id(local_surface_id());
+ if (TakeNewLocalSurfaceIdRequest())
+ target_tree->RequestNewLocalSurfaceId();
+ target_tree->SetLocalSurfaceIdFromParent(local_surface_id_from_parent());
target_tree->pending_page_scale_animation_ =
std::move(pending_page_scale_animation_);
@@ -963,6 +966,21 @@ 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::RequestNewLocalSurfaceId() {
+ new_local_surface_id_request_ = true;
+}
+
+bool LayerTreeImpl::TakeNewLocalSurfaceIdRequest() {
+ bool new_local_surface_id_request = new_local_surface_id_request_;
+ new_local_surface_id_request_ = false;
+ return new_local_surface_id_request;
+}
+
void LayerTreeImpl::SetRasterColorSpace(
int raster_color_space_id,
const gfx::ColorSpace& raster_color_space) {
@@ -1085,7 +1103,7 @@ bool LayerTreeImpl::UpdateDrawProperties(
device_scale_factor(), current_page_scale_factor(), PageScaleLayer(),
InnerViewportScrollLayer(), OuterViewportScrollLayer(),
elastic_overscroll()->Current(IsActiveTree()),
- OverscrollElasticityLayer(), resource_provider()->max_texture_size(),
+ OverscrollElasticityLayer(), max_texture_size(),
settings().layer_transforms_should_scale_layer_contents,
&render_surface_list_, &property_trees_);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
@@ -1376,6 +1394,10 @@ LayerTreeFrameSink* LayerTreeImpl::layer_tree_frame_sink() {
return host_impl_->layer_tree_frame_sink();
}
+int LayerTreeImpl::max_texture_size() const {
+ return host_impl_->max_texture_size();
+}
+
const LayerTreeSettings& LayerTreeImpl::settings() const {
return host_impl_->settings();
}
@@ -1388,10 +1410,6 @@ viz::ContextProvider* LayerTreeImpl::context_provider() const {
return host_impl_->layer_tree_frame_sink()->context_provider();
}
-viz::SharedBitmapManager* LayerTreeImpl::shared_bitmap_manager() const {
- return host_impl_->layer_tree_frame_sink()->shared_bitmap_manager();
-}
-
LayerTreeResourceProvider* LayerTreeImpl::resource_provider() const {
return host_impl_->resource_provider();
}
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 62c31dbd0a1..11e406e78d4 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -106,10 +106,10 @@ class CC_EXPORT LayerTreeImpl {
// Methods called by the layer tree that pass-through or access LTHI.
// ---------------------------------------------------------------------------
LayerTreeFrameSink* layer_tree_frame_sink();
+ int max_texture_size() const;
const LayerTreeSettings& settings() const;
const LayerTreeDebugState& debug_state() const;
viz::ContextProvider* context_provider() const;
- viz::SharedBitmapManager* shared_bitmap_manager() const;
LayerTreeResourceProvider* resource_provider() const;
TileManager* tile_manager() const;
ImageDecodeCache* image_decode_cache() const;
@@ -299,11 +299,15 @@ 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 set_local_surface_id(const viz::LocalSurfaceId& id) {
- local_surface_id_ = id;
+ void SetLocalSurfaceIdFromParent(const viz::LocalSurfaceId& id);
+ const viz::LocalSurfaceId& local_surface_id_from_parent() const {
+ return local_surface_id_from_parent_;
}
- const viz::LocalSurfaceId& local_surface_id() const {
- return local_surface_id_;
+
+ void RequestNewLocalSurfaceId();
+ bool TakeNewLocalSurfaceIdRequest();
+ bool new_local_surface_id_request_for_testing() const {
+ return new_local_surface_id_request_;
}
void SetRasterColorSpace(int raster_color_space_id,
@@ -608,7 +612,8 @@ class CC_EXPORT LayerTreeImpl {
gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_;
+ viz::LocalSurfaceId local_surface_id_from_parent_;
+ bool new_local_surface_id_request_ = false;
scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_;
diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc
index 08137e0e846..3f3000b41bf 100644
--- a/chromium/cc/trees/layer_tree_settings.cc
+++ b/chromium/cc/trees/layer_tree_settings.cc
@@ -15,8 +15,7 @@ LayerTreeSettings::LayerTreeSettings()
minimum_occlusion_tracking_size(gfx::Size(160, 160)),
memory_policy(64 * 1024 * 1024,
gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
- ManagedMemoryPolicy::kDefaultNumResourcesLimit),
- preferred_tile_format(viz::PlatformColor::BestTextureFormat()) {}
+ ManagedMemoryPolicy::kDefaultNumResourcesLimit) {}
LayerTreeSettings::LayerTreeSettings(const LayerTreeSettings& other) = default;
LayerTreeSettings::~LayerTreeSettings() = default;
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 2584543f863..50b8805bc7a 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -93,7 +93,7 @@ class CC_EXPORT LayerTreeSettings {
ManagedMemoryPolicy memory_policy;
size_t decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
int max_preraster_distance_in_screen_pixels = 1000;
- viz::ResourceFormat preferred_tile_format;
+ bool use_rgba_4444 = false;
bool unpremultiply_and_dither_low_bit_depth_tiles = false;
bool enable_mask_tiling = true;
@@ -156,6 +156,10 @@ class CC_EXPORT LayerTreeSettings {
// Whether SetViewportSizeAndScale should update the painted scale factor or
// the device scale factor.
bool use_painted_device_scale_factor = false;
+
+ // Whether a HitTestRegionList should be built from the active layer tree when
+ // submitting a CompositorFrame.
+ bool build_hit_test_data = false;
};
} // namespace cc
diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h
index e4aae914bae..18b7fe5118c 100644
--- a/chromium/cc/trees/mutator_host.h
+++ b/chromium/cc/trees/mutator_host.h
@@ -129,7 +129,6 @@ class MutatorHost {
virtual size_t CompositedAnimationsCount() const = 0;
virtual size_t MainThreadAnimationsCount() const = 0;
- virtual size_t MainThreadCompositableAnimationsCount() const = 0;
virtual bool CurrentFrameHadRAF() const = 0;
virtual bool NextFrameHasPendingRAF() const = 0;
};
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index 4c4cdd4c632..06b051455ed 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -367,10 +367,6 @@ size_t ProxyImpl::MainThreadAnimationsCount() const {
return host_impl_->mutator_host()->MainThreadAnimationsCount();
}
-size_t ProxyImpl::MainThreadCompositableAnimationsCount() const {
- return host_impl_->mutator_host()->MainThreadCompositableAnimationsCount();
-}
-
bool ProxyImpl::CurrentFrameHadRAF() const {
return host_impl_->mutator_host()->CurrentFrameHadRAF();
}
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 0e3347383df..467f0e616d8 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -125,7 +125,6 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
base::TimeTicks time) override;
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
- size_t MainThreadCompositableAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
bool NextFrameHasPendingRAF() const override;
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 7b7589167bb..668e674e30d 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -300,7 +300,7 @@ void ProxyMain::BeginMainFrame(
// commit.
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, 0, 0,
+ ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, 0,
begin_main_frame_state->begin_frame_args.frame_time, 1);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc
index 4466cb928c1..5678f5c8987 100644
--- a/chromium/cc/trees/render_frame_metadata.cc
+++ b/chromium/cc/trees/render_frame_metadata.cc
@@ -21,7 +21,15 @@ bool RenderFrameMetadata::HasAlwaysUpdateMetadataChanged(
const RenderFrameMetadata& rfm2) {
return rfm1.root_background_color != rfm2.root_background_color ||
rfm1.is_scroll_offset_at_top != rfm2.is_scroll_offset_at_top ||
- rfm1.selection != rfm2.selection;
+ rfm1.selection != rfm2.selection ||
+ rfm1.is_mobile_optimized != rfm2.is_mobile_optimized ||
+ rfm1.device_scale_factor != rfm2.device_scale_factor ||
+ rfm1.viewport_size_in_pixels != rfm2.viewport_size_in_pixels ||
+ rfm1.local_surface_id != rfm2.local_surface_id ||
+ rfm1.top_controls_height != rfm2.top_controls_height ||
+ rfm1.top_controls_shown_ratio != rfm2.top_controls_shown_ratio ||
+ rfm1.bottom_controls_height != rfm2.bottom_controls_height ||
+ rfm1.bottom_controls_shown_ratio != rfm2.bottom_controls_shown_ratio;
}
RenderFrameMetadata& RenderFrameMetadata::operator=(
@@ -30,14 +38,22 @@ RenderFrameMetadata& RenderFrameMetadata::operator=(
RenderFrameMetadata& RenderFrameMetadata::operator=(
RenderFrameMetadata&& other) = default;
-bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) {
+bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
return root_scroll_offset == other.root_scroll_offset &&
root_background_color == other.root_background_color &&
is_scroll_offset_at_top == other.is_scroll_offset_at_top &&
- selection == other.selection;
+ selection == other.selection &&
+ is_mobile_optimized == other.is_mobile_optimized &&
+ device_scale_factor == other.device_scale_factor &&
+ viewport_size_in_pixels == other.viewport_size_in_pixels &&
+ local_surface_id == other.local_surface_id &&
+ top_controls_height == other.top_controls_height &&
+ top_controls_shown_ratio == other.top_controls_shown_ratio &&
+ bottom_controls_height == other.bottom_controls_height &&
+ bottom_controls_shown_ratio == other.bottom_controls_shown_ratio;
}
-bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) {
+bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) const {
return !operator==(other);
}
diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h
index 0a20fa8d73c..d07d7d4bfc6 100644
--- a/chromium/cc/trees/render_frame_metadata.h
+++ b/chromium/cc/trees/render_frame_metadata.h
@@ -8,7 +8,9 @@
#include "base/optional.h"
#include "cc/cc_export.h"
#include "components/viz/common/quads/selection.h"
+#include "components/viz/common/surfaces/local_surface_id.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/selection_bound.h"
@@ -29,8 +31,8 @@ class CC_EXPORT RenderFrameMetadata {
RenderFrameMetadata& operator=(const RenderFrameMetadata&);
RenderFrameMetadata& operator=(RenderFrameMetadata&& other);
- bool operator==(const RenderFrameMetadata& other);
- bool operator!=(const RenderFrameMetadata& other);
+ bool operator==(const RenderFrameMetadata& other) const;
+ bool operator!=(const RenderFrameMetadata& other) const;
// Indicates whether the scroll offset of the root layer is at top, i.e.,
// whether scroll_offset.y() == 0.
@@ -48,6 +50,32 @@ class CC_EXPORT RenderFrameMetadata {
// Selection region relative to the current viewport. If the selection is
// empty or otherwise unused, the bound types will indicate such.
viz::Selection<gfx::SelectionBound> selection;
+
+ // Determines whether the page is mobile optimized or not, which means at
+ // least one of the following has to be true:
+ // - page has a width=device-width or narrower viewport.
+ // - page prevents zooming in or out (i.e. min and max page scale factors
+ // are the same).
+ bool is_mobile_optimized = false;
+
+ // The device scale factor used to generate a CompositorFrame.
+ float device_scale_factor = 1.f;
+
+ // The size of the viewport used to generate a CompositorFrame.
+ gfx::Size viewport_size_in_pixels;
+
+ // The last viz::LocalSurfaceId used to submit a CompositorFrame.
+ base::Optional<viz::LocalSurfaceId> local_surface_id;
+
+ // Used to position the Android location top bar and page content, whose
+ // precise position is computed by the renderer compositor.
+ float top_controls_height = 0.f;
+ float top_controls_shown_ratio = 0.f;
+
+ // Used to position Android bottom bar, whose position is computed by the
+ // renderer compositor.
+ float bottom_controls_height = 0.f;
+ float bottom_controls_shown_ratio = 0.f;
};
} // namespace cc
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 541e264e720..28c45b6196b 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -381,10 +381,6 @@ size_t SingleThreadProxy::MainThreadAnimationsCount() const {
return 0;
}
-size_t SingleThreadProxy::MainThreadCompositableAnimationsCount() const {
- return 0;
-}
-
bool SingleThreadProxy::CurrentFrameHadRAF() const {
return false;
}
@@ -748,8 +744,8 @@ void SingleThreadProxy::BeginMainFrame(
// know we will commit since QueueSwapPromise itself requests a commit.
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, 0, 0,
- begin_frame_args.frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, 0, begin_frame_args.frame_time,
+ 1);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
@@ -839,7 +835,9 @@ void SingleThreadProxy::ScheduledActionPrepareTiles() {
}
void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink() {
- NOTREACHED();
+ // This is an Android WebView codepath, which only uses multi-thread
+ // compositor. So this should not occur in single-thread mode.
+ NOTREACHED() << "Android Webview use-case, so multi-thread only";
}
void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 07b8ca1f53c..f505320da40 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -92,7 +92,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
base::TimeTicks time) override;
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
- size_t MainThreadCompositableAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
bool NextFrameHasPendingRAF() const override;