summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-11 11:32:04 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 13:40:17 +0000
commit31ccca0778db85c159634478b4ec7997f6704860 (patch)
tree3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/third_party/blink/renderer/platform
parent248b70b82a40964d5594eb04feca0fa36716185d (diff)
downloadqtwebengine-chromium-31ccca0778db85c159634478b4ec7997f6704860.tar.gz
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform')
-rw-r--r--chromium/third_party/blink/renderer/platform/BUILD.gn152
-rw-r--r--chromium/third_party/blink/renderer/platform/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/platform/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_array.h41
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/hrtf_elevation.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/reverb_convolver.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/RuntimeCallStats.md4
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h52
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/exception_messages.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/exception_messages.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc109
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.h41
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc121
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h129
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/to_v8.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_private_property.cc58
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h137
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h109
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/DEPS19
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie.cc)93
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.h102
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.typemap (renamed from chromium/third_party/blink/renderer/platform/mojo/canonical_cookie.typemap)8
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.cc (renamed from chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.cc)79
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_test.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie_test.cc)41
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms_test.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/platform.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/url_conversion.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_http_body.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_http_header_map.cc78
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_image.cc163
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_image_test.cc90
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_input_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_answer_options.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_offer_options.cc53
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_source.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description.cc106
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description_request.cc64
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_request.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_response.cc52
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_void_request.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_security_origin.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_request.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/file_metadata.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/file_metadata.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h76
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm23
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_point_3d.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc174
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc262
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc52
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc206
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc188
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc191
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc135
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc154
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h77
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc474
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h80
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc794
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc503
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc218
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc131
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_types.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc93
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc90
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc128
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h80
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/path.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h46
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc89
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md320
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache.cc68
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache.h63
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc212
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.cc157
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.h182
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.h148
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.cc123
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.h136
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test.cc535
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc213
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc128
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.h197
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/member.h128
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h48
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/page_memory.cc67
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/page_memory.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.cc287
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.h105
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc110
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/threading_traits.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/trace_traits.h474
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/visitor.h116
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc203
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/worklist.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc144
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/json/json_values.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/json/json_values.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/README.md4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/media_capabilities/web_audio_configuration.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_key_system_configuration.h49
-rw-r--r--chromium/third_party/blink/renderer/platform/media_capabilities/web_media_decoding_configuration.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/OWNERS6
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_level_calculator.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h65
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc)3
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h136
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options_test.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h215
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms.cc)20
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h98
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms_test.cc78
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/BUILD.gn15
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni2
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry.typemap9
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/network/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_parsers.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_parsers_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/network/network_utils.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/network/network_utils.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/port_allocator.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/port_allocator.h62
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc)72
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h112
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_legacy_stats.h53
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_sender.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h53
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_receiver.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_transceiver.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h73
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h86
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc102
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/task_queue_factory_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h139
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc39
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h190
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_util.h49
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc155
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5277
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/features.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc67
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc39
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task_unittest.cc48
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread_type.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_thread_type.cc)38
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.cc319
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h (renamed from chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h)130
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder_unittest.cc565
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc252
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc437
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc126
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc56
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc255
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc74
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/thread.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/thread_type.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/find_cc_layer.cc70
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/find_cc_layer.h44
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc412
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h99
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/a1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/b1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/c1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/d1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/e1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/f1
-rw-r--r--chromium/third_party/blink/renderer/platform/timer.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/timer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/timer_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/identity_transform_operation.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc62
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operation.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc133
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operations.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operations_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/local_video_capturer_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/web_test_support.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/web_test_support.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/known_ports.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc48
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin_hash.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc151
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/url_security_origin_map.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/track_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/track_observer.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_logging.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h92
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/BUILD.gn21
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/bloom_filter.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/construct_traits.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/deque.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/forward.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/functional.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_table.h130
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_traits.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/type_traits.h61
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.cc118
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h264
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc215
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h247
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.cc100
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h134
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/bigint64_array.h71
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/biguint64_array.h71
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float32_array.h101
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float64_array.h93
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int16_array.h82
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int32_array.h81
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int8_array.h85
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h63
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h126
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint16_array.h85
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint32_array.h85
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h85
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_clamped_array.h96
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector.h215
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_traits.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf.cc1
565 files changed, 12464 insertions, 12088 deletions
diff --git a/chromium/third_party/blink/renderer/platform/BUILD.gn b/chromium/third_party/blink/renderer/platform/BUILD.gn
index a3f1ea12b1e..2cdb42f959b 100644
--- a/chromium/third_party/blink/renderer/platform/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/BUILD.gn
@@ -114,6 +114,7 @@ group("make_platform_generated") {
visibility = [] # Allow re-assignment of list.
visibility = [ "//third_party/blink/renderer/*" ]
public_deps = [
+ ":bindings_buildflags",
":character_data",
":color_data",
":font_family_names",
@@ -141,7 +142,6 @@ group("blink_platform_public_deps") {
visibility = [] # Allow re-assignment of list.
visibility = [ "//third_party/blink/renderer/platform/*" ]
public_deps = [
- ":bindings_buildflags",
":make_platform_generated",
"//base",
"//cc",
@@ -401,6 +401,7 @@ jumbo_component("platform") {
"bindings/callback_method_retriever.cc",
"bindings/callback_method_retriever.h",
"bindings/custom_wrappable.h",
+ "bindings/dictionary_base.h",
"bindings/dom_data_store.cc",
"bindings/dom_data_store.h",
"bindings/dom_wrapper_world.cc",
@@ -429,6 +430,7 @@ jumbo_component("platform") {
"bindings/script_state.h",
"bindings/script_wrappable.cc",
"bindings/script_wrappable.h",
+ "bindings/shared_persistent.h",
"bindings/string_resource.cc",
"bindings/string_resource.h",
"bindings/to_v8.h",
@@ -464,6 +466,10 @@ jumbo_component("platform") {
"bindings/wrapper_type_info.cc",
"bindings/wrapper_type_info.h",
"content_decryption_module_result.h",
+ "cookie/canonical_cookie.cc",
+ "cookie/canonical_cookie.h",
+ "cookie/canonical_cookie_mojom_traits.cc",
+ "cookie/canonical_cookie_mojom_traits.h",
"cpu/mips/common_macros_msa.h",
"crypto.cc",
"crypto.h",
@@ -474,14 +480,10 @@ jumbo_component("platform") {
"data_resource_helper.h",
"exported/file_path_conversion.cc",
"exported/interface_registry.cc",
- "exported/mediastream/media_stream_audio_level_calculator.cc",
- "exported/mediastream/media_stream_audio_processor_options.cc",
- "exported/mediastream/media_stream_audio_source.cc",
"exported/mediastream/media_stream_audio_track.cc",
"exported/mediastream/web_media_element_source_utils.cc",
"exported/mediastream/web_platform_media_stream_source.cc",
"exported/mediastream/web_platform_media_stream_track.cc",
- "exported/mediastream/webrtc_uma_histograms.cc",
"exported/platform.cc",
"exported/url_conversion.cc",
"exported/video_capture/web_video_capture_impl_manager.cc",
@@ -489,7 +491,6 @@ jumbo_component("platform") {
"exported/web_audio_device.cc",
"exported/web_blob_info.cc",
"exported/web_cache.cc",
- "exported/web_canonical_cookie.cc",
"exported/web_coalesced_input_event.cc",
"exported/web_content_decryption_module.cc",
"exported/web_content_decryption_module_access.cc",
@@ -509,10 +510,8 @@ jumbo_component("platform") {
"exported/web_font_description.cc",
"exported/web_gesture_event.cc",
"exported/web_http_body.cc",
- "exported/web_http_header_map.cc",
"exported/web_http_load_info.cc",
"exported/web_icon_sizes_parser.cc",
- "exported/web_image.cc",
"exported/web_image_generator.cc",
"exported/web_input_event.cc",
"exported/web_media_constraints.cc",
@@ -532,20 +531,8 @@ jumbo_component("platform") {
"exported/web_prerender.cc",
"exported/web_prerendering_support.cc",
"exported/web_resource_timing_info.cc",
- "exported/web_rtc_answer_options.cc",
- "exported/web_rtc_ice_candidate.cc",
- "exported/web_rtc_offer_options.cc",
"exported/web_rtc_peer_connection_handler_client.cc",
- "exported/web_rtc_rtp_receiver.cc",
- "exported/web_rtc_rtp_sender.cc",
- "exported/web_rtc_rtp_source.cc",
- "exported/web_rtc_rtp_transceiver.cc",
- "exported/web_rtc_session_description.cc",
- "exported/web_rtc_session_description_request.cc",
"exported/web_rtc_stats.cc",
- "exported/web_rtc_stats_request.cc",
- "exported/web_rtc_stats_response.cc",
- "exported/web_rtc_void_request.cc",
"exported/web_runtime_features.cc",
"exported/web_security_origin.cc",
"exported/web_string.cc",
@@ -553,7 +540,6 @@ jumbo_component("platform") {
"exported/web_text_input_info.cc",
"exported/web_text_run.cc",
"exported/web_thread_safe_data.cc",
- "exported/web_thread_type.cc",
"exported/web_time_range.cc",
"exported/web_touch_event.cc",
"exported/web_url.cc",
@@ -608,6 +594,8 @@ jumbo_component("platform") {
"fonts/font_family.h",
"fonts/font_global_context.cc",
"fonts/font_global_context.h",
+ "fonts/font_matching_metrics.cc",
+ "fonts/font_matching_metrics.h",
"fonts/font_metrics.cc",
"fonts/font_metrics.h",
"fonts/font_optical_sizing.cc",
@@ -843,6 +831,8 @@ jumbo_component("platform") {
"graphics/compositing/chunk_to_layer_mapper.h",
"graphics/compositing/content_layer_client_impl.cc",
"graphics/compositing/content_layer_client_impl.h",
+ "graphics/compositing/layers_as_json.cc",
+ "graphics/compositing/layers_as_json.h",
"graphics/compositing/paint_artifact_compositor.cc",
"graphics/compositing/paint_artifact_compositor.h",
"graphics/compositing/paint_chunks_to_cc_layer.cc",
@@ -1082,6 +1072,8 @@ jumbo_component("platform") {
"graphics/paint/scroll_hit_test_display_item.h",
"graphics/paint/scroll_paint_property_node.cc",
"graphics/paint/scroll_paint_property_node.h",
+ "graphics/paint/scrollbar_display_item.cc",
+ "graphics/paint/scrollbar_display_item.h",
"graphics/paint/subsequence_recorder.h",
"graphics/paint/transform_paint_property_node.cc",
"graphics/paint/transform_paint_property_node.h",
@@ -1112,6 +1104,8 @@ jumbo_component("platform") {
"graphics/replaying_canvas.h",
"graphics/scoped_interpolation_quality.h",
"graphics/scroll_types.h",
+ "graphics/scrollbar_theme_settings.cc",
+ "graphics/scrollbar_theme_settings.h",
"graphics/skia/image_pixel_locker.cc",
"graphics/skia/image_pixel_locker.h",
"graphics/skia/sk_size_hash.h",
@@ -1194,14 +1188,18 @@ jumbo_component("platform") {
"media/webaudiosourceprovider_impl.cc",
"media_capabilities/web_audio_configuration.h",
"media_capabilities/web_media_capabilities_info.h",
- "media_capabilities/web_media_capabilities_key_system_configuration.h",
"media_capabilities/web_media_configuration.h",
- "media_capabilities/web_media_decoding_configuration.h",
"media_capabilities/web_video_configuration.h",
"mediastream/aec_dump_agent_impl.cc",
"mediastream/aec_dump_agent_impl.h",
"mediastream/audio_service_audio_processor_proxy.cc",
"mediastream/audio_service_audio_processor_proxy.h",
+ "mediastream/media_stream_audio_level_calculator.cc",
+ "mediastream/media_stream_audio_level_calculator.h",
+ "mediastream/media_stream_audio_processor_options.cc",
+ "mediastream/media_stream_audio_processor_options.h",
+ "mediastream/media_stream_audio_source.cc",
+ "mediastream/media_stream_audio_source.h",
"mediastream/media_stream_component.cc",
"mediastream/media_stream_component.h",
"mediastream/media_stream_descriptor.cc",
@@ -1212,6 +1210,8 @@ jumbo_component("platform") {
"mediastream/media_stream_web_audio_source.h",
"mediastream/webaudio_media_stream_source.cc",
"mediastream/webaudio_media_stream_source.h",
+ "mediastream/webrtc_uma_histograms.cc",
+ "mediastream/webrtc_uma_histograms.h",
"mhtml/archive_resource.cc",
"mhtml/archive_resource.h",
"mhtml/mhtml_archive.cc",
@@ -1224,10 +1224,10 @@ jumbo_component("platform") {
"mojo/big_string_mojom_traits.h",
"mojo/bluetooth_mojom_traits.cc",
"mojo/bluetooth_mojom_traits.h",
- "mojo/canonical_cookie_mojom_traits.cc",
- "mojo/canonical_cookie_mojom_traits.h",
"mojo/fetch_api_request_headers_mojom_traits.h",
+ "mojo/kurl_mojom_traits.h",
"mojo/mojo_helper.h",
+ "mojo/security_origin_mojom_traits.h",
"mojo/string16_mojom_traits.cc",
"mojo/string16_mojom_traits.h",
"p2p/empty_network_manager.cc",
@@ -1246,6 +1246,8 @@ jumbo_component("platform") {
"p2p/network_list_observer.h",
"p2p/network_manager_uma.cc",
"p2p/network_manager_uma.h",
+ "p2p/port_allocator.cc",
+ "p2p/port_allocator.h",
"p2p/socket_client.h",
"p2p/socket_client_delegate.h",
"p2p/socket_client_impl.cc",
@@ -1253,14 +1255,28 @@ jumbo_component("platform") {
"p2p/socket_dispatcher.cc",
"p2p/socket_dispatcher.h",
"peerconnection/audio_codec_factory.cc",
+ "peerconnection/audio_codec_factory.h",
"peerconnection/rtc_answer_options_platform.h",
+ "peerconnection/rtc_api_name.h",
"peerconnection/rtc_dtmf_sender_handler.cc",
"peerconnection/rtc_dtmf_sender_handler.h",
+ "peerconnection/rtc_event_log_output_sink.h",
"peerconnection/rtc_event_log_output_sink_proxy.cc",
"peerconnection/rtc_event_log_output_sink_proxy.h",
+ "peerconnection/rtc_ice_candidate_platform.cc",
+ "peerconnection/rtc_ice_candidate_platform.h",
+ "peerconnection/rtc_legacy_stats.h",
"peerconnection/rtc_offer_options_platform.h",
+ "peerconnection/rtc_rtp_receiver_platform.cc",
+ "peerconnection/rtc_rtp_receiver_platform.h",
+ "peerconnection/rtc_rtp_sender_platform.cc",
+ "peerconnection/rtc_rtp_sender_platform.h",
"peerconnection/rtc_rtp_source.cc",
"peerconnection/rtc_rtp_source.h",
+ "peerconnection/rtc_rtp_transceiver_platform.cc",
+ "peerconnection/rtc_rtp_transceiver_platform.h",
+ "peerconnection/rtc_session_description_platform.cc",
+ "peerconnection/rtc_session_description_platform.h",
"peerconnection/rtc_session_description_request.h",
"peerconnection/rtc_stats.cc",
"peerconnection/rtc_stats.h",
@@ -1279,10 +1295,14 @@ jumbo_component("platform") {
"peerconnection/stun_field_trial.h",
"peerconnection/transmission_encoding_info_handler.cc",
"peerconnection/transmission_encoding_info_handler.h",
+ "peerconnection/two_keys_adapter_map.h",
"peerconnection/video_codec_factory.cc",
"peerconnection/video_codec_factory.h",
"peerconnection/webrtc_audio_sink.cc",
+ "peerconnection/webrtc_audio_sink.h",
+ "peerconnection/webrtc_util.h",
"peerconnection/webrtc_video_track_source.cc",
+ "peerconnection/webrtc_video_track_source.h",
"prerender.cc",
"prerender.h",
"prerender_client.h",
@@ -1404,11 +1424,12 @@ jumbo_component("platform") {
"weborigin/security_policy.cc",
"weborigin/security_policy.h",
"weborigin/security_violation_reporting_policy.h",
- "weborigin/url_security_origin_map.h",
"webrtc/peer_connection_remote_audio_source.cc",
"webrtc/peer_connection_remote_audio_source.h",
"webrtc/track_observer.cc",
+ "webrtc/track_observer.h",
"webrtc/webrtc_logging.cc",
+ "webrtc/webrtc_source.h",
"webrtc/webrtc_video_frame_adapter.cc",
"webrtc/webrtc_video_frame_adapter.h",
"webrtc/webrtc_video_utils.cc",
@@ -1422,9 +1443,12 @@ jumbo_component("platform") {
sources += get_target_outputs(":character_data") +
get_target_outputs(":color_data") +
get_target_outputs(":font_family_names")
- set_sources_assignment_filter([ "*.pickle" ])
- sources += get_target_outputs(":runtime_enabled_features")
- set_sources_assignment_filter(sources_assignment_filter)
+
+ foreach(_output, get_target_outputs(":runtime_enabled_features")) {
+ if (get_path_info(_output, "extension") != "pickle") {
+ sources += [ _output ]
+ }
+ }
if (is_win) {
jumbo_excluded_sources = [
@@ -1464,10 +1488,12 @@ jumbo_component("platform") {
"//third_party/blink/renderer/platform/loader",
"//third_party/blink/renderer/platform/network",
"//third_party/blink/renderer/platform/scheduler",
+ "//ui/gfx",
]
deps = [
":platform_export",
"//base/allocator:buildflags",
+ "//cc/ipc",
"//components/paint_preview/common",
"//components/viz/client",
"//components/viz/common",
@@ -1484,33 +1510,18 @@ jumbo_component("platform") {
"//services/viz/public/cpp/gpu",
"//skia:skcms",
"//third_party:freetype_harfbuzz",
+ "//third_party/abseil-cpp/absl/types:optional",
+ "//third_party/blink/public:image_resources",
"//third_party/blink/public/common",
"//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings_blink",
+ "//third_party/blink/public/strings",
"//third_party/ced",
"//third_party/emoji-segmenter",
"//third_party/icu",
"//third_party/libyuv",
- "//third_party/webrtc/api:libjingle_logging_api",
- "//third_party/webrtc/api:packet_socket_factory",
- "//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16",
- "//third_party/webrtc/api/audio_codecs/L16:audio_encoder_L16",
- "//third_party/webrtc/api/audio_codecs/g711:audio_decoder_g711",
- "//third_party/webrtc/api/audio_codecs/g711:audio_encoder_g711",
- "//third_party/webrtc/api/audio_codecs/g722:audio_decoder_g722",
- "//third_party/webrtc/api/audio_codecs/g722:audio_encoder_g722",
- "//third_party/webrtc/api/audio_codecs/isac:audio_decoder_isac",
- "//third_party/webrtc/api/audio_codecs/isac:audio_encoder_isac",
- "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_multiopus",
- "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus",
- "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_multiopus",
- "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus",
- "//third_party/webrtc/media:rtc_internal_video_codecs",
- "//third_party/webrtc/modules/video_coding:webrtc_h264",
- "//third_party/webrtc/p2p:rtc_p2p",
- "//third_party/webrtc_overrides:init_webrtc",
+ "//third_party/webrtc_overrides:webrtc_component",
"//third_party/zlib/google:compression_utils",
"//ui/base:base",
- "//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/mojom",
]
@@ -1590,6 +1601,20 @@ jumbo_component("platform") {
configs += blink_symbols_config
}
+source_set("geometry_mojom_traits") {
+ visibility += [ "//ui/gfx/geometry/mojom:mojom_blink" ]
+
+ sources = [
+ "mojo/geometry_mojom_traits.cc",
+ "mojo/geometry_mojom_traits.h",
+ ]
+
+ public_deps = [
+ "//third_party/blink/public:blink_headers",
+ "//ui/gfx/geometry/mojom:mojom_blink_headers",
+ ]
+}
+
jumbo_static_library("test_support") {
visibility += [ "//third_party/blink/*" ]
testonly = true
@@ -1607,6 +1632,8 @@ jumbo_static_library("test_support") {
"testing/fake_display_item_client.h",
"testing/fake_graphics_layer.h",
"testing/fake_graphics_layer_client.h",
+ "testing/find_cc_layer.cc",
+ "testing/find_cc_layer.h",
"testing/font_test_helpers.cc",
"testing/font_test_helpers.h",
"testing/histogram_tester.cc",
@@ -1633,8 +1660,6 @@ jumbo_static_library("test_support") {
"testing/testing_platform_support.h",
"testing/testing_platform_support_with_mock_scheduler.cc",
"testing/testing_platform_support_with_mock_scheduler.h",
- "testing/testing_platform_support_with_web_rtc.cc",
- "testing/testing_platform_support_with_web_rtc.h",
"testing/unit_test_helpers.cc",
"testing/unit_test_helpers.h",
"testing/url_test_helpers.cc",
@@ -1650,7 +1675,7 @@ jumbo_static_library("test_support") {
]
# fuzzed_data_provider may not work with a custom toolchain.
- if (custom_toolchain == "") {
+ if (custom_toolchain == "" && is_clang) {
sources += [
"testing/fuzzed_data_provider.cc",
"testing/fuzzed_data_provider.h",
@@ -1718,13 +1743,11 @@ jumbo_source_set("blink_platform_unittests_sources") {
"audio/vector_math_test.cc",
"bindings/parkable_string_test.cc",
"bindings/runtime_call_stats_test.cc",
+ "cookie/canonical_cookie_test.cc",
"exported/file_path_conversion_test.cc",
- "exported/mediastream/media_stream_audio_processor_options_test.cc",
"exported/mediastream/media_stream_audio_test.cc",
- "exported/mediastream/webrtc_uma_histograms_test.cc",
"exported/page_zoom_test.cc",
"exported/video_capture/web_video_capture_impl_manager_test.cc",
- "exported/web_canonical_cookie_test.cc",
"exported/web_icon_sizes_parser_test.cc",
"exported/web_screen_info_test.cc",
"exported/web_string_test.cc",
@@ -1839,6 +1862,8 @@ jumbo_source_set("blink_platform_unittests_sources") {
"loader/cors/cors_test.cc",
"mac/graphics_context_canvas_test.mm",
"media/webaudiosourceprovider_impl_test.cc",
+ "mediastream/media_stream_audio_processor_options_test.cc",
+ "mediastream/webrtc_uma_histograms_test.cc",
"mhtml/mhtml_parser_test.cc",
"mojo/big_string_mojom_traits_test.cc",
"mojo/geometry_mojom_traits_test.cc",
@@ -1850,6 +1875,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"peerconnection/rtc_video_decoder_adapter_test.cc",
"peerconnection/rtc_video_encoder_test.cc",
"peerconnection/stun_field_trial_test.cc",
+ "peerconnection/task_queue_factory_test.cc",
"peerconnection/transmission_encoding_info_handler_test.cc",
"peerconnection/two_keys_adapter_map_unittest.cc",
"peerconnection/webrtc_video_track_source_test.cc",
@@ -1933,7 +1959,9 @@ jumbo_source_set("blink_platform_unittests_sources") {
"//third_party/blink/renderer/platform/network:unit_tests",
"//third_party/blink/renderer/platform/scheduler:unit_tests",
"//third_party/blink/renderer/platform/wtf",
- "//third_party/webrtc/stats:rtc_stats_test_utils",
+ "//third_party/libyuv",
+ "//third_party/webrtc/api/task_queue:task_queue_test",
+ "//third_party/webrtc_overrides:webrtc_component",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/geometry/mojom:test_interfaces_blink",
@@ -2113,6 +2141,19 @@ fuzzer_test("blink_png_decoder_fuzzer") {
]
}
+# Fuzzer for blink::DateTimeFormat.
+fuzzer_test("blink_date_time_format_fuzzer") {
+ sources = [
+ "text/date_time_format_fuzzer.cc",
+ ]
+ deps = [
+ ":blink_fuzzer_test_support",
+ ":platform",
+ ]
+ dict = "//testing/libfuzzer/fuzzers/dicts/date.dict"
+ seed_corpus = "text/date_time_format_fuzzer_seed_corpus"
+}
+
# Fuzzer for blink::JSONParser.
fuzzer_test("blink_json_parser_fuzzer") {
sources = [
@@ -2208,7 +2249,6 @@ jumbo_source_set("unit_tests") {
"graphics/test/stub_image.h",
# Tests migrated from the web/tests directory.
- "exported/web_image_test.cc",
"exported/web_resource_timing_info_test.cc",
"exported/web_url_request_test.cc",
"exported/web_url_response_test.cc",
diff --git a/chromium/third_party/blink/renderer/platform/DEPS b/chromium/third_party/blink/renderer/platform/DEPS
index 9a37cb552a9..4d639942df5 100644
--- a/chromium/third_party/blink/renderer/platform/DEPS
+++ b/chromium/third_party/blink/renderer/platform/DEPS
@@ -29,6 +29,7 @@ include_rules = [
"+base/metrics/sparse_histogram.h",
"+base/numerics/checked_math.h",
"+base/numerics/safe_conversions.h",
+ "+base/process/memory.h",
"+base/rand_util.h",
"+base/run_loop.h",
"+base/strings/pattern.h",
@@ -56,8 +57,11 @@ include_rules = [
"+gpu/command_buffer/common/sync_token.h",
"+mojo/public",
"+mozilla",
+ "+services/metrics/public/cpp/metrics_utils.h",
+ "+services/metrics/public/cpp/ukm_builders.h",
"+services/metrics/public/cpp/ukm_entry_builder.h",
"+services/metrics/public/cpp/ukm_recorder.h",
+ "+services/metrics/public/cpp/ukm_source_id.h",
"+services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h",
"+skia/ext",
#TODO(nverne): remove this
diff --git a/chromium/third_party/blink/renderer/platform/OWNERS b/chromium/third_party/blink/renderer/platform/OWNERS
index 8b254a80be2..7a13e44d2ab 100644
--- a/chromium/third_party/blink/renderer/platform/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/OWNERS
@@ -6,6 +6,7 @@ eae@chromium.org
fmalita@chromium.org
fserb@chromium.org
haraken@chromium.org
+ikilpatrick@chromium.org
jbroman@chromium.org
jochen@chromium.org
kbr@chromium.org
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
index d7f6df2f35a..4ea0dacd875 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
@@ -138,4 +138,11 @@ void CompositorAnimation::NotifyAnimationTakeover(
}
}
+void CompositorAnimation::NotifyLocalTimeUpdated(
+ base::Optional<base::TimeDelta> local_time) {
+ if (delegate_) {
+ delegate_->NotifyLocalTimeUpdated(local_time);
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
index 10cc0861a7e..e900e473315 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
@@ -82,6 +82,8 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
int target_property,
base::TimeTicks animation_start_time,
std::unique_ptr<cc::AnimationCurve>) override;
+ void NotifyLocalTimeUpdated(
+ base::Optional<base::TimeDelta> local_time) override;
scoped_refptr<cc::SingleKeyframeEffectAnimation> animation_;
CompositorAnimationDelegate* delegate_;
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
index 62a81b379e3..06509423ca7 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
@@ -29,6 +29,8 @@ class PLATFORM_EXPORT CompositorAnimationDelegate {
double monotonic_time,
double animation_start_time,
std::unique_ptr<cc::AnimationCurve> curve) {}
+ virtual void NotifyLocalTimeUpdated(
+ base::Optional<base::TimeDelta> local_time) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
index 092be3c443c..c40fb3822d0 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
@@ -56,27 +56,32 @@ TEST_F(CompositorAnimationTest, NullDelegate) {
std::unique_ptr<CompositorAnimationDelegateForTesting> delegate(
new CompositorAnimationDelegateForTesting);
- std::unique_ptr<CompositorAnimation> animation =
- CompositorAnimation::Create();
+ auto timeline = std::make_unique<CompositorAnimationTimeline>();
+ std::unique_ptr<CompositorAnimationTestClient> client(
+ new CompositorAnimationTestClient);
+ CompositorAnimation* animation = client->GetCompositorAnimation();
cc::SingleKeyframeEffectAnimation* cc_animation = animation->CcAnimation();
+ timeline->AnimationAttached(*client);
+ int timeline_id = cc_animation->animation_timeline()->id();
auto curve = std::make_unique<CompositorFloatAnimationCurve>();
auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
*curve, compositor_target_property::TRANSFORM, 0, 1);
+ int keyframe_model_id = keyframe_model->Id();
animation->AddKeyframeModel(std::move(keyframe_model));
animation->SetAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->finished_);
cc_animation->NotifyKeyframeModelFinishedForTesting(
- compositor_target_property::TRANSFORM, 1);
+ timeline_id, keyframe_model_id, compositor_target_property::TRANSFORM, 1);
EXPECT_TRUE(delegate->finished_);
delegate->ResetFlags();
animation->SetAnimationDelegate(nullptr);
cc_animation->NotifyKeyframeModelFinishedForTesting(
- compositor_target_property::TRANSFORM, 1);
+ timeline_id, keyframe_model_id, compositor_target_property::TRANSFORM, 1);
EXPECT_FALSE(delegate->finished_);
}
@@ -84,30 +89,35 @@ TEST_F(CompositorAnimationTest, NotifyFromCCAfterCompositorAnimationDeletion) {
std::unique_ptr<CompositorAnimationDelegateForTesting> delegate(
new CompositorAnimationDelegateForTesting);
- std::unique_ptr<CompositorAnimation> animation =
- CompositorAnimation::Create();
+ auto timeline = std::make_unique<CompositorAnimationTimeline>();
+ std::unique_ptr<CompositorAnimationTestClient> client(
+ new CompositorAnimationTestClient);
+ CompositorAnimation* animation = client->GetCompositorAnimation();
scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
animation->CcAnimation();
+ timeline->AnimationAttached(*client);
+ int timeline_id = cc_animation->animation_timeline()->id();
auto curve = std::make_unique<CompositorFloatAnimationCurve>();
auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
*curve, compositor_target_property::OPACITY, 0, 1);
+ int keyframe_model_id = keyframe_model->Id();
animation->AddKeyframeModel(std::move(keyframe_model));
animation->SetAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->finished_);
cc_animation->NotifyKeyframeModelFinishedForTesting(
- compositor_target_property::OPACITY, 1);
+ timeline_id, keyframe_model_id, compositor_target_property::OPACITY, 1);
EXPECT_TRUE(delegate->finished_);
delegate->finished_ = false;
// Delete CompositorAnimation. ccAnimation stays alive.
- animation = nullptr;
+ client = nullptr;
// No notifications. Doesn't crash.
cc_animation->NotifyKeyframeModelFinishedForTesting(
- compositor_target_property::OPACITY, 1);
+ timeline_id, keyframe_model_id, compositor_target_property::OPACITY, 1);
EXPECT_FALSE(delegate->finished_);
}
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
index dd81d4b8b80..0740006764e 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
@@ -6,38 +6,19 @@
#include "third_party/blink/renderer/platform/animation/timing_function.h"
#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "cc/animation/timing_function.h"
using blink::CompositorScrollOffsetAnimationCurve;
-using DurationBehavior = cc::ScrollOffsetAnimationCurve::DurationBehavior;
namespace blink {
-static DurationBehavior GetDurationBehavior(
- CompositorScrollOffsetAnimationCurve::ScrollDurationBehavior
- web_duration_behavior) {
- switch (web_duration_behavior) {
- case CompositorScrollOffsetAnimationCurve::kScrollDurationDeltaBased:
- return DurationBehavior::DELTA_BASED;
-
- case CompositorScrollOffsetAnimationCurve::kScrollDurationConstant:
- return DurationBehavior::CONSTANT;
-
- case CompositorScrollOffsetAnimationCurve::kScrollDurationInverseDelta:
- return DurationBehavior::INVERSE_DELTA;
- }
- NOTREACHED();
- return DurationBehavior::DELTA_BASED;
-}
-
CompositorScrollOffsetAnimationCurve::CompositorScrollOffsetAnimationCurve(
FloatPoint target_value,
- ScrollDurationBehavior duration_behavior)
- : curve_(cc::ScrollOffsetAnimationCurve::Create(
+ ScrollType scroll_type)
+ : curve_(cc::ScrollOffsetAnimationCurveFactory::CreateAnimation(
gfx::ScrollOffset(target_value.X(), target_value.Y()),
- cc::CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- GetDurationBehavior(duration_behavior))) {}
+ scroll_type)) {}
CompositorScrollOffsetAnimationCurve::CompositorScrollOffsetAnimationCurve(
cc::ScrollOffsetAnimationCurve* curve)
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
index 92420b74497..87ba98a8908 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_curve.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -22,13 +23,9 @@ namespace blink {
class PLATFORM_EXPORT CompositorScrollOffsetAnimationCurve
: public CompositorAnimationCurve {
public:
- enum ScrollDurationBehavior {
- kScrollDurationDeltaBased = 0,
- kScrollDurationConstant,
- kScrollDurationInverseDelta
- };
+ using ScrollType = cc::ScrollOffsetAnimationCurveFactory::ScrollType;
- CompositorScrollOffsetAnimationCurve(FloatPoint, ScrollDurationBehavior);
+ CompositorScrollOffsetAnimationCurve(FloatPoint, ScrollType);
explicit CompositorScrollOffsetAnimationCurve(
cc::ScrollOffsetAnimationCurve*);
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_array.h b/chromium/third_party/blink/renderer/platform/audio/audio_array.h
index 7ff276e5b9e..0a8c263eb67 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_array.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_array.h
@@ -62,6 +62,8 @@ class AudioArray {
CHECK_LE(n, std::numeric_limits<unsigned>::max() / sizeof(T));
uint32_t initial_size = static_cast<uint32_t>(sizeof(T) * n);
+ // Minimmum alignment requirements for arrays so that we can use
+ // SIMD.
#if defined(ARCH_CPU_X86_FAMILY) || defined(WTF_USE_WEBAUDIO_FFMPEG)
const unsigned kAlignment = 32;
#else
@@ -71,32 +73,17 @@ class AudioArray {
if (allocation_)
WTF::Partitions::FastFree(allocation_);
- bool is_allocation_good = false;
-
- while (!is_allocation_good) {
- // Initially we try to allocate the exact size, but if it's not aligned
- // then we'll have to reallocate and from then on allocate extra.
- static unsigned extra_allocation_bytes = 0;
-
- unsigned total =
- base::CheckAdd(initial_size, extra_allocation_bytes).ValueOrDie();
- T* allocation = static_cast<T*>(WTF::Partitions::FastZeroedMalloc(
- total, WTF_HEAP_PROFILER_TYPE_NAME(AudioArray<T>)));
- CHECK(allocation);
-
- T* aligned_data = AlignedAddress(allocation, kAlignment);
-
- if (aligned_data == allocation || extra_allocation_bytes == kAlignment) {
- allocation_ = allocation;
- aligned_data_ = aligned_data;
- size_ = static_cast<uint32_t>(n);
- is_allocation_good = true;
- } else {
- // always allocate extra after the first alignment failure.
- extra_allocation_bytes = kAlignment;
- WTF::Partitions::FastFree(allocation);
- }
- }
+ // Always allocate extra space so that we are guaranteed to get
+ // the desired alignment. Some memory is wasted, but it should be
+ // small since most arrays are probably at least 128 floats (or
+ // doubles).
+ unsigned total = base::CheckAdd(initial_size, kAlignment).ValueOrDie();
+ allocation_ = static_cast<T*>(WTF::Partitions::FastZeroedMalloc(
+ total, WTF_HEAP_PROFILER_TYPE_NAME(AudioArray<T>)));
+ CHECK(allocation_);
+
+ aligned_data_ = AlignedAddress(allocation_, kAlignment);
+ size_ = static_cast<uint32_t>(n);
}
T* Data() { return aligned_data_; }
@@ -140,6 +127,8 @@ class AudioArray {
}
private:
+ // Return an address that is aligned to an |alignment| boundary.
+ // |alignment| MUST be a power of two!
static T* AlignedAddress(T* address, intptr_t alignment) {
intptr_t value = reinterpret_cast<intptr_t>(address);
return reinterpret_cast<T*>((value + alignment - 1) & ~(alignment - 1));
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
index 4a47aa8aaa8..3e2f1a5a3fa 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
@@ -31,6 +31,9 @@
namespace blink {
+// Delay nodes have a max allowed delay time of this many seconds.
+const float kMaxDelayTimeSeconds = 30;
+
AudioDelayDSPKernel::AudioDelayDSPKernel(AudioDSPKernelProcessor* processor,
size_t processing_size_in_frames)
: AudioDSPKernel(processor),
@@ -42,8 +45,9 @@ AudioDelayDSPKernel::AudioDelayDSPKernel(double max_delay_time,
: AudioDSPKernel(sample_rate),
max_delay_time_(max_delay_time),
write_index_(0) {
- DCHECK_GT(max_delay_time, 0.0);
- DCHECK(!std::isnan(max_delay_time));
+ DCHECK_GT(max_delay_time_, 0.0);
+ DCHECK_LE(max_delay_time_, kMaxDelayTimeSeconds);
+ DCHECK(std::isfinite(max_delay_time_));
size_t buffer_length = BufferLengthForDelay(max_delay_time, sample_rate);
DCHECK(buffer_length);
@@ -81,6 +85,8 @@ void AudioDelayDSPKernel::Process(const float* source,
DCHECK(buffer_length);
DCHECK(source);
DCHECK(destination);
+ DCHECK_GE(write_index_, 0);
+ DCHECK_LT(static_cast<size_t>(write_index_), buffer_length);
float sample_rate = this->SampleRate();
double max_time = MaxDelayTime();
@@ -89,37 +95,48 @@ void AudioDelayDSPKernel::Process(const float* source,
float* delay_times = delay_times_.Data();
CalculateSampleAccurateValues(delay_times, frames_to_process);
+ int w_index = write_index_;
+
for (unsigned i = 0; i < frames_to_process; ++i) {
double delay_time = delay_times[i];
+ // TODO(crbug.com/1013345): Don't need this if that bug is fixed
if (std::isnan(delay_time))
delay_time = max_time;
- else
- delay_time = clampTo(delay_time, 0.0, max_time);
double desired_delay_frames = delay_time * sample_rate;
- double read_position =
- write_index_ + buffer_length - desired_delay_frames;
+ double read_position = w_index + buffer_length - desired_delay_frames;
if (read_position >= buffer_length)
read_position -= buffer_length;
// Linearly interpolate in-between delay times.
int read_index1 = static_cast<int>(read_position);
- int read_index2 = (read_index1 + 1) % buffer_length;
+ DCHECK_GE(read_index1, 0);
+ DCHECK_LT(static_cast<size_t>(read_index1), buffer_length);
+ int read_index2 = read_index1 + 1;
+ if (read_index2 >= static_cast<int>(buffer_length))
+ read_index2 -= buffer_length;
+ DCHECK_GE(read_index2, 0);
+ DCHECK_LT(static_cast<size_t>(read_index2), buffer_length);
+
double interpolation_factor = read_position - read_index1;
- double input = static_cast<float>(*source++);
- buffer[write_index_] = static_cast<float>(input);
- write_index_ = (write_index_ + 1) % buffer_length;
+ buffer[w_index] = *source++;
- double sample1 = buffer[read_index1];
- double sample2 = buffer[read_index2];
+ ++w_index;
+ if (w_index >= static_cast<int>(buffer_length))
+ w_index -= buffer_length;
- double output = (1.0 - interpolation_factor) * sample1 +
- interpolation_factor * sample2;
+ float sample1 = buffer[read_index1];
+ float sample2 = buffer[read_index2];
+
+ double output =
+ (1 - interpolation_factor) * sample1 + interpolation_factor * sample2;
*destination++ = static_cast<float>(output);
}
+
+ write_index_ = w_index;
} else {
// This is basically the same as above, but optimized for the case where the
// delay time is constant for the current render.
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
index cecc59b797f..e5f1a294fda 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
@@ -40,7 +40,7 @@ class PLATFORM_EXPORT AudioDelayDSPKernel : public AudioDSPKernel {
uint32_t frames_to_process) override;
void Reset() override;
- double MaxDelayTime() const { return max_delay_time_; }
+ float MaxDelayTime() const { return max_delay_time_; }
void SetDelayFrames(double number_of_frames) {
desired_delay_frames_ = number_of_frames;
@@ -60,7 +60,11 @@ class PLATFORM_EXPORT AudioDelayDSPKernel : public AudioDSPKernel {
virtual double DelayTime(float sample_rate);
AudioFloatArray buffer_;
- double max_delay_time_;
+
+ // Time is usually best kept as a double, but AudioParams are inherently
+ // floats, so make this a float to keep everything consistent.
+ float max_delay_time_;
+
int write_index_;
double desired_delay_frames_;
diff --git a/chromium/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc b/chromium/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
index 158ac45e6bf..034ded03d11 100644
--- a/chromium/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
@@ -95,7 +95,7 @@ void HRTFDatabaseLoader::LoadAsynchronously() {
// Start the asynchronous database loading process.
thread_ = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kHRTFDatabaseLoaderThread));
+ ThreadCreationParams(ThreadType::kHRTFDatabaseLoaderThread));
// TODO(alexclarke): Should this be posted as a loading task?
PostCrossThreadTask(*thread_->GetTaskRunner(), FROM_HERE,
CrossThreadBindOnce(&HRTFDatabaseLoader::LoadTask,
diff --git a/chromium/third_party/blink/renderer/platform/audio/hrtf_elevation.cc b/chromium/third_party/blink/renderer/platform/audio/hrtf_elevation.cc
index 6bab81a2125..e90ce4089ef 100644
--- a/chromium/third_party/blink/renderer/platform/audio/hrtf_elevation.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/hrtf_elevation.cc
@@ -154,14 +154,32 @@ bool HRTFElevation::CalculateKernelsForAzimuthElevation(
AudioBus::CreateBufferFromRange(bus.get(), start_frame, stop_frame));
scoped_refptr<AudioBus> response(AudioBus::CreateBySampleRateConverting(
pre_sample_rate_converted_response.get(), false, sample_rate));
+
+ // Note that depending on the fftSize returned by the panner, we may be
+ // truncating the impulse response we just loaded in, or we might zero-pad it.
+ const size_t fft_size = HRTFPanner::FftSizeForSampleRate(sample_rate);
+
+ if (2 * response->length() < fft_size) {
+ // Need to resize the response buffer length so that it fis the fft size.
+ // Create a new response of the right length and copy over the current
+ // response.
+ scoped_refptr<AudioBus> padded_response(
+ AudioBus::Create(response->NumberOfChannels(), fft_size / 2));
+ for (unsigned channel = 0; channel < response->NumberOfChannels();
+ ++channel) {
+ memcpy(padded_response->Channel(channel)->MutableData(),
+ response->Channel(channel)->Data(),
+ response->length() * sizeof(float));
+ }
+ response = padded_response;
+ }
+ DCHECK_GE(2 * response->length(), fft_size);
+
AudioChannel* left_ear_impulse_response =
response->Channel(AudioBus::kChannelLeft);
AudioChannel* right_ear_impulse_response =
response->Channel(AudioBus::kChannelRight);
- // Note that depending on the fftSize returned by the panner, we may be
- // truncating the impulse response we just loaded in.
- const size_t fft_size = HRTFPanner::FftSizeForSampleRate(sample_rate);
kernel_l = std::make_unique<HRTFKernel>(left_ear_impulse_response, fft_size,
sample_rate);
kernel_r = std::make_unique<HRTFKernel>(right_ear_impulse_response, fft_size,
diff --git a/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc b/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
index 1e5db219d62..c775df565e1 100644
--- a/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
@@ -33,7 +33,7 @@ class FIFOClient {
bus_(AudioBus::Create(fifo->GetStateForTest().number_of_channels,
bus_length)),
client_thread_(Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("FIFOClientThread"))),
done_event_(std::make_unique<base::WaitableEvent>(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
diff --git a/chromium/third_party/blink/renderer/platform/audio/reverb_convolver.cc b/chromium/third_party/blink/renderer/platform/audio/reverb_convolver.cc
index 68b923ba2bb..c23912975bd 100644
--- a/chromium/third_party/blink/renderer/platform/audio/reverb_convolver.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/reverb_convolver.cc
@@ -138,8 +138,8 @@ ReverbConvolver::ReverbConvolver(AudioChannel* impulse_response,
// FIXME: would be better to up the thread priority here. It doesn't need to
// be real-time, but higher than the default...
if (use_background_threads && background_stages_.size() > 0) {
- background_thread_ = Platform::Current()->CreateThread(ThreadCreationParams(
- WebThreadType::kReverbConvolutionBackgroundThread));
+ background_thread_ = Platform::Current()->CreateThread(
+ ThreadCreationParams(ThreadType::kReverbConvolutionBackgroundThread));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/DEPS b/chromium/third_party/blink/renderer/platform/bindings/DEPS
index 8ccefe115cc..3ed54d7dab5 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/DEPS
+++ b/chromium/third_party/blink/renderer/platform/bindings/DEPS
@@ -8,6 +8,7 @@ include_rules = [
# Dependencies.
"+gin/public",
"+third_party/blink/renderer/platform/wtf/cross_thread_functional.h",
+ "+third_party/blink/renderer/platform/crypto.h",
"+third_party/blink/renderer/platform/heap",
"+third_party/blink/renderer/platform/instrumentation/instance_counters.h",
"+third_party/blink/renderer/platform/instrumentation",
diff --git a/chromium/third_party/blink/renderer/platform/bindings/OWNERS b/chromium/third_party/blink/renderer/platform/bindings/OWNERS
index 09f5935a58f..750dcc6a414 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/bindings/OWNERS
@@ -3,6 +3,3 @@ file://third_party/blink/renderer/bindings/OWNERS
# TEAM: blink-reviews-bindings@chromium.org
# COMPONENT: Blink>Bindings
-
-per-file *_messages*.h=set noparent
-per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/renderer/platform/bindings/RuntimeCallStats.md b/chromium/third_party/blink/renderer/platform/bindings/RuntimeCallStats.md
index 28e54316af7..c1aab521596 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/RuntimeCallStats.md
+++ b/chromium/third_party/blink/renderer/platform/bindings/RuntimeCallStats.md
@@ -2,11 +2,11 @@
## About
-RuntimeCallStats is a group of counters used to track execution times and call counts of functions in Blink during JS Execution. V8 has its own corresponding implementation of RuntimeCallStats, which is closely mirrored by Blink. Blink's implementation can be found in [RuntimeCallStats.h](RuntimeCallStats.h) and [RuntimeCallStats.cpp](RuntimeCallStats.cpp).
+`RuntimeCallStats` is a group of counters used to track execution times and call counts of functions in Blink during JS Execution. V8 has its own corresponding implementation of runtime_call_stats, which is closely mirrored by Blink. Blink's implementation can be found in [runtime_call_stats.h](runtime_call_stats.h) and [runtime_call_stats.cpp](runtime_call_stats.cpp).
## Usage
-Counters can be added by adding a name under one of the categories listed under FOR_EACH_COUNTER in RuntimeCallStats.h and by using the RUNTIME_CALL_TIMER_SCOPE, RUNTIME_CALL_STATS_ENTER and RUNTIME_CALL_STATS_LEAVE macros. See documentation in [RuntimeCallStats.h](RuntimeCallStats.h) for more details.
+Counters can be added by adding a name under one of the categories listed under FOR_EACH_COUNTER in runtime_call_stats.h and by using the RUNTIME_CALL_TIMER_SCOPE, RUNTIME_CALL_STATS_ENTER and RUNTIME_CALL_STATS_LEAVE macros. See documentation in [runtime_call_stats.h](runtime_call_stats.h) for more details.
Counters can also be directly added to the bindings layer in method and attribute callbacks by using the `[RuntimeCallStatsCounter]` IDL extended attribute (see [IDLExtendedAttributes.md](../../bindings/IDLExtendedAttributes.md#RuntimeCallStatsCounter_m_a) for more details).
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h b/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
new file mode 100644
index 00000000000..6ee38d858ba
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_DICTIONARY_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_DICTIONARY_BASE_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+namespace bindings {
+
+// This class is the base class for all IDL dictionary implementations. This is
+// designed to collaborate with NativeValueTraits and ToV8 with supporting type
+// dispatching (SFINAE, etc.).
+class PLATFORM_EXPORT DictionaryBase : public GarbageCollected<DictionaryBase> {
+ public:
+ virtual ~DictionaryBase() = default;
+
+ v8::Local<v8::Value> CreateV8Object(
+ v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context) const {
+ v8::Local<v8::Context> context = creation_context->CreationContext();
+ DCHECK(!context.IsEmpty());
+ v8::Local<v8::Object> v8_object;
+ {
+ v8::Context::Scope context_scope(context);
+ v8_object = v8::Object::New(isolate);
+ }
+ FillWithMembers(isolate, creation_context, v8_object);
+ return v8_object;
+ }
+
+ protected:
+ DictionaryBase() = default;
+
+ DictionaryBase(const DictionaryBase&) = delete;
+ DictionaryBase(const DictionaryBase&&) = delete;
+ DictionaryBase& operator=(const DictionaryBase&) = delete;
+ DictionaryBase& operator=(const DictionaryBase&&) = delete;
+
+ virtual void FillWithMembers(v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context,
+ v8::Local<v8::Object> v8_object) const = 0;
+};
+
+} // namespace bindings
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_DICTIONARY_BASE_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
index e582ad68741..975c6b567c9 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
@@ -173,8 +173,7 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
bool ContainsWrapper(const ScriptWrappable* object) {
if (is_main_world_)
return object->ContainsWrapper();
- return wrapper_map_.find(const_cast<ScriptWrappable*>(object)) !=
- wrapper_map_.end();
+ return wrapper_map_.find(object) != wrapper_map_.end();
}
virtual void Trace(Visitor*);
@@ -216,7 +215,7 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
bool is_main_world_;
// Ephemeron map: WrappedReference will be kept alive as long as
// ScriptWrappable is alive.
- HeapHashMap<WeakMember<ScriptWrappable>, Member<WrappedReference>>
+ HeapHashMap<WeakMember<const ScriptWrappable>, Member<WrappedReference>>
wrapper_map_;
DISALLOW_COPY_AND_ASSIGN(DOMDataStore);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/exception_messages.cc b/chromium/third_party/blink/renderer/platform/bindings/exception_messages.cc
index 545e3399b08..e23f01f1491 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/exception_messages.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/exception_messages.cc
@@ -122,6 +122,12 @@ String ExceptionMessages::ArgumentNullOrIncorrectType(
" object.";
}
+String ExceptionMessages::ArgumentNotOfType(int argument_index,
+ const char* expected_type) {
+ return String::Format("parameter %d is not of type '%s'.", argument_index + 1,
+ expected_type);
+}
+
String ExceptionMessages::NotASequenceTypeProperty(
const String& property_name) {
return "'" + property_name +
diff --git a/chromium/third_party/blink/renderer/platform/bindings/exception_messages.h b/chromium/third_party/blink/renderer/platform/bindings/exception_messages.h
index e509c74e8d2..6c11dabe5e8 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/exception_messages.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/exception_messages.h
@@ -52,6 +52,8 @@ class PLATFORM_EXPORT ExceptionMessages {
static String ArgumentNullOrIncorrectType(int argument_index,
const String& expected_type);
+ static String ArgumentNotOfType(int argument_index,
+ const char* expected_type);
static String ConstructorNotCallableAsFunction(const char* type);
static String FailedToConvertJSValue(const char* type);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
index 310c57cea15..c9f4ac49bd9 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -10,11 +10,13 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/process/memory.h"
#include "base/single_thread_task_runner.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
+#include "third_party/blink/renderer/platform/crypto.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -184,18 +186,53 @@ enum class ParkableStringImpl::Status : uint8_t {
kLocked
};
+// static
+std::unique_ptr<ParkableStringImpl::SecureDigest>
+ParkableStringImpl::HashString(StringImpl* string) {
+ DigestValue digest_result;
+ bool ok = ComputeDigest(kHashAlgorithmSha256,
+ static_cast<const char*>(string->Bytes()),
+ string->CharactersSizeInBytes(), digest_result);
+
+ // The only case where this can return false in BoringSSL is an allocation
+ // failure of the temporary data required for hashing. In this case, there
+ // is nothing better to do than crashing.
+ if (!ok) {
+ // Don't know the exact size, the SHA256 spec hints at ~64 (block size)
+ // + 32 (digest) bytes.
+ base::TerminateBecauseOutOfMemory(64 + kDigestSize);
+ }
+ // Unless SHA256 is... not 256 bits?
+ DCHECK(digest_result.size() == kDigestSize);
+ return std::make_unique<SecureDigest>(digest_result);
+}
+
+// static
+scoped_refptr<ParkableStringImpl> ParkableStringImpl::MakeNonParkable(
+ scoped_refptr<StringImpl>&& impl) {
+ return base::AdoptRef(new ParkableStringImpl(std::move(impl), nullptr));
+}
+
+// static
+scoped_refptr<ParkableStringImpl> ParkableStringImpl::MakeParkable(
+ scoped_refptr<StringImpl>&& impl,
+ std::unique_ptr<SecureDigest> digest) {
+ DCHECK(!!digest);
+ return base::AdoptRef(
+ new ParkableStringImpl(std::move(impl), std::move(digest)));
+}
+
ParkableStringImpl::ParkableStringImpl(scoped_refptr<StringImpl>&& impl,
- ParkableState parkable)
+ std::unique_ptr<SecureDigest> digest)
: mutex_(),
lock_depth_(0),
state_(State::kUnparked),
string_(std::move(impl)),
compressed_(nullptr),
+ digest_(std::move(digest)),
is_young_(true),
- may_be_parked_(parkable == ParkableState::kParkable),
is_8bit_(string_.Is8Bit()),
- length_(string_.length()),
- hash_(string_.Impl()->GetHash())
+ length_(string_.length())
#if DCHECK_IS_ON()
,
owning_thread_(CurrentThread())
@@ -217,7 +254,7 @@ ParkableStringImpl::~ParkableStringImpl() {
}
void ParkableStringImpl::Lock() {
- if (!may_be_parked_)
+ if (!may_be_parked())
return;
MutexLocker locker(mutex_);
@@ -269,55 +306,6 @@ void ParkableStringImpl::PurgeMemory() {
compressed_ = nullptr;
}
-bool ParkableStringImpl::Equal(const ParkableStringImpl& rhs) const {
- // This is called when two strings share the same bucket. Either string can
- // be parked.
- //
- // As a consequence, for a hash collision or true equality, a string can be
- // unparked in this function, making it expensive (see below).
- AssertOnValidThread();
-
- if (this == &rhs)
- return true;
-
- // The hash is actually only 24 bits. If collisions become an issue, replace
- // it either with a stronger one (murmur2 for instance), or switch to SHA256
- // and don't check for equality.
- if (GetHash() != rhs.GetHash() || length() != rhs.length())
- return false;
-
- // Can be expensive.
- //
- // Using the transient version because otherwise a lot of code in
- // ParkableStringManager becomes more reentrant than it already is, and many
- // parts of ParkableStringImpl would become mutable.
- // For instance, ToString() can unpark a string, and that would call into
- // ParkableStringManager::OnUnparked(), from ParkableStringManager::Add().
- //
- // Note that we only get here in two cases:
- // - Hash collision
- // - True equality
- //
- // Assuming that collisions are rare, unparking for true equality is not too
- // bad, as the obvious alternative is to compare a cryptographic hash. On
- // low-end ARM devices, unparking is roughly as expensive as SHA256, but we
- // only do it for one of the two strings, so this is still expected to be
- // faster than SHA256, at the cost of more memory (since both strings are held
- // in memory temporarily).
- return ToStringTransient() == rhs.ToStringTransient();
-}
-
-bool ParkableStringImpl::Equal(scoped_refptr<StringImpl> string) const {
- // See above for comments about cost of this function. This is called from
- // ParkableStringManager::Add() through ParkableStringImplTranslator.
- AssertOnValidThread();
-
- if (GetHash() != string->GetHash() || length() != string->length())
- return false;
-
- return ToStringTransient() == String(string);
-}
-
void ParkableStringImpl::MakeYoung() {
mutex_.AssertAcquired();
is_young_ = true;
@@ -335,16 +323,6 @@ const String& ParkableStringImpl::ToString() {
return string_;
}
-String ParkableStringImpl::ToStringTransient() const {
- AssertOnValidThread();
- if (!is_parked()) {
- AsanUnpoisonString(string_);
- return string_;
- }
-
- return UnparkInternal();
-}
-
unsigned ParkableStringImpl::CharactersSizeInBytes() const {
AssertOnValidThread();
return length_ * (is_8bit() ? sizeof(LChar) : sizeof(UChar));
@@ -638,8 +616,7 @@ ParkableString::ParkableString(scoped_refptr<StringImpl>&& impl) {
if (is_parkable) {
impl_ = ParkableStringManager::Instance().Add(std::move(impl));
} else {
- impl_ = base::MakeRefCounted<ParkableStringImpl>(
- std::move(impl), ParkableStringImpl::ParkableState::kNotParkable);
+ impl_ = ParkableStringImpl::MakeNonParkable(std::move(impl));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
index 96fa7f71b94..cd1b5ee2be8 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -41,17 +41,25 @@ struct CompressionTaskParams;
class PLATFORM_EXPORT ParkableStringImpl final
: public RefCounted<ParkableStringImpl> {
public:
- enum class ParkableState { kParkable, kNotParkable };
enum class ParkingMode { kIfCompressedDataExists, kAlways };
enum class AgeOrParkResult {
kSuccessOrTransientFailure,
kNonTransientFailure
};
- // Not all parkable strings can actually be parked. If |parkable| is
- // kNotParkable, then one cannot call |Park()|, and the underlying StringImpl
- // will not move.
- ParkableStringImpl(scoped_refptr<StringImpl>&& impl, ParkableState parkable);
+ constexpr static size_t kDigestSize = 32; // SHA256.
+ using SecureDigest = Vector<uint8_t, kDigestSize>;
+ // Computes a secure hash of a |string|, to be passed to |MakeParkable()|.
+ static std::unique_ptr<SecureDigest> HashString(StringImpl* string);
+
+ // Not all ParkableStringImpls are actually parkable.
+ static scoped_refptr<ParkableStringImpl> MakeNonParkable(
+ scoped_refptr<StringImpl>&& impl);
+ // |digest| is as returned by |HashString()|, hence not nullptr.
+ static scoped_refptr<ParkableStringImpl> MakeParkable(
+ scoped_refptr<StringImpl>&& impl,
+ std::unique_ptr<SecureDigest> digest);
+
~ParkableStringImpl();
void Lock();
@@ -93,7 +101,7 @@ class PLATFORM_EXPORT ParkableStringImpl final
// Returns true iff the string can be parked. This does not mean that the
// string can be parked now, merely that it is eligible to be parked at some
// point.
- bool may_be_parked() const { return may_be_parked_; }
+ bool may_be_parked() const { return !!digest_; }
// Returns true if the string is parked.
bool is_parked() const;
// Returns whether synchronous parking is possible, that is the string was
@@ -111,16 +119,22 @@ class PLATFORM_EXPORT ParkableStringImpl final
return is_young_;
}
+ // Must only be called on parkable ParkableStringImpls.
+ SecureDigest* digest() const {
+ AssertOnValidThread();
+ DCHECK(digest_);
+ return digest_.get();
+ }
+
private:
enum class State : uint8_t;
enum class Status : uint8_t;
friend class ParkableStringManager;
- unsigned GetHash() const { return hash_; }
-
- // Both functions below can be expensive (i.e. trigger unparking).
- bool Equal(const ParkableStringImpl& rhs) const;
- bool Equal(const scoped_refptr<StringImpl> rhs) const;
+ // |digest| is as returned by calling HashString() on |impl|, or nullptr for
+ // a non-parkable instance.
+ ParkableStringImpl(scoped_refptr<StringImpl>&& impl,
+ std::unique_ptr<SecureDigest> digest);
#if defined(ADDRESS_SANITIZER)
// See |CompressInBackground()|. Doesn't make the string young.
@@ -136,7 +150,6 @@ class PLATFORM_EXPORT ParkableStringImpl final
void ParkInternal(ParkingMode mode);
void Unpark();
String UnparkInternal() const;
- String ToStringTransient() const;
// Called on the main thread after compression is done.
// |params| is the same as the one passed to |CompressInBackground()|,
// |compressed| is the compressed data, nullptr if compression failed.
@@ -162,6 +175,7 @@ class PLATFORM_EXPORT ParkableStringImpl final
State state_;
String string_;
std::unique_ptr<Vector<uint8_t>> compressed_;
+ const std::unique_ptr<SecureDigest> digest_;
// A string can either be "young" or "old". It starts young, and transitions
// are:
@@ -173,11 +187,8 @@ class PLATFORM_EXPORT ParkableStringImpl final
// bitfield with a mutex, but this is correct here, as the other members are
// const (and never change).
bool is_young_ : 1 GUARDED_BY(mutex_);
-
- const bool may_be_parked_ : 1;
const bool is_8bit_ : 1;
const unsigned length_;
- const wtf_size_t hash_;
#if DCHECK_IS_ON()
const base::PlatformThreadId owning_thread_;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
index f3c6a8a3683..45da38a8126 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
@@ -62,38 +62,23 @@ class OnPurgeMemoryListener : public GarbageCollected<OnPurgeMemoryListener>,
} // namespace
-struct ParkableStringManager::ParkableStringImplHash {
- STATIC_ONLY(ParkableStringImplHash);
+// Compares not the pointers, but the arrays. Uses pointers to save space.
+struct ParkableStringManager::SecureDigestHash {
+ STATIC_ONLY(SecureDigestHash);
- static unsigned GetHash(ParkableStringImpl* key) { return key->GetHash(); }
-
- static inline bool Equal(const ParkableStringImpl* a,
- const ParkableStringImpl* b) {
- return a->Equal(*b);
- }
-
- static constexpr bool safe_to_compare_to_empty_or_deleted = false;
-};
-
-struct ParkableStringManager::ParkableStringImplTranslator {
- STATIC_ONLY(ParkableStringImplTranslator);
-
- static unsigned GetHash(const scoped_refptr<StringImpl>& string) {
- return string->GetHash();
+ static unsigned GetHash(ParkableStringImpl::SecureDigest* const digest) {
+ // The first bytes of the hash are as good as anything else.
+ return *reinterpret_cast<const unsigned*>(digest->data());
}
- static bool Equal(const ParkableStringImpl* parkable,
- const scoped_refptr<StringImpl>& string) {
- return parkable->Equal(string);
+ static inline bool Equal(ParkableStringImpl::SecureDigest* const a,
+ ParkableStringImpl::SecureDigest* const b) {
+ return a == b ||
+ std::equal(a->data(), a->data() + ParkableStringImpl::kDigestSize,
+ b->data());
}
- static void Translate(ParkableStringImpl*& new_parkable,
- scoped_refptr<StringImpl>&& string,
- unsigned hash) {
- new_parkable = new ParkableStringImpl(
- std::move(string), ParkableStringImpl::ParkableState::kParkable);
- DCHECK_EQ(hash, new_parkable->GetHash());
- }
+ static constexpr bool safe_to_compare_to_empty_or_deleted = false;
};
// static
@@ -170,33 +155,25 @@ scoped_refptr<ParkableStringImpl> ParkableStringManager::Add(
ScheduleAgingTaskIfNeeded();
- scoped_refptr<StringImpl> string_ptr(string);
- // Hit in either the unparked or parked strings.
- auto it = unparked_strings_
- .Find<ParkableStringImplTranslator, scoped_refptr<StringImpl>>(
- string_ptr);
+ auto string_impl = string;
+ auto digest = ParkableStringImpl::HashString(string_impl.get());
+ DCHECK(digest.get());
+
+ auto it = unparked_strings_.find(digest.get());
if (it != unparked_strings_.end())
- return *it;
+ return it->value;
- // This is an "expensive hit", as we unparked then discarded the unparked
- // representation of a string.
- //
- // If this is problematic, we can unpark the string for "free" (since the
- // incoming) string is unparked and has the same content, or change the
- // interface. Note that at the same time the hit means that we avoided an
- // expensive compression task.
- it = parked_strings_
- .Find<ParkableStringImplTranslator, scoped_refptr<StringImpl>>(
- string_ptr);
+ it = parked_strings_.find(digest.get());
if (it != parked_strings_.end())
- return *it;
+ return it->value;
+
+ auto new_parkable = ParkableStringImpl::MakeParkable(std::move(string_impl),
+ std::move(digest));
// No hit, new unparked string.
- auto add_result =
- unparked_strings_.AddWithTranslator<ParkableStringImplTranslator,
- scoped_refptr<StringImpl>>(
- std::move(string_ptr));
- DCHECK(add_result.is_new_entry);
+ auto insert_result =
+ unparked_strings_.insert(new_parkable->digest(), new_parkable.get());
+ DCHECK(insert_result.is_new_entry);
// Lazy registration because registering too early can cause crashes on Linux,
// see crbug.com/930117, and registering without any strings is pointless
@@ -221,18 +198,20 @@ scoped_refptr<ParkableStringImpl> ParkableStringManager::Add(
has_posted_unparking_time_accounting_task_ = true;
}
- return base::AdoptRef(*add_result.stored_value);
+ return new_parkable;
}
void ParkableStringManager::Remove(ParkableStringImpl* string) {
DCHECK(IsMainThread());
DCHECK(string->may_be_parked());
+ DCHECK(string->digest());
+
if (string->is_parked()) {
- auto it = parked_strings_.find(string);
+ auto it = parked_strings_.find(string->digest());
DCHECK(it != parked_strings_.end());
parked_strings_.erase(it);
} else {
- auto it = unparked_strings_.find(string);
+ auto it = unparked_strings_.find(string->digest());
DCHECK(it != unparked_strings_.end());
unparked_strings_.erase(it);
}
@@ -242,22 +221,22 @@ void ParkableStringManager::OnParked(ParkableStringImpl* newly_parked_string) {
DCHECK(IsMainThread());
DCHECK(newly_parked_string->may_be_parked());
DCHECK(newly_parked_string->is_parked());
- auto it = unparked_strings_.find(newly_parked_string);
+ auto it = unparked_strings_.find(newly_parked_string->digest());
DCHECK(it != unparked_strings_.end());
- DCHECK_EQ(*it, newly_parked_string);
+ DCHECK_EQ(it->value, newly_parked_string);
unparked_strings_.erase(it);
- parked_strings_.insert(newly_parked_string);
+ parked_strings_.insert(newly_parked_string->digest(), newly_parked_string);
}
void ParkableStringManager::OnUnparked(ParkableStringImpl* was_parked_string) {
DCHECK(IsMainThread());
DCHECK(was_parked_string->may_be_parked());
DCHECK(!was_parked_string->is_parked());
- auto it = parked_strings_.find(was_parked_string);
+ auto it = parked_strings_.find(was_parked_string->digest());
DCHECK(it != parked_strings_.end());
- DCHECK_EQ(*it, was_parked_string);
+ DCHECK_EQ(it->value, was_parked_string);
parked_strings_.erase(it);
- unparked_strings_.insert(was_parked_string);
+ unparked_strings_.insert(was_parked_string->digest(), was_parked_string);
ScheduleAgingTaskIfNeeded();
}
@@ -271,8 +250,8 @@ void ParkableStringManager::ParkAll(ParkableStringImpl::ParkingMode mode) {
DCHECK(CompressionEnabled());
size_t total_size = 0;
- for (ParkableStringImpl* str : parked_strings_)
- total_size += str->CharactersSizeInBytes();
+ for (const auto& kv : parked_strings_)
+ total_size += kv.value->CharactersSizeInBytes();
// Parking may be synchronous, need to copy values first.
// In case of synchronous parking, |ParkableStringImpl::Park()| calls
@@ -376,16 +355,16 @@ void ParkableStringManager::PurgeMemory() {
// synchronously (and no longer in |unparked_strings_|), or being parked and
// purging is a no-op.
if (!IsRendererBackgrounded()) {
- for (ParkableStringImpl* str : unparked_strings_)
- str->PurgeMemory();
+ for (const auto& kv : unparked_strings_)
+ kv.value->PurgeMemory();
}
}
Vector<ParkableStringImpl*> ParkableStringManager::GetUnparkedStrings() const {
WTF::Vector<ParkableStringImpl*> unparked;
unparked.ReserveCapacity(unparked_strings_.size());
- for (ParkableStringImpl* str : unparked_strings_)
- unparked.push_back(str);
+ for (const auto& kv : unparked_strings_)
+ unparked.push_back(kv.value);
return unparked;
}
@@ -393,23 +372,29 @@ Vector<ParkableStringImpl*> ParkableStringManager::GetUnparkedStrings() const {
ParkableStringManager::Statistics ParkableStringManager::ComputeStatistics()
const {
ParkableStringManager::Statistics stats = {};
+ // The digest has an inline capacity set to the digest size, hence sizeof() is
+ // accurate.
+ constexpr size_t kParkableStringImplActualSize =
+ sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::SecureDigest);
- for (ParkableStringImpl* str : unparked_strings_) {
+ for (const auto& kv : unparked_strings_) {
+ ParkableStringImpl* str = kv.value;
size_t size = str->CharactersSizeInBytes();
stats.original_size += size;
stats.uncompressed_size += size;
- stats.metadata_size += sizeof(ParkableStringImpl);
+ stats.metadata_size += kParkableStringImplActualSize;
if (str->has_compressed_data())
stats.overhead_size += str->compressed_size();
}
- for (ParkableStringImpl* str : parked_strings_) {
+ for (const auto& kv : parked_strings_) {
+ ParkableStringImpl* str = kv.value;
size_t size = str->CharactersSizeInBytes();
stats.compressed_original_size += size;
stats.original_size += size;
stats.compressed_size += str->compressed_size();
- stats.metadata_size += sizeof(ParkableStringImpl);
+ stats.metadata_size += kParkableStringImplActualSize;
}
stats.total_size = stats.uncompressed_size + stats.compressed_size +
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
index 5aefb0984ac..ecc958b620f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
@@ -70,8 +70,7 @@ class PLATFORM_EXPORT ParkableStringManager {
private:
friend class ParkableString;
friend class ParkableStringImpl;
- struct ParkableStringImplHash;
- struct ParkableStringImplTranslator;
+ struct SecureDigestHash;
scoped_refptr<ParkableStringImpl> Add(scoped_refptr<StringImpl>&&);
void Remove(ParkableStringImpl*);
@@ -100,8 +99,17 @@ class PLATFORM_EXPORT ParkableStringManager {
bool did_register_memory_pressure_listener_;
base::TimeDelta total_unparking_time_;
base::TimeDelta total_parking_thread_time_;
- WTF::HashSet<ParkableStringImpl*, ParkableStringImplHash> unparked_strings_;
- WTF::HashSet<ParkableStringImpl*, ParkableStringImplHash> parked_strings_;
+
+ // Relies on secure hash equality for deduplication. If one day SHA256 becomes
+ // insecure, then this would need to be updated to a more robust hash.
+ WTF::HashMap<ParkableStringImpl::SecureDigest*,
+ ParkableStringImpl*,
+ SecureDigestHash>
+ unparked_strings_;
+ WTF::HashMap<ParkableStringImpl::SecureDigest*,
+ ParkableStringImpl*,
+ SecureDigestHash>
+ parked_strings_;
friend class ParkableStringTest;
FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, SynchronousCompression);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
index 970245a9599..a6b796743d6 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
@@ -91,7 +91,6 @@ class ParkableStringTest : public ::testing::Test {
task_environment_.FastForwardUntilNoTasksRemain();
}
-
ParkableString CreateAndParkAll() {
auto& manager = ParkableStringManager::Instance();
// Checking that there are no other strings, to make sure this doesn't
@@ -194,22 +193,6 @@ TEST_F(ParkableStringTest, Simple) {
EXPECT_EQ(copy.Impl(), parkable_abc.Impl());
}
-TEST_F(ParkableStringTest, Equality) {
- ParkableString abc(String("abc").ReleaseImpl());
- ParkableString abc2(String("abc").ReleaseImpl());
-
- EXPECT_NE(abc.ToString().Impl(), abc2.ToString().Impl());
- EXPECT_TRUE(abc.Impl()->Equal(*abc2.Impl()));
-
- // Should not crash. Unlocking poisons the string with ASAN, checks that we
- // unpoison it correctly when calling Equal().
- ParkableString parkable(MakeLargeString('a').ReleaseImpl());
- parkable.Lock();
- parkable.Unlock();
- ParkableString parkable2(MakeLargeString('a').ReleaseImpl());
- EXPECT_EQ(parkable.Impl(), parkable2.Impl());
-}
-
TEST_F(ParkableStringTest, Park) {
{
ParkableString parkable(MakeLargeString('a').ReleaseImpl());
@@ -256,7 +239,6 @@ TEST_F(ParkableStringTest, EqualityNoUnparking) {
ParkableString parkable_copy(copy.Impl());
EXPECT_EQ(parkable_copy.Impl(), parkable.Impl()); // De-duplicated.
- EXPECT_TRUE(parkable_copy.Impl()->Equal(*parkable.Impl()));
EXPECT_TRUE(parkable.Impl()->is_parked());
EXPECT_TRUE(parkable_copy.Impl()->is_parked());
@@ -665,14 +647,16 @@ TEST_F(ParkableStringTest, ReportMemoryDump) {
kCompressedSize);
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(overhead))));
+ constexpr size_t kParkableStringImplActualSize =
+ sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::SecureDigest);
MemoryAllocatorDump::Entry metadata("metadata_size", "bytes",
- 2 * sizeof(ParkableStringImpl));
+ 2 * kParkableStringImplActualSize);
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(metadata))));
MemoryAllocatorDump::Entry savings(
"savings_size", "bytes",
- 2 * kStringSize -
- (kStringSize + 2 * kCompressedSize + 2 * sizeof(ParkableStringImpl)));
+ 2 * kStringSize - (kStringSize + 2 * kCompressedSize +
+ 2 * kParkableStringImplActualSize));
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(savings))));
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h b/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h
new file mode 100644
index 00000000000..03a87e9e10c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
+#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// A ref counted version of ScopedPersistent. This class is intended for use by
+// ScriptValue and not for normal use. Consider using ScopedPersistent directly
+// instead.
+// TODO(crbug.com/1029738): Remove once bug is fixed.
+template <typename T>
+class SharedPersistent : public RefCounted<SharedPersistent<T>> {
+ USING_FAST_MALLOC(SharedPersistent);
+
+ public:
+ static scoped_refptr<SharedPersistent<T>> Create(v8::Isolate* isolate,
+ v8::Local<T> value) {
+ return base::AdoptRef(new SharedPersistent<T>(isolate, value));
+ }
+
+ // Returns the V8 reference. Crashes if |world_| is set and it is
+ // different from |target_script_state|'s world.
+ v8::Local<T> Get(ScriptState* target_script_state) const {
+ DCHECK(!value_.IsEmpty());
+ if (world_) {
+ CHECK_EQ(world_.get(), &target_script_state->World());
+ }
+ return value_.NewLocal(target_script_state->GetIsolate());
+ }
+
+ // Returns a V8 reference that is safe to access in |target_script_state|.
+ // The return value may be a cloned object.
+ v8::Local<T> GetAcrossWorld(ScriptState* target_script_state) const {
+ CHECK(world_);
+ DCHECK(!value_.IsEmpty());
+
+ v8::Isolate* isolate = target_script_state->GetIsolate();
+
+ if (world_ == &target_script_state->World())
+ return value_.NewLocal(isolate);
+
+ // If |v8_reference| is a v8::Object, clones |v8_reference| in the context
+ // of |target_script_state| and returns it. Otherwise returns
+ // |v8_reference| itself that is already safe to access in
+ // |target_script_state|.
+
+ v8::Local<v8::Value> value = value_.NewLocal(isolate);
+ DCHECK(value->IsObject());
+ return value.template As<T>();
+ }
+
+ bool IsEmpty() { return value_.IsEmpty(); }
+
+ bool operator==(const SharedPersistent<T>& other) {
+ return value_ == other.value_;
+ }
+
+ private:
+ explicit SharedPersistent(v8::Isolate* isolate, v8::Local<T> value)
+ : value_(isolate, value) {
+ DCHECK(!value.IsEmpty());
+ // Basically, |world_| is a world when this V8 reference is created.
+ // However, when this V8 reference isn't created in context and value is
+ // object, we set |world_| to a value's creation cotext's world.
+ if (isolate->InContext()) {
+ world_ = &DOMWrapperWorld::Current(isolate);
+ if (value->IsObject()) {
+ v8::Local<v8::Context> context =
+ value.template As<v8::Object>()->CreationContext();
+ // Creation context is null if the value is a remote object.
+ if (!context.IsEmpty()) {
+ ScriptState* script_state = ScriptState::From(context);
+ CHECK_EQ(world_.get(), &script_state->World());
+ }
+ }
+ } else if (value->IsObject()) {
+ ScriptState* script_state =
+ ScriptState::From(value.template As<v8::Object>()->CreationContext());
+ world_ = &script_state->World();
+ }
+ }
+
+ ScopedPersistent<T> value_;
+ // The world of the current context at the time when |value_| was set.
+ // It's guaranteed that, if |value_| is a v8::Object, the world of the
+ // creation context of |value_| is the same as |world_|.
+ scoped_refptr<const DOMWrapperWorld> world_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedPersistent);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
index f3126cf8a6f..246140e5dcd 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
@@ -12,8 +12,10 @@
#include "base/containers/span.h"
#include "base/optional.h"
+#include "base/time/time.h"
#include "third_party/blink/renderer/platform/bindings/callback_function_base.h"
#include "third_party/blink/renderer/platform/bindings/callback_interface_base.h"
+#include "third_party/blink/renderer/platform/bindings/dictionary_base.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -40,6 +42,19 @@ inline v8::Local<v8::Value> ToV8(ScriptWrappable* impl,
return wrapper;
}
+// Dictionary
+
+inline v8::Local<v8::Value> ToV8(bindings::DictionaryBase* dictionary,
+ v8::Local<v8::Object> creation_context,
+ v8::Isolate* isolate) {
+ if (UNLIKELY(!dictionary))
+ return v8::Null(isolate);
+ v8::Local<v8::Value> v8_value =
+ dictionary->CreateV8Object(isolate, creation_context);
+ DCHECK(!v8_value.IsEmpty());
+ return v8_value;
+}
+
// Callback function
inline v8::Local<v8::Value> ToV8(CallbackFunctionBase* callback,
@@ -323,6 +338,12 @@ inline v8::Local<v8::Value> ToV8(T&& value, ScriptState* script_state) {
script_state->GetIsolate());
}
+// Date
+inline v8::Local<v8::Value> ToV8(base::Time date, ScriptState* script_state) {
+ return v8::Date::New(script_state->GetContext(), date.ToJsTimeIgnoringNull())
+ .ToLocalChecked();
+}
+
// Only declare ToV8(void*,...) for checking function overload mismatch.
// This ToV8(void*,...) should be never used. So we will find mismatch
// because of "unresolved external symbol".
diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
index d11fd0c3acc..a635b0adb10 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
@@ -120,4 +120,25 @@ class TraceWrapperV8Reference {
} // namespace blink
+namespace WTF {
+
+template <typename T>
+struct IsTraceable<blink::TraceWrapperV8Reference<T>> {
+ STATIC_ONLY(IsTraceable);
+ static const bool value = true;
+};
+
+template <typename T>
+struct VectorTraits<blink::TraceWrapperV8Reference<T>>
+ : VectorTraitsBase<blink::TraceWrapperV8Reference<T>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanCopyWithMemcpy = false;
+ static const bool kCanMoveWithMemcpy = false;
+};
+
+} // namespace WTF
+
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_TRACE_WRAPPER_V8_REFERENCE_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h b/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
index 53b2bddb02b..2ec174ff7aa 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
@@ -34,6 +34,16 @@
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "v8/include/v8.h"
+#if defined(OS_WIN)
+#if !defined(alloca)
+// Windows uses _alloca instead of alloca, but only #define's alloca to _alloca
+// in malloc.h if _CRT_INTERNAL_NONSTDC_NAMES is defined. If that doesn't happen
+// (e.g. on Windows on Arm), fix up the definition.
+#include <malloc.h>
+#define alloca _alloca
+#endif
+#endif
+
namespace blink {
// type is an instance of class template V8StringResource<>,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
index f77d0dccdbc..6c25c30dcb3 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
@@ -55,7 +55,7 @@ constexpr char kInterfaceMapLabel[] =
} // namespace
-// Wrapper function defined in WebKit.h
+// Wrapper function defined in blink.h
v8::Isolate* MainThreadIsolate() {
return V8PerIsolateData::MainThreadIsolate();
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.cc
index 2fc7ea7355a..50294775bcb 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.cc
@@ -11,6 +11,18 @@
namespace blink {
+// As SymbolKey is widely used, numerous instances of SymbolKey are created,
+// plus all the instances have static storage duration (defined as static
+// variables). Thus, it's important to make SymbolKey
+// trivially-constructible/destructible so that compilers can remove all the
+// constructor/destructor calls and reduce the code size.
+static_assert(
+ std::is_trivially_constructible<V8PrivateProperty::SymbolKey>::value,
+ "SymbolKey is not trivially constructible");
+static_assert(
+ std::is_trivially_destructible<V8PrivateProperty::SymbolKey>::value,
+ "SymbolKey is not trivially destructible");
+
v8::MaybeLocal<v8::Value> V8PrivateProperty::Symbol::GetFromMainWorld(
ScriptWrappable* script_wrappable) {
v8::Local<v8::Object> wrapper = script_wrappable->MainWorldWrapper(isolate_);
@@ -18,16 +30,48 @@ v8::MaybeLocal<v8::Value> V8PrivateProperty::Symbol::GetFromMainWorld(
: GetOrUndefined(wrapper);
}
-v8::Local<v8::Private> V8PrivateProperty::CreateV8Private(v8::Isolate* isolate,
- const char* symbol) {
- return v8::Private::New(isolate, V8String(isolate, symbol));
+V8PrivateProperty::Symbol V8PrivateProperty::GetWindowDocumentCachedAccessor(
+ v8::Isolate* isolate) {
+ V8PrivateProperty* private_prop =
+ V8PerIsolateData::From(isolate)->PrivateProperty();
+ if (UNLIKELY(
+ private_prop->symbol_window_document_cached_accessor_.IsEmpty())) {
+ // This private property is used in Window, and Window and Document are
+ // stored in the V8 context snapshot. So, this private property needs to
+ // be restorable from the snapshot, and only v8::Private::ForApi supports
+ // it so far.
+ //
+ // TODO(peria): Explore a better way to connect a Document to a Window.
+ v8::Local<v8::Private> private_symbol = v8::Private::ForApi(
+ isolate, V8String(isolate, "Window#DocumentCachedAccessor"));
+ private_prop->symbol_window_document_cached_accessor_.Set(isolate,
+ private_symbol);
+ }
+ return Symbol(
+ isolate,
+ private_prop->symbol_window_document_cached_accessor_.NewLocal(isolate));
}
-v8::Local<v8::Private> V8PrivateProperty::CreateCachedV8Private(
+V8PrivateProperty::Symbol V8PrivateProperty::GetSymbol(
v8::Isolate* isolate,
- const char* symbol) {
- // Use ForApi() to get the same Private symbol which is not cached in Chrome.
- return v8::Private::ForApi(isolate, V8String(isolate, symbol));
+ const V8PrivateProperty::SymbolKey& key) {
+ V8PrivateProperty* private_prop =
+ V8PerIsolateData::From(isolate)->PrivateProperty();
+ auto& symbol_map = private_prop->symbol_map_;
+ auto iter = symbol_map.find(&key);
+ v8::Local<v8::Private> v8_private;
+ if (UNLIKELY(iter == symbol_map.end())) {
+ v8_private = CreateV8Private(isolate, nullptr);
+ symbol_map.insert(&key, v8::Eternal<v8::Private>(isolate, v8_private));
+ } else {
+ v8_private = iter->value.Get(isolate);
+ }
+ return Symbol(isolate, v8_private);
+}
+
+v8::Local<v8::Private> V8PrivateProperty::CreateV8Private(v8::Isolate* isolate,
+ const char* symbol) {
+ return v8::Private::New(isolate, V8String(isolate, symbol));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
index 6d41991be21..864454f18c2 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
@@ -20,66 +20,16 @@ namespace blink {
class ScriptWrappable;
-// TODO(peria): Remove properties just to keep V8 objects alive.
-// e.g. IDBCursor.Request.
-// Apply |X| for each pair of (InterfaceName, PrivateKeyName).
-#define V8_PRIVATE_PROPERTY_FOR_EACH(X) \
- X(CustomElement, Document) \
- X(CustomElement, IsInterfacePrototypeObject) \
- X(CustomElement, NamespaceURI) \
- X(CustomElement, TagName) \
- X(CustomElement, Type) \
- X(CustomElementLifecycle, AttachedCallback) \
- X(CustomElementLifecycle, AttributeChangedCallback) \
- X(CustomElementLifecycle, CreatedCallback) \
- X(CustomElementLifecycle, DetachedCallback) \
- X(DOMException, Error) \
- X(Global, Event) \
- X(IDBCursor, Request) \
- X(IntersectionObserver, Callback) \
- X(MessageChannel, Port1) \
- X(MessageChannel, Port2) \
- X(MessageEvent, CachedData) \
- X(MutationObserver, Callback) \
- X(NamedConstructor, Initialized) \
- X(PopStateEvent, State) \
- X(SameObject, DetectedBarcodeCornerPoints) \
- X(SameObject, DetectedFaceLandmarks) \
- X(SameObject, NotificationActions) \
- X(SameObject, NotificationData) \
- X(SameObject, NotificationVibrate) \
- X(SameObject, PerformanceLongTaskTimingAttribution) \
- X(SameObject, PerformanceObserverSupportedEntryTypes) \
- X(SameObject, PushManagerSupportedContentEncodings) \
- X(SameObject, XRInputSourceProfiles) \
- X(SameObject, XRInputSourcesChangeEventAdded) \
- X(SameObject, XRInputSourcesChangeEventRemoved) \
- X(SameObject, XRViewerPoseViews) \
- SCRIPT_PROMISE_PROPERTIES(X, Promise) \
- SCRIPT_PROMISE_PROPERTIES(X, Resolver)
-
-// The getter's name for a private property.
-#define V8_PRIVATE_PROPERTY_GETTER_NAME(InterfaceName, PrivateKeyName) \
- Get##InterfaceName##PrivateKeyName
-
-// The string used to create a private symbol. Must be unique per V8 instance.
-#define V8_PRIVATE_PROPERTY_SYMBOL_STRING(InterfaceName, PrivateKeyName) \
- #InterfaceName "#" #PrivateKeyName // NOLINT(whitespace/indent)
-
-// Provides access to V8's private properties.
+// Provides access to V8's private properties with a symbol key.
//
-// Usage 1) Fast path to use a pre-registered symbol.
-// auto private_property = V8PrivateProperty::GetDOMExceptionError(isolate);
+// static const V8PrivateProperty::SymbolKey kPrivateProperty;
+// auto private_property = V8PrivateProperty::GetSymbol(
+// isolate, kPrivateProperty);
// v8::Local<v8::Object> object = ...;
// v8::Local<v8::Value> value;
// if (!private_property.GetOrUndefined(object).ToLocal(&value)) return;
// value = ...;
-// private_property.set(object, value);
-//
-// Usage 2) Slow path to create a global private symbol.
-// const char symbol_name[] = "Interface#PrivateKeyName";
-// auto private_property =
-// V8PrivateProperty::GetSymbol(isolate, symbol_name);
+// private_property.Set(object, value);
// ...
class PLATFORM_EXPORT V8PrivateProperty {
USING_FAST_MALLOC(V8PrivateProperty);
@@ -126,7 +76,6 @@ class PLATFORM_EXPORT V8PrivateProperty {
friend class V8PrivateProperty;
// The following classes are exceptionally allowed to call to
// getFromMainWorld.
- friend class V8CustomEvent;
friend class V8ExtendableMessageEvent;
Symbol(v8::Isolate* isolate, v8::Local<v8::Private> private_symbol)
@@ -145,36 +94,22 @@ class PLATFORM_EXPORT V8PrivateProperty {
v8::Isolate* isolate_;
};
-#define V8_PRIVATE_PROPERTY_DEFINE_GETTER(InterfaceName, KeyName) \
- static Symbol V8_PRIVATE_PROPERTY_GETTER_NAME(/* // NOLINT */ \
- InterfaceName, KeyName)( \
- v8::Isolate * isolate) { \
- /* This key is used for uniquely identifying v8::Private. */ \
- static int private_property_key; \
- return GetSymbol( \
- isolate, &private_property_key, \
- V8_PRIVATE_PROPERTY_SYMBOL_STRING(InterfaceName, KeyName)); \
- }
+ // This class is used for a key to get Symbol.
+ //
+ // We can improve ability of tracking private properties by using an instance
+ // of this class.
+ class PLATFORM_EXPORT SymbolKey final {
+ public:
+ SymbolKey() = default;
- V8_PRIVATE_PROPERTY_FOR_EACH(V8_PRIVATE_PROPERTY_DEFINE_GETTER)
-#undef V8_PRIVATE_PROPERTY_DEFINE_GETTER
+ private:
+ SymbolKey(const SymbolKey&) = delete;
+ SymbolKey& operator=(const SymbolKey&) = delete;
+ };
// TODO(peria): Do not use this specialized hack. See a TODO comment
// on m_symbolWindowDocumentCachedAccessor.
- static Symbol GetWindowDocumentCachedAccessor(v8::Isolate* isolate) {
- V8PrivateProperty* private_prop =
- V8PerIsolateData::From(isolate)->PrivateProperty();
- if (UNLIKELY(
- private_prop->symbol_window_document_cached_accessor_.IsEmpty())) {
- private_prop->symbol_window_document_cached_accessor_.Set(
- isolate, CreateCachedV8Private(
- isolate, V8_PRIVATE_PROPERTY_SYMBOL_STRING(
- "Window", "DocumentCachedAccessor")));
- }
- return Symbol(
- isolate, private_prop->symbol_window_document_cached_accessor_.NewLocal(
- isolate));
- }
+ static Symbol GetWindowDocumentCachedAccessor(v8::Isolate* isolate);
static Symbol GetCachedAccessor(v8::Isolate* isolate,
CachedAccessorSymbol symbol_id) {
@@ -185,45 +120,29 @@ class PLATFORM_EXPORT V8PrivateProperty {
break;
}
NOTREACHED();
- return GetSymbol(isolate, "unexpected cached accessor");
+ return GetEmptySymbol();
}
// This is a hack for PopStateEvent to get the same private property of
// History, named State.
static Symbol GetHistoryStateSymbol(v8::Isolate* isolate) {
- // This key is used for uniquely identifying v8::Private.
- static int private_property_key;
- return GetSymbol(isolate, &private_property_key, "History#State");
- }
-
- static Symbol GetSymbol(v8::Isolate* isolate, const char* symbol) {
- return Symbol(isolate, CreateCachedV8Private(isolate, symbol));
+ static const SymbolKey kPrivatePropertyKey;
+ return GetSymbol(isolate, kPrivatePropertyKey);
}
// Returns a Symbol to access a private property. Symbol instances from same
- // |key|s are guaranteed to access the same property. |desc| is a description
- // of the property.
- static Symbol GetSymbol(v8::Isolate* isolate, void* key, const char* desc) {
- V8PrivateProperty* private_prop =
- V8PerIsolateData::From(isolate)->PrivateProperty();
- auto& symbol_map = private_prop->symbol_map_;
- auto iter = symbol_map.find(key);
- v8::Local<v8::Private> v8_private;
- if (UNLIKELY(iter == symbol_map.end())) {
- v8_private = CreateV8Private(isolate, desc);
- symbol_map.insert(key, v8::Eternal<v8::Private>(isolate, v8_private));
- } else {
- v8_private = iter->value.Get(isolate);
- }
- return Symbol(isolate, v8_private);
+ // |key| are guaranteed to access the same property.
+ static Symbol GetSymbol(v8::Isolate* isolate, const SymbolKey& key);
+
+ // This function is always called after NOTREACHED(). The Symbol returned from
+ // this function must not be used.
+ static Symbol GetEmptySymbol() {
+ return Symbol(nullptr, v8::Local<v8::Private>());
}
private:
static v8::Local<v8::Private> CreateV8Private(v8::Isolate*,
const char* symbol);
- // TODO(peria): Remove this method. We should not use v8::Private::ForApi().
- static v8::Local<v8::Private> CreateCachedV8Private(v8::Isolate*,
- const char* symbol);
// TODO(peria): Do not use this specialized hack for
// Window#DocumentCachedAccessor. This is required to put v8::Private key in
@@ -231,7 +150,7 @@ class PLATFORM_EXPORT V8PrivateProperty {
// requirement.
ScopedPersistent<v8::Private> symbol_window_document_cached_accessor_;
- WTF::HashMap<void*, v8::Eternal<v8::Private>> symbol_map_;
+ WTF::HashMap<const void*, v8::Eternal<v8::Private>> symbol_map_;
DISALLOW_COPY_AND_ASSIGN(V8PrivateProperty);
};
diff --git a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
index 50a8ac77733..635665ec38c 100644
--- a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
@@ -27,6 +27,8 @@ blink_platform_sources("blob") {
"blob_data.h",
"blob_url.cc",
"blob_url.h",
+ "blob_url_null_origin_map.cc",
+ "blob_url_null_origin_map.h",
"serialized_blob_mojom_traits.cc",
"serialized_blob_mojom_traits.h",
]
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
index 6f79a51f248..e1140bbe3eb 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
@@ -339,9 +339,9 @@ TEST_F(BlobBytesProviderTest, RequestAsStream) {
pipe.consumer_handle.get(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_WATCH_CONDITION_SATISFIED,
base::BindRepeating(
- [](mojo::DataPipeConsumerHandle pipe, base::Closure quit_closure,
- Vector<uint8_t>* bytes_out, MojoResult result,
- const mojo::HandleSignalsState& state) {
+ [](mojo::DataPipeConsumerHandle pipe,
+ base::RepeatingClosure quit_closure, Vector<uint8_t>* bytes_out,
+ MojoResult result, const mojo::HandleSignalsState& state) {
if (result == MOJO_RESULT_CANCELLED ||
result == MOJO_RESULT_FAILED_PRECONDITION) {
quit_closure.Run();
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
index f88c3d4b5dd..1b5e7a11cc6 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -120,24 +120,23 @@ std::unique_ptr<BlobData> BlobData::CreateForFileWithUnknownSize(
std::unique_ptr<BlobData> BlobData::CreateForFileWithUnknownSize(
const String& path,
- double expected_modification_time) {
+ const base::Optional<base::Time>& expected_modification_time) {
std::unique_ptr<BlobData> data = base::WrapUnique(
new BlobData(FileCompositionStatus::SINGLE_UNKNOWN_SIZE_FILE));
- data->elements_.push_back(DataElement::NewFile(DataElementFile::New(
- WebStringToFilePath(path), 0, BlobData::kToEndOfFile,
- base::Time::FromDoubleT(expected_modification_time))));
+ data->elements_.push_back(DataElement::NewFile(
+ DataElementFile::New(WebStringToFilePath(path), 0, BlobData::kToEndOfFile,
+ expected_modification_time)));
return data;
}
std::unique_ptr<BlobData> BlobData::CreateForFileSystemURLWithUnknownSize(
const KURL& file_system_url,
- double expected_modification_time) {
+ const base::Optional<base::Time>& expected_modification_time) {
std::unique_ptr<BlobData> data = base::WrapUnique(
new BlobData(FileCompositionStatus::SINGLE_UNKNOWN_SIZE_FILE));
- data->elements_.push_back(
- DataElement::NewFileFilesystem(DataElementFilesystemURL::New(
- file_system_url, 0, BlobData::kToEndOfFile,
- base::Time::FromDoubleT(expected_modification_time))));
+ data->elements_.push_back(DataElement::NewFileFilesystem(
+ DataElementFilesystemURL::New(file_system_url, 0, BlobData::kToEndOfFile,
+ expected_modification_time)));
return data;
}
@@ -162,10 +161,11 @@ void BlobData::AppendData(scoped_refptr<RawData> data) {
AppendDataInternal(base::make_span(data->data(), data->length()), data);
}
-void BlobData::AppendFile(const String& path,
- int64_t offset,
- int64_t length,
- double expected_modification_time) {
+void BlobData::AppendFile(
+ const String& path,
+ int64_t offset,
+ int64_t length,
+ const base::Optional<base::Time>& expected_modification_time) {
DCHECK_EQ(file_composition_, FileCompositionStatus::NO_UNKNOWN_SIZE_FILES)
<< "Blobs with a unknown-size file cannot have other items.";
DCHECK_NE(length, BlobData::kToEndOfFile)
@@ -177,8 +177,7 @@ void BlobData::AppendFile(const String& path,
if (length == 0)
return;
elements_.push_back(DataElement::NewFile(DataElementFile::New(
- WebStringToFilePath(path), offset, length,
- base::Time::FromDoubleT(expected_modification_time))));
+ WebStringToFilePath(path), offset, length, expected_modification_time)));
}
void BlobData::AppendBlob(scoped_refptr<BlobDataHandle> data_handle,
@@ -195,10 +194,11 @@ void BlobData::AppendBlob(scoped_refptr<BlobDataHandle> data_handle,
DataElementBlob::New(data_handle->CloneBlobRemote(), offset, length)));
}
-void BlobData::AppendFileSystemURL(const KURL& url,
- int64_t offset,
- int64_t length,
- double expected_modification_time) {
+void BlobData::AppendFileSystemURL(
+ const KURL& url,
+ int64_t offset,
+ int64_t length,
+ const base::Optional<base::Time>& expected_modification_time) {
DCHECK_EQ(file_composition_, FileCompositionStatus::NO_UNKNOWN_SIZE_FILES)
<< "Blobs with a unknown-size file cannot have other items.";
// Skip zero-byte items, as they don't matter for the contents of the blob.
@@ -206,8 +206,7 @@ void BlobData::AppendFileSystemURL(const KURL& url,
return;
elements_.push_back(
DataElement::NewFileFilesystem(DataElementFilesystemURL::New(
- url, offset, length,
- base::Time::FromDoubleT(expected_modification_time))));
+ url, offset, length, expected_modification_time)));
}
void BlobData::AppendText(const String& text,
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data.h b/chromium/third_party/blink/renderer/platform/blob/blob_data.h
index 9ae3614125a..9965fe9c64b 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.h
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.h
@@ -113,10 +113,10 @@ class PLATFORM_EXPORT BlobData {
const String& path);
static std::unique_ptr<BlobData> CreateForFileWithUnknownSize(
const String& path,
- double expected_modification_time);
+ const base::Optional<base::Time>& expected_modification_time);
static std::unique_ptr<BlobData> CreateForFileSystemURLWithUnknownSize(
const KURL& file_system_url,
- double expected_modification_time);
+ const base::Optional<base::Time>& expected_modification_time);
// Detaches from current thread so that it can be passed to another thread.
void DetachFromCurrentThread();
@@ -134,17 +134,18 @@ class PLATFORM_EXPORT BlobData {
void AppendFile(const String& path,
int64_t offset,
int64_t length,
- double expected_modification_time);
+ const base::Optional<base::Time>& expected_modification_time);
// The given blob must not be a file with unknown size. Please use the
// File::appendTo instead.
void AppendBlob(scoped_refptr<BlobDataHandle>,
int64_t offset,
int64_t length);
- void AppendFileSystemURL(const KURL&,
- int64_t offset,
- int64_t length,
- double expected_modification_time);
+ void AppendFileSystemURL(
+ const KURL&,
+ int64_t offset,
+ int64_t length,
+ const base::Optional<base::Time>& expected_modification_time);
void AppendText(const String&, bool normalize_line_endings_to_native);
// The value of the size property for a Blob who has this data.
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc b/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
index ee7a6b4d2f9..aa375aa798d 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
@@ -166,13 +166,13 @@ class BlobDataHandleTest : public testing::Test {
Vector<uint8_t> received_bytes;
mojo::Remote<mojom::blink::BytesProvider> actual_data(
std::move(actual->get_bytes()->data));
- actual_data->RequestAsReply(base::BindOnce(
- [](base::Closure quit_closure, Vector<uint8_t>* bytes_out,
+ actual_data->RequestAsReply(WTF::Bind(
+ [](base::RepeatingClosure quit_closure, Vector<uint8_t>* bytes_out,
const Vector<uint8_t>& bytes) {
*bytes_out = bytes;
quit_closure.Run();
},
- loop.QuitClosure(), &received_bytes));
+ loop.QuitClosure(), WTF::Unretained(&received_bytes)));
loop.Run();
if (expected->get_bytes()->embedded_data)
EXPECT_EQ(expected->get_bytes()->embedded_data, received_bytes);
@@ -205,7 +205,7 @@ class BlobDataHandleTest : public testing::Test {
mojo::Remote<mojom::blink::Blob> blob(
std::move(actual->get_blob()->blob));
blob->GetInternalUUID(base::BindOnce(
- [](base::Closure quit_closure, String* uuid_out,
+ [](base::RepeatingClosure quit_closure, String* uuid_out,
const String& uuid) {
*uuid_out = uuid;
quit_closure.Run();
@@ -284,8 +284,8 @@ TEST_F(BlobDataHandleTest, CreateFromEmptyElements) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(small_test_data_.data(), 0);
data->AppendBlob(empty_blob_, 0, 0);
- data->AppendFile("path", 0, 0, 0.0);
- data->AppendFileSystemURL(NullURL(), 0, 0, 0.0);
+ data->AppendFile("path", 0, 0, base::Time::UnixEpoch());
+ data->AppendFileSystemURL(NullURL(), 0, 0, base::Time::UnixEpoch());
TestCreateBlob(std::move(data), {});
}
@@ -359,18 +359,17 @@ TEST_F(BlobDataHandleTest, CreateFromMergedSmallAndLargeBytes) {
}
TEST_F(BlobDataHandleTest, CreateFromFileAndFileSystemURL) {
- double timestamp1 = base::Time::Now().ToDoubleT();
- double timestamp2 = timestamp1 + 1;
+ base::Time timestamp1 = base::Time::Now();
+ base::Time timestamp2 = timestamp1 + base::TimeDelta::FromSeconds(1);
KURL url(NullURL(), "http://example.com/");
auto data = std::make_unique<BlobData>();
data->AppendFile("path", 4, 32, timestamp1);
data->AppendFileSystemURL(url, 15, 876, timestamp2);
Vector<ExpectedElement> expected_elements;
- expected_elements.push_back(ExpectedElement::File(
- "path", 4, 32, base::Time::FromDoubleT(timestamp1)));
- expected_elements.push_back(ExpectedElement::FileFilesystem(
- url, 15, 876, base::Time::FromDoubleT(timestamp2)));
+ expected_elements.push_back(ExpectedElement::File("path", 4, 32, timestamp1));
+ expected_elements.push_back(
+ ExpectedElement::FileFilesystem(url, 15, 876, timestamp2));
TestCreateBlob(std::move(data), std::move(expected_elements));
}
@@ -385,11 +384,11 @@ TEST_F(BlobDataHandleTest, CreateFromFileWithUnknownSize) {
}
TEST_F(BlobDataHandleTest, CreateFromFilesystemFileWithUnknownSize) {
- double timestamp = base::Time::Now().ToDoubleT();
+ base::Time timestamp = base::Time::Now();
KURL url(NullURL(), "http://example.com/");
Vector<ExpectedElement> expected_elements;
- expected_elements.push_back(ExpectedElement::FileFilesystem(
- url, 0, uint64_t(-1), base::Time::FromDoubleT(timestamp)));
+ expected_elements.push_back(
+ ExpectedElement::FileFilesystem(url, 0, uint64_t(-1), timestamp));
TestCreateBlob(
BlobData::CreateForFileSystemURLWithUnknownSize(url, timestamp),
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc b/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc
new file mode 100644
index 00000000000..cfa2014920a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc
@@ -0,0 +1,80 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h"
+
+#include "third_party/blink/renderer/platform/blob/blob_url.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+// static
+ThreadSpecific<BlobURLNullOriginMap>& BlobURLNullOriginMap::GetInstance() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<BlobURLNullOriginMap>, map,
+ ());
+ return map;
+}
+
+void BlobURLNullOriginMap::Add(const KURL& blob_url, SecurityOrigin* origin) {
+ DCHECK(blob_url.ProtocolIs("blob"));
+ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
+ DCHECK(!blob_url.HasFragmentIdentifier());
+ DCHECK(origin->SerializesAsNull());
+ blob_url_null_origin_map_.insert(blob_url.GetString(), origin);
+ if (origin->IsOpaque())
+ BlobURLOpaqueOriginNonceMap::GetInstance().Add(blob_url, origin);
+}
+
+void BlobURLNullOriginMap::Remove(const KURL& blob_url) {
+ DCHECK(blob_url.ProtocolIs("blob"));
+ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
+ BlobURLOpaqueOriginNonceMap::GetInstance().Remove(blob_url);
+ blob_url_null_origin_map_.erase(blob_url.GetString());
+}
+
+SecurityOrigin* BlobURLNullOriginMap::Get(const KURL& blob_url) {
+ DCHECK(blob_url.ProtocolIs("blob"));
+ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
+ KURL blob_url_without_fragment = blob_url;
+ blob_url_without_fragment.RemoveFragmentIdentifier();
+ return blob_url_null_origin_map_.at(blob_url_without_fragment.GetString());
+}
+
+BlobURLOpaqueOriginNonceMap& BlobURLOpaqueOriginNonceMap::GetInstance() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(BlobURLOpaqueOriginNonceMap, map, ());
+ return map;
+}
+
+void BlobURLOpaqueOriginNonceMap::Add(const KURL& blob_url,
+ SecurityOrigin* origin) {
+ MutexLocker lock(mutex_);
+ DCHECK(blob_url.ProtocolIs("blob"));
+ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
+ DCHECK(!blob_url.HasFragmentIdentifier());
+ DCHECK(origin->IsOpaque());
+ DCHECK(origin->GetNonceForSerialization());
+ auto result = blob_url_opaque_origin_nonce_map_.insert(
+ blob_url.GetString(), *origin->GetNonceForSerialization());
+ // The blob URL must be registered only once within the process.
+ SECURITY_CHECK(result.is_new_entry);
+}
+
+void BlobURLOpaqueOriginNonceMap::Remove(const KURL& blob_url) {
+ MutexLocker lock(mutex_);
+ DCHECK(blob_url.ProtocolIs("blob"));
+ blob_url_opaque_origin_nonce_map_.erase(blob_url.GetString());
+}
+
+base::UnguessableToken BlobURLOpaqueOriginNonceMap::Get(const KURL& blob_url) {
+ MutexLocker lock(mutex_);
+ DCHECK(blob_url.ProtocolIs("blob"));
+ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
+ KURL blob_url_without_fragment = blob_url;
+ blob_url_without_fragment.RemoveFragmentIdentifier();
+ return blob_url_opaque_origin_nonce_map_.at(
+ blob_url_without_fragment.GetString());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h b/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h
new file mode 100644
index 00000000000..9cc789671c2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h
@@ -0,0 +1,109 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
+
+#include "base/thread_annotations.h"
+#include "base/unguessable_token.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+
+namespace blink {
+
+class KURL;
+class SecurityOrigin;
+
+// BlobURLNullOriginMap contains pairs of blob URL and security origin that is
+// serialized into "null". An instance of this class is per-thread, and created
+// when GetInstace() is called for the first time.
+//
+// When a blob URL is created in an opaque origin or something whose
+// SecurityOrigin::SerializesAsNull() returns true, the origin is serialized
+// into the URL as "null". Since that makes it impossible to parse the origin
+// back out and compare it against a context's origin (to check if a context is
+// allowed to dereference the URL), this class stores a map of blob URL to such
+// an origin.
+class PLATFORM_EXPORT BlobURLNullOriginMap {
+ public:
+ // Returns a thread-specific instance. The instance is created when this
+ // function is called for the first time.
+ static ThreadSpecific<BlobURLNullOriginMap>& GetInstance();
+
+ // Adds a pair of |blob_url| and |origin| to the map. |blob_url| and |origin|
+ // must have the same "null" origin.
+ void Add(const KURL& blob_url, SecurityOrigin* origin);
+
+ // Removes a "null" origin keyed with |blob_url| from the map. |blob_url| must
+ // have the "null" origin.
+ void Remove(const KURL& blob_url);
+
+ // Returns a "null" origin keyed with |blob_url| from the map. |blob_url| must
+ // have the "null" origin.
+ SecurityOrigin* Get(const KURL& blob_url);
+
+ private:
+ friend class ThreadSpecific<BlobURLNullOriginMap>;
+
+ HashMap<String, scoped_refptr<SecurityOrigin>> blob_url_null_origin_map_;
+};
+
+// BlobURLOpaqueOriginNonceMap contains pairs of blob URL and opaque security
+// origin's nonce. This is used for comparing opaque origins in a thread-safe
+// way. An instance of this class is singleton, and can safely be accessed from
+// any threads.
+//
+// BlobURLNullOriginMap above does not work for the case where the blob URL is
+// registered in an opaque origin, and then a network request is sent to the URL
+// from a different thread because the map contains non-thread-safe
+// SecurityOrigin. For example, this happens on dedicated worker construction
+// that loads a top-level worker script on a worker thread.
+//
+// To handle the case, BlobURLOpaqueOriginNonceMap keeps SecurityOrigin::Nonce
+// instead of SecurityOrigin. The nonce is uniquely assigned to SecurityOrigin
+// when it is constructed as an opaque origin, and SecurityOrigin instances
+// (isolated-)copied from the same opaque origin share the same nonce. The nonce
+// is thread-safe, so it is feasible to compare opaque origins over threads.
+//
+// TODO(nhiroki): Unify BlobURLNullOriginMap and BlobURLOpaqueOriginNonceMap.
+// Making BlobURLNullOriginMap thread-safe could be possible solution, but
+// actually it should be quite hard and not practical. This is because
+// SecurityOrigin is not thread-safe, and widely used with an assumption that it
+// is not shared among threads. Instead, we could stop using
+// BlobURLNullOriginMap, and use BlobURLNullOriginMap in any case.
+class PLATFORM_EXPORT BlobURLOpaqueOriginNonceMap {
+ public:
+ // Returns the singleton instance of this class. The instance is created when
+ // this function is called for the first time.
+ static BlobURLOpaqueOriginNonceMap& GetInstance();
+
+ // Returns an opaque origin's nonce keyed with |blob_url| from the map.
+ // |blob_url| must have the opaque origin.
+ base::UnguessableToken Get(const KURL& blob_url) LOCKS_EXCLUDED(mutex_);
+
+ private:
+ friend class BlobURLNullOriginMap;
+
+ // Adds a pair of |blob_url| and |origin|'s nonce to the map. |blob_url| and
+ // |origin| must have the same opaque origin. Only called from
+ // BlobURLNullOriginMap::Add().
+ void Add(const KURL& blob_url, SecurityOrigin* origin) LOCKS_EXCLUDED(mutex_);
+
+ // Removes an opaque origin's nonce keyed with |blob_url| from the map.
+ // |blob_url| must have the opaque origin. Only called from
+ // BlobURLNullOriginMap::Remove().
+ void Remove(const KURL& blob_url) LOCKS_EXCLUDED(mutex_);
+
+ HashMap<String, base::UnguessableToken> blob_url_opaque_origin_nonce_map_
+ GUARDED_BY(mutex_);
+
+ Mutex mutex_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/cookie/DEPS b/chromium/third_party/blink/renderer/platform/cookie/DEPS
new file mode 100644
index 00000000000..b943aa153a4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cookie/DEPS
@@ -0,0 +1,19 @@
+include_rules = [
+ # Don't depend on platform/.
+ "-third_party/blink/renderer/platform",
+
+ # Module.
+ "+third_party/blink/renderer/platform/cookie",
+
+ # Dependencies.
+ "+third_party/blink/renderer/platform/platform_export.h",
+ "+third_party/blink/renderer/platform/weborigin",
+ "+third_party/blink/renderer/platform/wtf",
+]
+
+specific_include_rules = {
+ "canonical_cookie.cc": [
+ "+net/cookies/canonical_cookie.h",
+ "+net/cookies/cookie_constants.h",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/platform/cookie/OWNERS b/chromium/third_party/blink/renderer/platform/cookie/OWNERS
new file mode 100644
index 00000000000..7aebc8abbf8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cookie/OWNERS
@@ -0,0 +1,4 @@
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie.cc b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.cc
index ca867911f08..ea02c4fc617 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie.cc
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_canonical_cookie.h"
+#include "third_party/blink/renderer/platform/cookie/canonical_cookie.h"
#include <memory>
+#include <utility>
#include "base/optional.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
+#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "url/gurl.h"
@@ -22,8 +24,6 @@ STATIC_ASSERT_ENUM(net::CookieSameSite::LAX_MODE,
network::mojom::CookieSameSite::LAX_MODE);
STATIC_ASSERT_ENUM(net::CookieSameSite::STRICT_MODE,
network::mojom::CookieSameSite::STRICT_MODE);
-STATIC_ASSERT_ENUM(net::CookieSameSite::EXTENDED_MODE,
- network::mojom::CookieSameSite::EXTENDED_MODE);
STATIC_ASSERT_ENUM(net::CookiePriority::COOKIE_PRIORITY_LOW,
network::mojom::CookiePriority::LOW);
@@ -32,38 +32,48 @@ STATIC_ASSERT_ENUM(net::CookiePriority::COOKIE_PRIORITY_MEDIUM,
STATIC_ASSERT_ENUM(net::CookiePriority::COOKIE_PRIORITY_HIGH,
network::mojom::CookiePriority::HIGH);
STATIC_ASSERT_ENUM(net::CookiePriority::COOKIE_PRIORITY_DEFAULT,
- blink::WebCanonicalCookie::kDefaultPriority);
+ blink::CanonicalCookie::kDefaultPriority);
+
+STATIC_ASSERT_ENUM(net::CookieSourceScheme::kUnset,
+ network::mojom::CookieSourceScheme::kUnset);
+STATIC_ASSERT_ENUM(net::CookieSourceScheme::kNonSecure,
+ network::mojom::CookieSourceScheme::kNonSecure);
+STATIC_ASSERT_ENUM(net::CookieSourceScheme::kSecure,
+ network::mojom::CookieSourceScheme::kSecure);
namespace blink {
namespace {
-net::CanonicalCookie ToNetCanonicalCookie(const WebCanonicalCookie& cookie) {
+net::CanonicalCookie ToNetCanonicalCookie(const CanonicalCookie& cookie) {
net::CanonicalCookie net_cookie(
cookie.Name().Utf8(), cookie.Value().Utf8(), cookie.Domain().Utf8(),
cookie.Path().Utf8(), cookie.CreationDate(), cookie.ExpiryDate(),
cookie.LastAccessDate(), cookie.IsSecure(), cookie.IsHttpOnly(),
static_cast<net::CookieSameSite>(cookie.SameSite()),
- static_cast<net::CookiePriority>(cookie.Priority()));
+ static_cast<net::CookiePriority>(cookie.Priority()),
+ static_cast<net::CookieSourceScheme>(cookie.SourceScheme()));
DCHECK(net_cookie.IsCanonical());
return net_cookie;
}
} // namespace
-WebCanonicalCookie::WebCanonicalCookie() = default;
-
-WebCanonicalCookie::WebCanonicalCookie(WebString name,
- WebString value,
- WebString domain,
- WebString path,
- base::Time creation,
- base::Time expiration,
- base::Time last_access,
- bool is_secure,
- bool is_http_only,
- network::mojom::CookieSameSite same_site,
- network::mojom::CookiePriority priority)
+CanonicalCookie::CanonicalCookie() = default;
+
+CanonicalCookie::CanonicalCookie(
+ WebString name,
+ WebString value,
+ WebString domain,
+ WebString path,
+ base::Time creation,
+ base::Time expiration,
+ base::Time last_access,
+ bool is_secure,
+ bool is_http_only,
+ network::mojom::CookieSameSite same_site,
+ network::mojom::CookiePriority priority,
+ network::mojom::CookieSourceScheme source_scheme)
: name_(std::move(name)),
value_(std::move(value)),
domain_(std::move(domain)),
@@ -74,17 +84,17 @@ WebCanonicalCookie::WebCanonicalCookie(WebString name,
is_secure_(is_secure),
is_http_only_(is_http_only),
same_site_(same_site),
- priority_(priority) {
+ priority_(priority),
+ source_scheme_(source_scheme) {
DCHECK(ToNetCanonicalCookie(*this).IsCanonical());
}
-WebCanonicalCookie::WebCanonicalCookie(const WebCanonicalCookie& other) =
- default;
+CanonicalCookie::CanonicalCookie(const CanonicalCookie& other) = default;
-WebCanonicalCookie& WebCanonicalCookie::operator=(
- const WebCanonicalCookie& other) = default;
+CanonicalCookie& CanonicalCookie::operator=(const CanonicalCookie& other) =
+ default;
-WebCanonicalCookie::~WebCanonicalCookie() = default;
+CanonicalCookie::~CanonicalCookie() = default;
namespace {
@@ -99,7 +109,7 @@ GURL ToGURL(const WebURL& url) {
} // namespace
// static
-base::Optional<WebCanonicalCookie> WebCanonicalCookie::Create(
+base::Optional<CanonicalCookie> CanonicalCookie::Create(
const WebURL& url,
const WebString& cookie_line,
base::Time creation_time) {
@@ -108,18 +118,19 @@ base::Optional<WebCanonicalCookie> WebCanonicalCookie::Create(
base::nullopt /* server_time */);
if (!cookie)
return base::nullopt;
- return WebCanonicalCookie(
+ return CanonicalCookie(
WebString::FromUTF8(cookie->Name()), WebString::FromUTF8(cookie->Value()),
WebString::FromUTF8(cookie->Domain()),
WebString::FromUTF8(cookie->Path()), cookie->CreationDate(),
cookie->ExpiryDate(), cookie->LastAccessDate(), cookie->IsSecure(),
cookie->IsHttpOnly(),
static_cast<network::mojom::CookieSameSite>(cookie->SameSite()),
- static_cast<network::mojom::CookiePriority>(cookie->Priority()));
+ static_cast<network::mojom::CookiePriority>(cookie->Priority()),
+ static_cast<network::mojom::CookieSourceScheme>(cookie->SourceScheme()));
}
// static
-base::Optional<WebCanonicalCookie> WebCanonicalCookie::Create(
+base::Optional<CanonicalCookie> CanonicalCookie::Create(
WebString name,
WebString value,
WebString domain,
@@ -130,22 +141,24 @@ base::Optional<WebCanonicalCookie> WebCanonicalCookie::Create(
bool is_secure,
bool is_http_only,
network::mojom::CookieSameSite same_site,
- network::mojom::CookiePriority priority) {
- net::CanonicalCookie net_cookie(name.Utf8(), value.Utf8(), domain.Utf8(),
- path.Utf8(), creation, expiration,
- last_access, is_secure, is_http_only,
- static_cast<net::CookieSameSite>(same_site),
- static_cast<net::CookiePriority>(priority));
+ network::mojom::CookiePriority priority,
+ network::mojom::CookieSourceScheme source_scheme) {
+ net::CanonicalCookie net_cookie(
+ name.Utf8(), value.Utf8(), domain.Utf8(), path.Utf8(), creation,
+ expiration, last_access, is_secure, is_http_only,
+ static_cast<net::CookieSameSite>(same_site),
+ static_cast<net::CookiePriority>(priority),
+ static_cast<net::CookieSourceScheme>(source_scheme));
if (!net_cookie.IsCanonical())
return base::nullopt;
- return WebCanonicalCookie(std::move(name), std::move(value),
- std::move(domain), std::move(path), creation,
- expiration, last_access, is_secure, is_http_only,
- same_site, priority);
+ return CanonicalCookie(std::move(name), std::move(value), std::move(domain),
+ std::move(path), creation, expiration, last_access,
+ is_secure, is_http_only, same_site, priority,
+ source_scheme);
}
constexpr const network::mojom::CookiePriority
- WebCanonicalCookie::kDefaultPriority;
+ CanonicalCookie::kDefaultPriority;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.h b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.h
new file mode 100644
index 00000000000..965409c9f0f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.h
@@ -0,0 +1,102 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_H_
+
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "services/network/public/mojom/cookie_manager.mojom-shared.h"
+#include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/platform/web_string.h"
+
+namespace blink {
+
+class WebURL;
+
+// This class is a blink analogue for net::CanonicalCookie.
+class BLINK_PLATFORM_EXPORT CanonicalCookie {
+ public:
+ // Default/copy constructor needed for use with Vector.
+ CanonicalCookie();
+ CanonicalCookie(const CanonicalCookie& other);
+
+ ~CanonicalCookie();
+
+ CanonicalCookie& operator=(const CanonicalCookie& other);
+
+ const WebString& Name() const { return name_; }
+ const WebString& Value() const { return value_; }
+ const WebString& Domain() const { return domain_; }
+ const WebString& Path() const { return path_; }
+ base::Time CreationDate() const { return creation_; }
+ base::Time ExpiryDate() const { return expiration_; }
+ base::Time LastAccessDate() const { return last_access_; }
+ bool IsSecure() const { return is_secure_; }
+ bool IsHttpOnly() const { return is_http_only_; }
+ network::mojom::CookieSameSite SameSite() const { return same_site_; }
+ network::mojom::CookiePriority Priority() const { return priority_; }
+ network::mojom::CookieSourceScheme SourceScheme() const {
+ return source_scheme_;
+ }
+
+ // If the result is not canonical, nullopt will be returned.
+ static base::Optional<CanonicalCookie> Create(
+ WebString name,
+ WebString value,
+ WebString domain,
+ WebString path,
+ base::Time creation,
+ base::Time expiration,
+ base::Time last_access,
+ bool is_secure,
+ bool is_http_only,
+ network::mojom::CookieSameSite same_site,
+ network::mojom::CookiePriority priority,
+ network::mojom::CookieSourceScheme source_scheme);
+
+ // Parsing, for the document.cookie API.
+ // If the result is not canonical, nullopt will be returned.
+ static base::Optional<CanonicalCookie> Create(const WebURL& url,
+ const WebString& cookie_line,
+ base::Time creation_time);
+
+ static constexpr const network::mojom::CookiePriority kDefaultPriority =
+ network::mojom::CookiePriority::MEDIUM;
+
+ private:
+ // Prefer static Create methods, which ensure that the returned cookie is
+ // canonical.
+ CanonicalCookie(WebString name,
+ WebString value,
+ WebString domain,
+ WebString path,
+ base::Time creation,
+ base::Time expiration,
+ base::Time last_access,
+ bool is_secure,
+ bool is_http_only,
+ network::mojom::CookieSameSite same_site,
+ network::mojom::CookiePriority priority,
+ network::mojom::CookieSourceScheme source_scheme);
+
+ WebString name_;
+ WebString value_;
+ WebString domain_;
+ WebString path_;
+ base::Time creation_;
+ base::Time expiration_;
+ base::Time last_access_;
+ bool is_secure_ = false;
+ bool is_http_only_ = false;
+ network::mojom::CookieSameSite same_site_ =
+ network::mojom::CookieSameSite::NO_RESTRICTION;
+ network::mojom::CookiePriority priority_ = kDefaultPriority;
+ network::mojom::CookieSourceScheme source_scheme_ =
+ network::mojom::CookieSourceScheme::kUnset;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie.typemap b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.typemap
index 3cddb9536de..2e2b7da2403 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie.typemap
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie.typemap
@@ -4,11 +4,9 @@
mojom = "//services/network/public/mojom/cookie_manager.mojom"
public_headers =
- [ "//third_party/blink/public/platform/web_canonical_cookie.h" ]
-traits_headers = [
- "//third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h",
-]
+ [ "//third_party/blink/renderer/platform/cookie/canonical_cookie.h" ]
+traits_headers = [ "//third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h" ]
deps = [
"//mojo/public/cpp/bindings",
]
-type_mappings = [ "network.mojom.CanonicalCookie=::blink::WebCanonicalCookie" ]
+type_mappings = [ "network.mojom.CanonicalCookie=::blink::CanonicalCookie" ]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.cc
index 2890d794561..e3ebbbb57d9 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.cc
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.cc
@@ -2,97 +2,105 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h"
+#include "third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h"
+
+#include <utility>
#include "base/optional.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
#include "mojo/public/cpp/bindings/string_traits_wtf.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace mojo {
// static
-WTF::String StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::name(const blink::WebCanonicalCookie& c) {
+WTF::String
+StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::name(const blink::CanonicalCookie& c) {
return c.Name();
}
// static
-WTF::String StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::value(const blink::WebCanonicalCookie& c) {
+WTF::String
+StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::value(const blink::CanonicalCookie& c) {
return c.Value();
}
// static
-WTF::String StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::domain(const blink::WebCanonicalCookie& c) {
+WTF::String
+StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::domain(const blink::CanonicalCookie& c) {
return c.Domain();
}
// static
-WTF::String StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::path(const blink::WebCanonicalCookie& c) {
+WTF::String
+StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::path(const blink::CanonicalCookie& c) {
return c.Path();
}
// static
base::Time StructTraits<
network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::creation(const blink::WebCanonicalCookie& c) {
+ blink::CanonicalCookie>::creation(const blink::CanonicalCookie& c) {
return c.CreationDate();
}
// static
-base::Time StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::expiry(const blink::WebCanonicalCookie& c) {
+base::Time
+StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::expiry(const blink::CanonicalCookie& c) {
return c.ExpiryDate();
}
// static
-base::Time StructTraits<network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::
- last_access(const blink::WebCanonicalCookie& c) {
+base::Time StructTraits<
+ network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::last_access(const blink::CanonicalCookie& c) {
return c.LastAccessDate();
}
// static
-bool StructTraits<
- network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::secure(const blink::WebCanonicalCookie& c) {
+bool StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::secure(const blink::CanonicalCookie&
+ c) {
return c.IsSecure();
}
// static
bool StructTraits<
network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::httponly(const blink::WebCanonicalCookie& c) {
+ blink::CanonicalCookie>::httponly(const blink::CanonicalCookie& c) {
return c.IsHttpOnly();
}
// static
network::mojom::CookieSameSite
-StructTraits<network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::
- site_restrictions(const blink::WebCanonicalCookie& c) {
+StructTraits<network::mojom::CanonicalCookieDataView, blink::CanonicalCookie>::
+ site_restrictions(const blink::CanonicalCookie& c) {
return c.SameSite();
}
// static
network::mojom::CookiePriority StructTraits<
network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::priority(const blink::WebCanonicalCookie& c) {
+ blink::CanonicalCookie>::priority(const blink::CanonicalCookie& c) {
return c.Priority();
}
// static
+network::mojom::CookieSourceScheme StructTraits<
+ network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie>::source_scheme(const blink::CanonicalCookie& c) {
+ return c.SourceScheme();
+}
+
+// static
bool StructTraits<network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie>::
+ blink::CanonicalCookie>::
Read(network::mojom::CanonicalCookieDataView cookie,
- blink::WebCanonicalCookie* out) {
+ blink::CanonicalCookie* out) {
WTF::String name;
if (!cookie.ReadName(&name))
return false;
@@ -129,10 +137,11 @@ bool StructTraits<network::mojom::CanonicalCookieDataView,
if (!cookie.ReadPriority(&priority))
return false;
- base::Optional<blink::WebCanonicalCookie> created =
- blink::WebCanonicalCookie::Create(
- name, value, domain, path, creation, expiry, last_access,
- cookie.secure(), cookie.httponly(), site_restrictions, priority);
+ base::Optional<blink::CanonicalCookie> created =
+ blink::CanonicalCookie::Create(name, value, domain, path, creation,
+ expiry, last_access, cookie.secure(),
+ cookie.httponly(), site_restrictions,
+ priority, cookie.source_scheme());
if (!created)
return false;
*out = std::move(created).value();
diff --git a/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h
new file mode 100644
index 00000000000..b284809667c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_mojom_traits.h
@@ -0,0 +1,43 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_MOJOM_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_MOJOM_TRAITS_H_
+
+#include "base/time/time.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "services/network/public/mojom/cookie_manager.mojom-blink-forward.h"
+#include "services/network/public/mojom/cookie_manager.mojom-shared.h"
+#include "third_party/blink/renderer/platform/cookie/canonical_cookie.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+
+namespace mojo {
+
+template <>
+struct PLATFORM_EXPORT StructTraits<network::mojom::CanonicalCookieDataView,
+ blink::CanonicalCookie> {
+ static WTF::String name(const blink::CanonicalCookie& c);
+ static WTF::String value(const blink::CanonicalCookie& c);
+ static WTF::String domain(const blink::CanonicalCookie& c);
+ static WTF::String path(const blink::CanonicalCookie& c);
+ static base::Time creation(const blink::CanonicalCookie& c);
+ static base::Time expiry(const blink::CanonicalCookie& c);
+ static base::Time last_access(const blink::CanonicalCookie& c);
+ static bool secure(const blink::CanonicalCookie& c);
+ static bool httponly(const blink::CanonicalCookie& c);
+ static network::mojom::CookieSameSite site_restrictions(
+ const blink::CanonicalCookie& c);
+ static network::mojom::CookiePriority priority(
+ const blink::CanonicalCookie& c);
+ static network::mojom::CookieSourceScheme source_scheme(
+ const blink::CanonicalCookie& c);
+
+ static bool Read(network::mojom::CanonicalCookieDataView cookie,
+ blink::CanonicalCookie* out);
+};
+
+} // namespace mojo
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_COOKIE_CANONICAL_COOKIE_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie_test.cc b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_test.cc
index 98096c6872d..23135517356 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_canonical_cookie_test.cc
+++ b/chromium/third_party/blink/renderer/platform/cookie/canonical_cookie_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_canonical_cookie.h"
+#include "third_party/blink/renderer/platform/cookie/canonical_cookie.h"
#include <initializer_list>
@@ -15,8 +15,8 @@
namespace blink {
-TEST(WebCanonicalCookieTest, Defaults) {
- WebCanonicalCookie cookie;
+TEST(CanonicalCookieTest, Defaults) {
+ CanonicalCookie cookie;
EXPECT_EQ(WebString(), cookie.Name());
EXPECT_EQ(WebString(), cookie.Value());
EXPECT_EQ(WebString(), cookie.Domain());
@@ -27,26 +27,27 @@ TEST(WebCanonicalCookieTest, Defaults) {
EXPECT_FALSE(cookie.IsSecure());
EXPECT_FALSE(cookie.IsHttpOnly());
EXPECT_EQ(network::mojom::CookieSameSite::NO_RESTRICTION, cookie.SameSite());
- EXPECT_EQ(WebCanonicalCookie::kDefaultPriority, cookie.Priority());
+ EXPECT_EQ(CanonicalCookie::kDefaultPriority, cookie.Priority());
}
-TEST(WebCanonicalCookieTest, CreationFailure) {
+TEST(CanonicalCookieTest, CreationFailure) {
const WebURL url(KURL("http://example.com"));
// Invalid cookie lines cause nullopt to be returned.
EXPECT_FALSE(
- WebCanonicalCookie::Create(url, "\x01", base::Time::Now()).has_value());
+ CanonicalCookie::Create(url, "\x01", base::Time::Now()).has_value());
// Invalid names cause nullopt to be returned.
- EXPECT_FALSE(WebCanonicalCookie::Create(
+ EXPECT_FALSE(CanonicalCookie::Create(
"\x01", "value", "domain", "/path", base::Time::Now(),
base::Time::Now(), base::Time::Now(), false, false,
network::mojom::CookieSameSite::NO_RESTRICTION,
- WebCanonicalCookie::kDefaultPriority)
+ CanonicalCookie::kDefaultPriority,
+ network::mojom::CookieSourceScheme::kNonSecure)
.has_value());
}
-TEST(WebCanonicalCookieTest, Properties) {
+TEST(CanonicalCookieTest, Properties) {
const base::Time t1 = base::Time::FromDoubleT(1);
const base::Time t2 = base::Time::FromDoubleT(2);
const base::Time t3 = base::Time::FromDoubleT(3);
@@ -54,12 +55,13 @@ TEST(WebCanonicalCookieTest, Properties) {
ASSERT_NE(t1, t3);
ASSERT_NE(t2, t3);
- base::Optional<WebCanonicalCookie> cookie_opt = WebCanonicalCookie::Create(
+ base::Optional<CanonicalCookie> cookie_opt = CanonicalCookie::Create(
"name", "value", "domain", "/path", t1, t2, t3, true, true,
network::mojom::CookieSameSite::STRICT_MODE,
- network::mojom::CookiePriority::HIGH);
+ network::mojom::CookiePriority::HIGH,
+ network::mojom::CookieSourceScheme::kSecure);
ASSERT_TRUE(cookie_opt);
- WebCanonicalCookie& cookie = cookie_opt.value();
+ CanonicalCookie& cookie = cookie_opt.value();
EXPECT_EQ("name", cookie.Name());
EXPECT_EQ("value", cookie.Value());
@@ -72,15 +74,17 @@ TEST(WebCanonicalCookieTest, Properties) {
EXPECT_TRUE(cookie.IsHttpOnly());
EXPECT_EQ(network::mojom::CookieSameSite::STRICT_MODE, cookie.SameSite());
EXPECT_EQ(network::mojom::CookiePriority::HIGH, cookie.Priority());
+ EXPECT_EQ(cookie.SourceScheme(), network::mojom::CookieSourceScheme::kSecure);
// Exercise WebCookieSameSite values.
for (auto same_site : {network::mojom::CookieSameSite::NO_RESTRICTION,
network::mojom::CookieSameSite::LAX_MODE,
network::mojom::CookieSameSite::STRICT_MODE}) {
EXPECT_EQ(same_site,
- WebCanonicalCookie::Create("name", "value", "domain", "/path", t1,
- t2, t3, false, false, same_site,
- WebCanonicalCookie::kDefaultPriority)
+ CanonicalCookie::Create(
+ "name", "value", "domain", "/path", t1, t2, t3, false, false,
+ same_site, CanonicalCookie::kDefaultPriority,
+ network::mojom::CookieSourceScheme::kSecure)
->SameSite());
}
@@ -88,11 +92,12 @@ TEST(WebCanonicalCookieTest, Properties) {
for (auto priority : {network::mojom::CookiePriority::LOW,
network::mojom::CookiePriority::MEDIUM,
network::mojom::CookiePriority::HIGH,
- WebCanonicalCookie::kDefaultPriority}) {
+ CanonicalCookie::kDefaultPriority}) {
EXPECT_EQ(priority,
- WebCanonicalCookie::Create(
+ CanonicalCookie::Create(
"name", "value", "domain", "/path", t1, t2, t3, false, false,
- network::mojom::CookieSameSite::NO_RESTRICTION, priority)
+ network::mojom::CookieSameSite::NO_RESTRICTION, priority,
+ network::mojom::CookieSourceScheme::kSecure)
->Priority());
}
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/DEPS b/chromium/third_party/blink/renderer/platform/exported/DEPS
index fde7f658ac5..84765698080 100644
--- a/chromium/third_party/blink/renderer/platform/exported/DEPS
+++ b/chromium/third_party/blink/renderer/platform/exported/DEPS
@@ -1,7 +1,5 @@
include_rules = [
"+net/base/load_flags.h",
- "+net/cookies/canonical_cookie.h",
- "+net/cookies/cookie_constants.h",
"+services/network/public/cpp/features.h",
]
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc b/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
index beccdfeaed3..c5825eed5ef 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
@@ -13,12 +13,12 @@
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc b/chromium/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
index b3849ece3ad..2c3ddd6af0d 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
@@ -47,9 +47,9 @@ void WebPlatformMediaStreamSource::SetDevice(const MediaStreamDevice& device) {
}
void WebPlatformMediaStreamSource::SetStopCallback(
- const SourceStoppedCallback& stop_callback) {
+ SourceStoppedCallback stop_callback) {
DCHECK(stop_callback_.is_null());
- stop_callback_ = stop_callback;
+ stop_callback_ = std::move(stop_callback);
}
void WebPlatformMediaStreamSource::ResetSourceStoppedCallback() {
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms_test.cc b/chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms_test.cc
deleted file mode 100644
index 73afe13309b..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms_test.cc
+++ /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.
-
-#include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-
-namespace blink {
-
-class MockPerSessionWebRTCAPIMetrics : public PerSessionWebRTCAPIMetrics {
- public:
- MockPerSessionWebRTCAPIMetrics() {}
-
- using PerSessionWebRTCAPIMetrics::LogUsageOnlyOnce;
-
- MOCK_METHOD1(LogUsage, void(WebRTCAPIName));
-};
-
-class PerSessionWebRTCAPIMetricsTest
- : public testing::Test,
- public testing::WithParamInterface<WebRTCAPIName> {
- public:
- PerSessionWebRTCAPIMetricsTest() = default;
- ~PerSessionWebRTCAPIMetricsTest() override = default;
-
- protected:
- MockPerSessionWebRTCAPIMetrics metrics;
-};
-
-TEST_P(PerSessionWebRTCAPIMetricsTest, NoCallOngoing) {
- WebRTCAPIName api_name = GetParam();
- EXPECT_CALL(metrics, LogUsage(api_name)).Times(1);
- metrics.LogUsageOnlyOnce(api_name);
-}
-
-TEST_P(PerSessionWebRTCAPIMetricsTest, CallOngoing) {
- WebRTCAPIName api_name = GetParam();
- metrics.IncrementStreamCounter();
- EXPECT_CALL(metrics, LogUsage(api_name)).Times(1);
- metrics.LogUsageOnlyOnce(api_name);
-}
-
-INSTANTIATE_TEST_SUITE_P(
- PerSessionWebRTCAPIMetricsTest,
- PerSessionWebRTCAPIMetricsTest,
- ::testing::ValuesIn({WebRTCAPIName::kGetUserMedia,
- WebRTCAPIName::kGetDisplayMedia,
- WebRTCAPIName::kEnumerateDevices,
- WebRTCAPIName::kRTCPeerConnection}));
-
-TEST(PerSessionWebRTCAPIMetrics, NoCallOngoingMultiplePC) {
- MockPerSessionWebRTCAPIMetrics metrics;
- EXPECT_CALL(metrics, LogUsage(WebRTCAPIName::kRTCPeerConnection)).Times(1);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
-}
-
-TEST(PerSessionWebRTCAPIMetrics, BeforeAfterCallMultiplePC) {
- MockPerSessionWebRTCAPIMetrics metrics;
- EXPECT_CALL(metrics, LogUsage(WebRTCAPIName::kRTCPeerConnection)).Times(1);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.IncrementStreamCounter();
- metrics.IncrementStreamCounter();
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.DecrementStreamCounter();
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.DecrementStreamCounter();
- EXPECT_CALL(metrics, LogUsage(WebRTCAPIName::kRTCPeerConnection)).Times(1);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
- metrics.LogUsageOnlyOnce(WebRTCAPIName::kRTCPeerConnection);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/platform.cc b/chromium/third_party/blink/renderer/platform/exported/platform.cc
index ff12a36a135..55f9e8146b7 100644
--- a/chromium/third_party/blink/renderer/platform/exported/platform.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/platform.cc
@@ -44,7 +44,6 @@
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/public/platform/web_prerendering_support.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
#include "third_party/blink/renderer/platform/font_family_names.h"
@@ -63,7 +62,6 @@
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/webrtc/api/async_resolver_factory.h"
#include "third_party/webrtc/api/rtp_parameters.h"
#include "third_party/webrtc/p2p/base/port_allocator.h"
@@ -81,7 +79,7 @@ class DefaultInterfaceProvider : public InterfaceProvider {
// InterfaceProvider implementation:
void GetInterface(const char* interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override {
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
mojo::GenericPendingReceiver(interface_name,
std::move(interface_pipe)));
}
@@ -294,8 +292,7 @@ InterfaceProvider* Platform::GetInterfaceProvider() {
return &provider;
}
-ThreadSafeBrowserInterfaceBrokerProxy*
-Platform::GetBrowserInterfaceBrokerProxy() {
+ThreadSafeBrowserInterfaceBrokerProxy* Platform::GetBrowserInterfaceBroker() {
DEFINE_STATIC_LOCAL(DefaultBrowserInterfaceBrokerProxy, proxy, ());
return &proxy;
}
@@ -330,25 +327,8 @@ Platform::CreateSharedOffscreenGraphicsContext3DProvider() {
}
std::unique_ptr<WebGraphicsContext3DProvider>
-Platform::CreateWebGPUGraphicsContext3DProvider(const WebURL& top_document_url,
- GraphicsInfo*) {
- return nullptr;
-}
-
-std::unique_ptr<WebRTCPeerConnectionHandler>
-Platform::CreateRTCPeerConnectionHandler(
- WebRTCPeerConnectionHandlerClient*,
- scoped_refptr<base::SingleThreadTaskRunner>) {
- return nullptr;
-}
-
-std::unique_ptr<cricket::PortAllocator> Platform::CreateWebRtcPortAllocator(
- WebLocalFrame* frame) {
- return nullptr;
-}
-
-std::unique_ptr<webrtc::AsyncResolverFactory>
-Platform::CreateWebRtcAsyncResolverFactory() {
+Platform::CreateWebGPUGraphicsContext3DProvider(
+ const WebURL& top_document_url) {
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc b/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
index 4b149343d90..5980f067a4a 100644
--- a/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "url/gurl.h"
@@ -26,4 +27,15 @@ GURL WebStringToGURL(const WebString& web_string) {
return GURL(base::StringPiece16(str.Characters16(), str.length()));
}
+mojo::ScopedMessagePipeHandle DataURLToMessagePipeHandle(
+ const WebString& data_url) {
+ auto blob_data = std::make_unique<blink::BlobData>();
+ blob_data->AppendBytes(data_url.Utf8().data(), data_url.length());
+ scoped_refptr<blink::BlobDataHandle> blob_data_handle =
+ blink::BlobDataHandle::Create(std::move(blob_data), data_url.length());
+ mojo::PendingRemote<mojom::blink::Blob> data_url_blob =
+ blob_data_handle->CloneBlobRemote();
+ return data_url_blob.PassPipe();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc b/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
index ebf7dcdbc61..3c104d77bf2 100644
--- a/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
@@ -18,6 +18,8 @@
#include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
#include "third_party/blink/renderer/platform/video_capture/gpu_memory_buffer_test_support.h"
#include "third_party/blink/renderer/platform/video_capture/video_capture_impl.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
using media::BindToCurrentLoop;
using ::testing::_;
@@ -50,12 +52,12 @@ class MockVideoCaptureImpl : public VideoCaptureImpl,
public:
MockVideoCaptureImpl(const media::VideoCaptureSessionId& session_id,
PauseResumeCallback* pause_callback,
- base::Closure destruct_callback)
+ base::OnceClosure destruct_callback)
: VideoCaptureImpl(session_id),
pause_callback_(pause_callback),
- destruct_callback_(destruct_callback) {}
+ destruct_callback_(std::move(destruct_callback)) {}
- ~MockVideoCaptureImpl() override { destruct_callback_.Run(); }
+ ~MockVideoCaptureImpl() override { std::move(destruct_callback_).Run(); }
private:
void Start(const base::UnguessableToken& device_id,
@@ -103,7 +105,7 @@ class MockVideoCaptureImpl : public VideoCaptureImpl,
MOCK_METHOD2(OnLog, void(const base::UnguessableToken&, const String&));
PauseResumeCallback* const pause_callback_;
- const base::Closure destruct_callback_;
+ base::OnceClosure destruct_callback_;
DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImpl);
};
@@ -111,7 +113,7 @@ class MockVideoCaptureImpl : public VideoCaptureImpl,
class MockVideoCaptureImplManager : public WebVideoCaptureImplManager {
public:
MockVideoCaptureImplManager(PauseResumeCallback* pause_callback,
- base::Closure stop_capture_callback)
+ base::RepeatingClosure stop_capture_callback)
: pause_callback_(pause_callback),
stop_capture_callback_(stop_capture_callback) {}
~MockVideoCaptureImplManager() override {}
@@ -126,7 +128,7 @@ class MockVideoCaptureImplManager : public WebVideoCaptureImplManager {
}
PauseResumeCallback* const pause_callback_;
- const base::Closure stop_capture_callback_;
+ const base::RepeatingClosure stop_capture_callback_;
DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImplManager);
};
@@ -216,10 +218,12 @@ class VideoCaptureImplManagerTest : public ::testing::Test,
const media::VideoCaptureParams& params) {
return manager_->StartCapture(
id, params,
- base::Bind(&VideoCaptureImplManagerTest::OnStateUpdate,
- base::Unretained(this), id),
- base::Bind(&VideoCaptureImplManagerTest::OnFrameReady,
- base::Unretained(this)));
+ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
+ &VideoCaptureImplManagerTest::OnStateUpdate,
+ CrossThreadUnretained(this), id)),
+ ConvertToBaseRepeatingCallback(
+ CrossThreadBindRepeating(&VideoCaptureImplManagerTest::OnFrameReady,
+ CrossThreadUnretained(this))));
}
base::test::TaskEnvironment task_environment_;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
index 9496a7da67d..b6d911afba9 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
@@ -26,7 +26,7 @@ WebBlobInfo::WebBlobInfo(const WebString& uuid,
const WebString& file_path,
const WebString& file_name,
const WebString& type,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
uint64_t size,
mojo::ScopedMessagePipeHandle handle)
: WebBlobInfo(
@@ -52,7 +52,7 @@ WebBlobInfo WebBlobInfo::FileForTesting(const WebString& uuid,
const WebString& file_path,
const WebString& file_name,
const WebString& type) {
- return WebBlobInfo(uuid, file_path, file_name, type, 0,
+ return WebBlobInfo(uuid, file_path, file_name, type, base::nullopt,
std::numeric_limits<uint64_t>::max(),
mojo::MessagePipe().handle0);
}
@@ -79,7 +79,7 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle)
WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
const WebString& file_path,
const WebString& file_name,
- double last_modified)
+ const base::Optional<base::Time>& last_modified)
: WebBlobInfo(handle,
file_path,
file_name,
@@ -94,14 +94,13 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
uuid_(handle->Uuid()),
type_(type),
size_(size),
- blob_handle_(std::move(handle)),
- last_modified_(0) {}
+ blob_handle_(std::move(handle)) {}
WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
const WebString& file_path,
const WebString& file_name,
const WebString& type,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
uint64_t size)
: is_file_(true),
uuid_(handle->Uuid()),
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc
index a29fcfa81dd..c26adc1f2f1 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc
@@ -45,12 +45,6 @@ WebCursorInfo::WebCursorInfo(const Cursor& cursor)
: type(static_cast<ui::CursorType>(cursor.GetType())),
hot_spot(cursor.HotSpot()),
image_scale_factor(cursor.ImageScaleFactor()),
- custom_image(GetCursorBitmap(cursor))
-#ifdef WIN32
- ,
- external_handle(0)
-#endif
-{
-}
+ custom_image(GetCursorBitmap(cursor)) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc b/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
index f56eb5dac95..f60fa03f4c9 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
@@ -72,7 +72,7 @@ bool WebHTTPBody::ElementAt(size_t index, Element& result) const {
result.file_path.Reset();
result.file_start = 0;
result.file_length = 0;
- result.modification_time = InvalidFileTime();
+ result.modification_time = base::nullopt;
result.blob_uuid.Reset();
switch (element.type_) {
@@ -126,10 +126,11 @@ void WebHTTPBody::AppendFile(const WebString& file_path) {
private_->AppendFile(file_path);
}
-void WebHTTPBody::AppendFileRange(const WebString& file_path,
- int64_t file_start,
- int64_t file_length,
- double modification_time) {
+void WebHTTPBody::AppendFileRange(
+ const WebString& file_path,
+ int64_t file_start,
+ int64_t file_length,
+ const base::Optional<base::Time>& modification_time) {
EnsureMutable();
private_->AppendFileRange(file_path, file_start, file_length,
modification_time);
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_http_header_map.cc b/chromium/third_party/blink/renderer/platform/exported/web_http_header_map.cc
deleted file mode 100644
index 0e63830c2dd..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_http_header_map.cc
+++ /dev/null
@@ -1,78 +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 "third_party/blink/public/platform/web_http_header_map.h"
-
-#include <memory>
-#include <string>
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/platform/network/http_header_map.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-
-namespace blink {
-
-class WebHTTPHeaderMap::WebHTTPHeaderMapImpl {
- USING_FAST_MALLOC(WebHTTPHeaderMap::WebHTTPHeaderMapImpl);
-
- public:
- explicit WebHTTPHeaderMapImpl(const HTTPHeaderMap& map) : map_(map) {}
-
- explicit WebHTTPHeaderMapImpl(const net::HttpRequestHeaders* headers) {
- for (net::HttpRequestHeaders::Iterator it(*headers); it.GetNext();) {
- map_.Add(
- WTF::AtomicString::FromUTF8(it.name().c_str(), it.name().length()),
- WTF::AtomicString::FromUTF8(it.value().c_str(), it.value().length()));
- }
- }
-
- explicit WebHTTPHeaderMapImpl(const net::HttpResponseHeaders* headers) {
- size_t iter = 0;
- std::string name;
- std::string value;
-
- while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
- WTF::AtomicString atomic_name =
- WTF::AtomicString::FromUTF8(name.c_str(), name.length());
- WTF::AtomicString atomic_value =
- WTF::AtomicString::FromUTF8(value.c_str(), value.length());
-
- if (map_.Contains(atomic_name))
- map_.Set(atomic_name, map_.Get(atomic_name) + "," + atomic_value);
- else
- map_.Add(atomic_name, atomic_value);
- }
- }
-
- const HTTPHeaderMap& map() const { return map_; }
-
- private:
- HTTPHeaderMap map_;
-};
-
-WebHTTPHeaderMap::~WebHTTPHeaderMap() = default;
-
-WebHTTPHeaderMap::WebHTTPHeaderMap(const HTTPHeaderMap& map) {
- implementation_ = std::make_unique<WebHTTPHeaderMapImpl>(map);
-}
-
-WebHTTPHeaderMap::WebHTTPHeaderMap(const net::HttpResponseHeaders* headers) {
- implementation_ = std::make_unique<WebHTTPHeaderMapImpl>(headers);
-}
-
-WebHTTPHeaderMap::WebHTTPHeaderMap(const net::HttpRequestHeaders* headers) {
- implementation_ = std::make_unique<WebHTTPHeaderMapImpl>(headers);
-}
-
-const HTTPHeaderMap& WebHTTPHeaderMap::GetHTTPHeaderMap() const {
- return implementation_->map();
-}
-
-WebString WebHTTPHeaderMap::Get(const WebString& name) const {
- return implementation_->map().Get(name).GetString();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_image.cc b/chromium/third_party/blink/renderer/platform/exported/web_image.cc
deleted file mode 100644
index cdedc8eae69..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_image.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_image.h"
-
-#include <algorithm>
-#include <memory>
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_data.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
-#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
-#include "third_party/skia/include/core/SkImage.h"
-
-namespace blink {
-
-SkBitmap WebImage::FromData(const WebData& data, const WebSize& desired_size) {
- const bool data_complete = true;
- std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
- data, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()));
- if (!decoder || !decoder->IsSizeAvailable())
- return {};
-
- // Frames are arranged by decreasing size, then decreasing bit depth.
- // Pick the frame closest to |desiredSize|'s area without being smaller,
- // which has the highest bit depth.
- const size_t frame_count = decoder->FrameCount();
- size_t index = 0; // Default to first frame if none are large enough.
- int frame_area_at_index = 0;
- for (size_t i = 0; i < frame_count; ++i) {
- const IntSize frame_size = decoder->FrameSizeAtIndex(i);
- if (WebSize(frame_size) == desired_size) {
- index = i;
- break; // Perfect match.
- }
-
- const int frame_area = frame_size.Width() * frame_size.Height();
- if (frame_area < (desired_size.width * desired_size.height))
- break; // No more frames that are large enough.
-
- if (!i || (frame_area < frame_area_at_index)) {
- index = i; // Closer to desired area than previous best match.
- frame_area_at_index = frame_area;
- }
- }
-
- ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(index);
- if (!frame || decoder->Failed())
- return {};
- return frame->Bitmap();
-}
-
-WebVector<SkBitmap> WebImage::FramesFromData(const WebData& data) {
- // This is to protect from malicious images. It should be big enough that it's
- // never hit in practice.
- const size_t kMaxFrameCount = 8;
-
- const bool data_complete = true;
- std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
- data, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()));
- if (!decoder || !decoder->IsSizeAvailable())
- return {};
-
- // Frames are arranged by decreasing size, then decreasing bit depth.
- // Keep the first frame at every size, has the highest bit depth.
- const size_t frame_count = decoder->FrameCount();
- IntSize last_size;
-
- WebVector<SkBitmap> frames;
- for (size_t i = 0; i < std::min(frame_count, kMaxFrameCount); ++i) {
- const IntSize frame_size = decoder->FrameSizeAtIndex(i);
- if (frame_size == last_size)
- continue;
- last_size = frame_size;
-
- ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(i);
- if (!frame)
- continue;
-
- SkBitmap bitmap = frame->Bitmap();
- if (!bitmap.isNull() && frame->GetStatus() == ImageFrame::kFrameComplete)
- frames.emplace_back(std::move(bitmap));
- }
-
- return frames;
-}
-
-WebVector<WebImage::AnimationFrame> WebImage::AnimationFromData(
- const WebData& data) {
- const bool data_complete = true;
- std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
- data, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()));
- if (!decoder || !decoder->IsSizeAvailable() || decoder->FrameCount() == 0)
- return {};
-
- const size_t frame_count = decoder->FrameCount();
- IntSize last_size = decoder->FrameSizeAtIndex(0);
-
- WebVector<WebImage::AnimationFrame> frames;
- frames.reserve(frame_count);
- for (size_t i = 0; i < frame_count; ++i) {
- // If frame size changes, this is most likely not an animation and is
- // instead an image with multiple versions at different resolutions. If
- // that's the case, return only the first frame (or no frames if we failed
- // decoding the first one).
- if (last_size != decoder->FrameSizeAtIndex(i)) {
- frames.resize(frames.empty() ? 0 : 1);
- return frames;
- }
- last_size = decoder->FrameSizeAtIndex(i);
-
- ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(i);
-
- SkBitmap bitmap = frame->Bitmap();
- if (bitmap.isNull() || frame->GetStatus() != ImageFrame::kFrameComplete)
- continue;
-
- // Make the bitmap a deep copy, otherwise the next loop iteration will
- // replace the contents of the previous frame. DecodeFrameBufferAtIndex
- // reuses the same underlying pixel buffer.
- bitmap.setImmutable();
-
- AnimationFrame output;
- output.bitmap = bitmap;
- output.duration = frame->Duration();
- frames.emplace_back(std::move(output));
- }
-
- return frames;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_image_test.cc b/chromium/third_party/blink/renderer/platform/exported/web_image_test.cc
deleted file mode 100644
index cc718b0822c..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_image_test.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_image.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_data.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
-
-namespace blink {
-
-static scoped_refptr<SharedBuffer> ReadFile(const char* file_name) {
- String file_path = test::CoreTestDataPath(file_name);
-
- return test::ReadFromFile(file_path);
-}
-
-TEST(WebImageTest, PNGImage) {
- scoped_refptr<SharedBuffer> data = ReadFile("white-1x1.png");
- ASSERT_TRUE(data.get());
-
- SkBitmap image = WebImage::FromData(WebData(data), WebSize());
- EXPECT_EQ(image.width(), 1);
- EXPECT_EQ(image.height(), 1);
- EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), image.getColor(0, 0));
-}
-
-TEST(WebImageTest, ICOImage) {
- scoped_refptr<SharedBuffer> data = ReadFile("black-and-white.ico");
- ASSERT_TRUE(data.get());
-
- WebVector<SkBitmap> images = WebImage::FramesFromData(WebData(data));
- ASSERT_EQ(2u, images.size());
- EXPECT_EQ(images[0].width(), 2);
- EXPECT_EQ(images[0].height(), 2);
- EXPECT_EQ(images[1].width(), 1);
- EXPECT_EQ(images[1].height(), 1);
- EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), images[0].getColor(0, 0));
- EXPECT_EQ(SkColorSetARGB(255, 0, 0, 0), images[1].getColor(0, 0));
-}
-
-TEST(WebImageTest, ICOValidHeaderMissingBitmap) {
- scoped_refptr<SharedBuffer> data =
- ReadFile("valid_header_missing_bitmap.ico");
- ASSERT_TRUE(data.get());
-
- WebVector<SkBitmap> images = WebImage::FramesFromData(WebData(data));
- ASSERT_TRUE(images.empty());
-}
-
-TEST(WebImageTest, BadImage) {
- const char kBadImage[] = "hello world";
- WebVector<SkBitmap> images = WebImage::FramesFromData(WebData(kBadImage));
- ASSERT_EQ(0u, images.size());
-
- SkBitmap image = WebImage::FromData(WebData(kBadImage), WebSize());
- EXPECT_TRUE(image.empty());
- EXPECT_TRUE(image.isNull());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc
index 2ff43ce5b77..85661bc1203 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc
@@ -54,11 +54,11 @@ struct SameSizeAsWebMouseEvent : public SameSizeAsWebInputEvent {
};
struct SameSizeAsWebMouseWheelEvent : public SameSizeAsWebMouseEvent {
- int mousewheel_data[13];
+ int mousewheel_data[12];
};
struct SameSizeAsWebGestureEvent : public SameSizeAsWebInputEvent {
- int gesture_data[15];
+ int gesture_data[14];
};
struct SameSizeAsWebTouchEvent : public SameSizeAsWebInputEvent {
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc
index 55b725c7a44..ac11337e73a 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc
@@ -43,6 +43,7 @@ bool WebResourceTimingInfo::operator==(
transfer_size == other.transfer_size &&
encoded_body_size == other.encoded_body_size &&
decoded_body_size == other.decoded_body_size &&
+ context_type == other.context_type &&
did_reuse_connection == other.did_reuse_connection &&
is_secure_context == other.is_secure_context &&
allow_timing_details == other.allow_timing_details &&
@@ -76,6 +77,7 @@ CrossThreadCopier<blink::WebResourceTimingInfo>::Copy(
copy.transfer_size = info.transfer_size;
copy.encoded_body_size = info.encoded_body_size;
copy.decoded_body_size = info.decoded_body_size;
+ copy.context_type = info.context_type;
copy.did_reuse_connection = info.did_reuse_connection;
copy.is_secure_context = info.is_secure_context;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
index e2aad2dd9ec..1caab47f81c 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
@@ -118,7 +118,7 @@ TEST(WebResourceTimingInfoTest, CrossThreadCopy) {
WebResourceTimingInfo info = CreateWebResourceTimingInfo(pseudo_time);
std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("TestThread"));
PostCrossThreadTask(*thread->GetTaskRunner(), FROM_HERE,
CrossThreadBindOnce(&CheckWebResourceTimingInfoOnThread,
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_answer_options.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_answer_options.cc
deleted file mode 100644
index 11d96529ea7..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_answer_options.cc
+++ /dev/null
@@ -1,27 +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.
-
-#include "third_party/blink/public/platform/web_rtc_answer_options.h"
-
-#include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h"
-
-namespace blink {
-
-WebRTCAnswerOptions::WebRTCAnswerOptions(RTCAnswerOptionsPlatform* options)
- : private_(options) {}
-
-void WebRTCAnswerOptions::Assign(const WebRTCAnswerOptions& other) {
- private_ = other.private_;
-}
-
-void WebRTCAnswerOptions::Reset() {
- private_.Reset();
-}
-
-bool WebRTCAnswerOptions::VoiceActivityDetection() const {
- DCHECK(!private_.IsNull());
- return private_->VoiceActivityDetection();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_offer_options.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_offer_options.cc
deleted file mode 100644
index 366bb3d2bb2..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_offer_options.cc
+++ /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.
-
-#include "third_party/blink/public/platform/web_rtc_offer_options.h"
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
-
-namespace blink {
-
-WebRTCOfferOptions::WebRTCOfferOptions(RTCOfferOptionsPlatform* options)
- : private_(options) {}
-
-WebRTCOfferOptions::WebRTCOfferOptions(int32_t offer_to_receive_audio,
- int32_t offer_to_receive_video,
- bool voice_activity_detection,
- bool ice_restart)
- : private_(MakeGarbageCollected<RTCOfferOptionsPlatform>(
- offer_to_receive_audio,
- offer_to_receive_video,
- voice_activity_detection,
- ice_restart)) {}
-
-void WebRTCOfferOptions::Assign(const WebRTCOfferOptions& other) {
- private_ = other.private_;
-}
-
-void WebRTCOfferOptions::Reset() {
- private_.Reset();
-}
-
-int32_t WebRTCOfferOptions::OfferToReceiveVideo() const {
- DCHECK(!IsNull());
- return private_->OfferToReceiveVideo();
-}
-
-int32_t WebRTCOfferOptions::OfferToReceiveAudio() const {
- DCHECK(!IsNull());
- return private_->OfferToReceiveAudio();
-}
-
-bool WebRTCOfferOptions::VoiceActivityDetection() const {
- DCHECK(!IsNull());
- return private_->VoiceActivityDetection();
-}
-
-bool WebRTCOfferOptions::IceRestart() const {
- DCHECK(!IsNull());
- return private_->IceRestart();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_source.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_source.cc
deleted file mode 100644
index 621bbf77dda..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_source.cc
+++ /dev/null
@@ -1,11 +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 "third_party/blink/public/platform/web_rtc_rtp_source.h"
-
-namespace blink {
-
-WebRTCRtpSource::~WebRTCRtpSource() = default;
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description.cc
deleted file mode 100644
index 2de0d60d486..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_rtc_session_description.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-
-namespace blink {
-
-class WebRTCSessionDescriptionPrivate final
- : public RefCounted<WebRTCSessionDescriptionPrivate> {
- USING_FAST_MALLOC(WebRTCSessionDescription);
-
- public:
- static scoped_refptr<WebRTCSessionDescriptionPrivate> Create(
- const WebString& type,
- const WebString& sdp);
-
- WebString GetType() { return type_; }
- void SetType(const WebString& type) { type_ = type; }
-
- WebString Sdp() { return sdp_; }
- void SetSdp(const WebString& sdp) { sdp_ = sdp; }
-
- private:
- WebRTCSessionDescriptionPrivate(const WebString& type, const WebString& sdp);
-
- WebString type_;
- WebString sdp_;
-};
-
-scoped_refptr<WebRTCSessionDescriptionPrivate>
-WebRTCSessionDescriptionPrivate::Create(const WebString& type,
- const WebString& sdp) {
- return base::AdoptRef(new WebRTCSessionDescriptionPrivate(type, sdp));
-}
-
-WebRTCSessionDescriptionPrivate::WebRTCSessionDescriptionPrivate(
- const WebString& type,
- const WebString& sdp)
- : type_(type), sdp_(sdp) {}
-
-void WebRTCSessionDescription::Assign(const WebRTCSessionDescription& other) {
- private_ = other.private_;
-}
-
-void WebRTCSessionDescription::Reset() {
- private_.Reset();
-}
-
-void WebRTCSessionDescription::Initialize(const WebString& type,
- const WebString& sdp) {
- private_ = WebRTCSessionDescriptionPrivate::Create(type, sdp);
-}
-
-WebString WebRTCSessionDescription::GetType() const {
- DCHECK(!private_.IsNull());
- return private_->GetType();
-}
-
-void WebRTCSessionDescription::SetType(const WebString& type) {
- DCHECK(!private_.IsNull());
- return private_->SetType(type);
-}
-
-WebString WebRTCSessionDescription::Sdp() const {
- DCHECK(!private_.IsNull());
- return private_->Sdp();
-}
-
-void WebRTCSessionDescription::SetSDP(const WebString& sdp) {
- DCHECK(!private_.IsNull());
- return private_->SetSdp(sdp);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description_request.cc
deleted file mode 100644
index ca17946ee50..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_session_description_request.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_rtc_session_description_request.h"
-
-#include "third_party/blink/public/platform/web_rtc_session_description.h"
-#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-WebRTCSessionDescriptionRequest::WebRTCSessionDescriptionRequest(
- RTCSessionDescriptionRequest* request)
- : private_(request) {}
-
-void WebRTCSessionDescriptionRequest::Assign(
- const WebRTCSessionDescriptionRequest& other) {
- private_ = other.private_;
-}
-
-void WebRTCSessionDescriptionRequest::Reset() {
- private_.Reset();
-}
-
-void WebRTCSessionDescriptionRequest::RequestSucceeded(
- const WebRTCSessionDescription& session_description) const {
- DCHECK(private_.Get());
- private_->RequestSucceeded(session_description);
-}
-
-void WebRTCSessionDescriptionRequest::RequestFailed(
- const webrtc::RTCError& error) const {
- DCHECK(private_.Get());
- private_->RequestFailed(error);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
index ed27c0a3cc8..52175634f23 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
@@ -6,10 +6,4 @@
namespace blink {
-WebRTCStatsReport::~WebRTCStatsReport() = default;
-
-WebRTCStats::~WebRTCStats() = default;
-
-WebRTCStatsMember::~WebRTCStatsMember() = default;
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_request.cc
deleted file mode 100644
index 809050fa22c..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_request.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_rtc_stats_request.h"
-
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_rtc_stats_response.h"
-#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h"
-#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h"
-
-namespace blink {
-
-WebRTCStatsRequest::WebRTCStatsRequest(RTCStatsRequest* request)
- : private_(request) {}
-
-void WebRTCStatsRequest::Assign(const WebRTCStatsRequest& other) {
- private_ = other.private_;
-}
-
-void WebRTCStatsRequest::Reset() {
- private_.Reset();
-}
-
-WebRTCStatsResponse WebRTCStatsRequest::CreateResponse() const {
- return WebRTCStatsResponse(private_->CreateResponse());
-}
-
-bool WebRTCStatsRequest::HasSelector() const {
- return private_->HasSelector();
-}
-
-const WebMediaStreamTrack WebRTCStatsRequest::Component() const {
- return WebMediaStreamTrack(private_->Component());
-}
-
-void WebRTCStatsRequest::RequestSucceeded(
- const WebRTCStatsResponse& response) const {
- private_->RequestSucceeded(response);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_response.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_response.cc
deleted file mode 100644
index 2c7d842b641..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats_response.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_rtc_stats_response.h"
-
-#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-WebRTCStatsResponse::WebRTCStatsResponse(RTCStatsResponseBase* request)
- : private_(request) {}
-
-void WebRTCStatsResponse::Assign(const WebRTCStatsResponse& other) {
- private_ = other.private_;
-}
-
-void WebRTCStatsResponse::Reset() {
- private_.Reset();
-}
-
-WebRTCStatsResponse::operator RTCStatsResponseBase*() const {
- return private_.Get();
-}
-
-void WebRTCStatsResponse::AddStats(const WebRTCLegacyStats& stats) {
- DCHECK(!private_.IsNull());
- private_->AddStats(stats);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_void_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_void_request.cc
deleted file mode 100644
index e796bd659b7..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_void_request.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_rtc_void_request.h"
-
-#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-WebRTCVoidRequest::WebRTCVoidRequest(RTCVoidRequest* constraints)
- : private_(constraints) {}
-
-void WebRTCVoidRequest::Assign(const WebRTCVoidRequest& other) {
- private_ = other.private_;
-}
-
-void WebRTCVoidRequest::Reset() {
- private_.Reset();
-}
-
-void WebRTCVoidRequest::RequestSucceeded() const {
- if (private_.Get())
- private_->RequestSucceeded();
-}
-
-void WebRTCVoidRequest::RequestFailed(const webrtc::RTCError& error) const {
- if (private_.Get()) {
- private_->RequestFailed(error);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index bbeca4e606c..a9da7db2638 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/public/platform/web_runtime_features.h"
+#include "third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -192,10 +193,6 @@ void WebRuntimeFeatures::EnableFallbackCursorMode(bool enable) {
RuntimeEnabledFeatures::SetFallbackCursorModeEnabled(enable);
}
-void WebRuntimeFeatures::EnableFastMobileScrolling(bool enable) {
- RuntimeEnabledFeatures::SetFastMobileScrollingEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableFeaturePolicyForSandbox(bool enable) {
RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(enable);
}
@@ -272,10 +269,6 @@ void WebRuntimeFeatures::EnableMediaSession(bool enable) {
RuntimeEnabledFeatures::SetMediaSessionEnabled(enable);
}
-void WebRuntimeFeatures::EnableMimeHandlerViewInCrossProcessFrame(bool enable) {
- RuntimeEnabledFeatures::SetMimeHandlerViewInCrossProcessFrameEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableNotificationConstructor(bool enable) {
RuntimeEnabledFeatures::SetNotificationConstructorEnabled(enable);
}
@@ -296,6 +289,10 @@ void WebRuntimeFeatures::EnableNetInfoDownlinkMax(bool enable) {
RuntimeEnabledFeatures::SetNetInfoDownlinkMaxEnabled(enable);
}
+void WebRuntimeFeatures::EnableNeverSlowMode(bool enable) {
+ RuntimeEnabledFeatures::SetNeverSlowModeEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableOnDeviceChange(bool enable) {
RuntimeEnabledFeatures::SetOnDeviceChangeEnabled(enable);
}
@@ -389,10 +386,6 @@ void WebRuntimeFeatures::EnableUserActivationSameOriginVisibility(bool enable) {
RuntimeEnabledFeatures::SetUserActivationSameOriginVisibilityEnabled(enable);
}
-void WebRuntimeFeatures::EnableUserActivationV2(bool enable) {
- RuntimeEnabledFeatures::SetUserActivationV2Enabled(enable);
-}
-
void WebRuntimeFeatures::EnableTouchEventFeatureDetection(bool enable) {
RuntimeEnabledFeatures::SetTouchEventFeatureDetectionEnabled(enable);
}
@@ -414,7 +407,7 @@ void WebRuntimeFeatures::EnableXSLT(bool enable) {
}
void WebRuntimeFeatures::EnableOverlayScrollbars(bool enable) {
- RuntimeEnabledFeatures::SetOverlayScrollbarsEnabled(enable);
+ ScrollbarThemeSettings::SetOverlayScrollbarsEnabled(enable);
}
void WebRuntimeFeatures::ForceOverlayFullscreenVideo(bool enable) {
@@ -465,10 +458,6 @@ void WebRuntimeFeatures::EnableWebGPU(bool enable) {
RuntimeEnabledFeatures::SetWebGPUEnabled(enable);
}
-void WebRuntimeFeatures::EnableWebVR(bool enable) {
- RuntimeEnabledFeatures::SetWebVREnabled(enable);
-}
-
void WebRuntimeFeatures::EnableWebXR(bool enable) {
RuntimeEnabledFeatures::SetWebXREnabled(enable);
}
@@ -567,6 +556,10 @@ void WebRuntimeFeatures::EnableVideoFullscreenDetection(bool enable) {
RuntimeEnabledFeatures::SetVideoFullscreenDetectionEnabled(enable);
}
+void WebRuntimeFeatures::EnableVideoPlaybackQuality(bool enable) {
+ RuntimeEnabledFeatures::SetVideoPlaybackQualityEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableMediaControlsOverlayPlayButton(bool enable) {
RuntimeEnabledFeatures::SetMediaControlsOverlayPlayButtonEnabled(enable);
}
@@ -583,6 +576,10 @@ void WebRuntimeFeatures::EnableWebAuth(bool enable) {
RuntimeEnabledFeatures::SetWebAuthEnabled(enable);
}
+void WebRuntimeFeatures::EnableWebAuthenticationFeaturePolicy(bool enable) {
+ RuntimeEnabledFeatures::SetWebAuthenticationFeaturePolicyEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableLazyInitializeMediaControls(bool enable) {
RuntimeEnabledFeatures::SetLazyInitializeMediaControlsEnabled(enable);
}
@@ -629,10 +626,6 @@ void WebRuntimeFeatures::EnableBackgroundFetch(bool enable) {
RuntimeEnabledFeatures::SetBackgroundFetchEnabled(enable);
}
-void WebRuntimeFeatures::EnableMergeBlockingNonBlockingPools(bool enable) {
- RuntimeEnabledFeatures::SetMergeBlockingNonBlockingPoolsEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableGetDisplayMedia(bool enable) {
RuntimeEnabledFeatures::SetGetDisplayMediaEnabled(enable);
}
@@ -651,7 +644,6 @@ void WebRuntimeFeatures::EnableCustomElementsV0(bool enable) {
void WebRuntimeFeatures::EnableHTMLImports(bool enable) {
RuntimeEnabledFeatures::SetHTMLImportsEnabled(enable);
- RuntimeEnabledFeatures::SetHTMLImportsOnlyChromeEnabled(enable);
}
void WebRuntimeFeatures::EnableSignedExchangePrefetchCacheForNavigations(
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_security_origin.cc b/chromium/third_party/blink/renderer/platform/exported/web_security_origin.cc
index afd42428a06..a465d679e5e 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_security_origin.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_security_origin.cc
@@ -93,6 +93,11 @@ bool WebSecurityOrigin::CanRequest(const WebURL& url) const {
return private_->CanRequest(url);
}
+bool WebSecurityOrigin::CanDisplay(const WebURL& url) const {
+ DCHECK(private_);
+ return private_->CanDisplay(url);
+}
+
bool WebSecurityOrigin::IsPotentiallyTrustworthy() const {
DCHECK(private_);
return private_->IsPotentiallyTrustworthy();
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
index 7caaaf10b1b..50ebdbbad7c 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -473,7 +473,7 @@ int WebURLRequest::GetLoadFlagsForWebUrlRequest() const {
blink::mojom::RequestContextType::PREFETCH);
DCHECK(base::FeatureList::IsEnabled(
network::features::kPrefetchMainResourceNetworkIsolationKey));
- if (!resource_request_->RequestorOrigin()->IsSameSchemeHostPort(
+ if (!resource_request_->RequestorOrigin()->IsSameOriginWith(
SecurityOrigin::Create(resource_request_->Url()).get())) {
load_flags |= net::LOAD_RESTRICTED_PREFETCH;
}
diff --git a/chromium/third_party/blink/renderer/platform/file_metadata.cc b/chromium/third_party/blink/renderer/platform/file_metadata.cc
index e3c075c047b..c78e471f403 100644
--- a/chromium/third_party/blink/renderer/platform/file_metadata.cc
+++ b/chromium/third_party/blink/renderer/platform/file_metadata.cc
@@ -46,13 +46,22 @@
namespace blink {
+namespace {
+
+mojo::Remote<mojom::blink::FileUtilitiesHost>& GetFileUtilitiesHost() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(
+ ThreadSpecific<mojo::Remote<mojom::blink::FileUtilitiesHost>>,
+ thread_specific_host, ());
+ return *thread_specific_host;
+}
+
+} // namespace
+
// static
FileMetadata FileMetadata::From(const base::File::Info& file_info) {
FileMetadata file_metadata;
- if (file_info.last_modified.is_null())
- file_metadata.modification_time = std::numeric_limits<double>::quiet_NaN();
- else
- file_metadata.modification_time = file_info.last_modified.ToJsTime();
+ file_metadata.modification_time =
+ NullableTimeToOptionalTime(file_info.last_modified);
file_metadata.length = file_info.size;
if (file_info.is_directory)
file_metadata.type = FileMetadata::kTypeDirectory;
@@ -69,7 +78,8 @@ bool GetFileSize(const String& path, int64_t& result) {
return true;
}
-bool GetFileModificationTime(const String& path, double& result) {
+bool GetFileModificationTime(const String& path,
+ base::Optional<base::Time>& result) {
FileMetadata metadata;
if (!GetFileMetadata(path, metadata))
return false;
@@ -77,11 +87,17 @@ bool GetFileModificationTime(const String& path, double& result) {
return true;
}
+void RebindFileUtilitiesForTesting() {
+ auto& host = GetFileUtilitiesHost();
+ if (host) {
+ host.Unbind().reset();
+ }
+ Platform::Current()->GetInterfaceProvider()->GetInterface(
+ host.BindNewPipeAndPassReceiver());
+}
+
bool GetFileMetadata(const String& path, FileMetadata& metadata) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- ThreadSpecific<mojo::Remote<mojom::blink::FileUtilitiesHost>>,
- thread_specific_host, ());
- auto& host = *thread_specific_host;
+ auto& host = GetFileUtilitiesHost();
if (!host) {
Platform::Current()->GetInterfaceProvider()->GetInterface(
host.BindNewPipeAndPassReceiver());
@@ -91,10 +107,8 @@ bool GetFileMetadata(const String& path, FileMetadata& metadata) {
if (!host->GetFileInfo(WebStringToFilePath(path), &file_info) || !file_info)
return false;
- // Blink now expects NaN as uninitialized/null Date.
- metadata.modification_time = file_info->last_modified.is_null()
- ? std::numeric_limits<double>::quiet_NaN()
- : file_info->last_modified.ToJsTime();
+ metadata.modification_time =
+ NullableTimeToOptionalTime(file_info->last_modified);
metadata.length = file_info->size;
metadata.type = file_info->is_directory ? FileMetadata::kTypeDirectory
: FileMetadata::kTypeFile;
diff --git a/chromium/third_party/blink/renderer/platform/file_metadata.h b/chromium/third_party/blink/renderer/platform/file_metadata.h
index 10db67e3640..08c52dd94ef 100644
--- a/chromium/third_party/blink/renderer/platform/file_metadata.h
+++ b/chromium/third_party/blink/renderer/platform/file_metadata.h
@@ -31,35 +31,27 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FILE_METADATA_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FILE_METADATA_H_
-#include <time.h>
#include "base/files/file.h"
+#include "base/optional.h"
+#include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-inline double InvalidFileTime() {
- return std::numeric_limits<double>::quiet_NaN();
-}
-inline bool IsValidFileTime(double time) {
- return std::isfinite(time);
-}
-
class FileMetadata {
DISALLOW_NEW();
public:
FileMetadata()
- : modification_time(InvalidFileTime()), length(-1), type(kTypeUnknown) {}
+ : modification_time(base::nullopt), length(-1), type(kTypeUnknown) {}
PLATFORM_EXPORT static FileMetadata From(const base::File::Info& file_info);
- // The last modification time of the file, in milliseconds.
- // The value NaN means that the time is not known.
- double modification_time;
+ // The last modification time of the file.
+ base::Optional<base::Time> modification_time;
// The length of the file in bytes.
// The value -1 means that the length is not set.
@@ -72,10 +64,20 @@ class FileMetadata {
};
PLATFORM_EXPORT bool GetFileSize(const String&, int64_t& result);
-PLATFORM_EXPORT bool GetFileModificationTime(const String&, double& result);
+PLATFORM_EXPORT bool GetFileModificationTime(
+ const String&,
+ base::Optional<base::Time>& result);
PLATFORM_EXPORT bool GetFileMetadata(const String&, FileMetadata&);
PLATFORM_EXPORT KURL FilePathToURL(const String&);
+PLATFORM_EXPORT void RebindFileUtilitiesForTesting();
+
+inline base::Optional<base::Time> NullableTimeToOptionalTime(base::Time time) {
+ if (time.is_null())
+ return base::nullopt;
+ return time;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FILE_METADATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.cc b/chromium/third_party/blink/renderer/platform/fonts/font.cc
index 4fc2c843e14..2b110b2e0e0 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.cc
@@ -28,7 +28,6 @@
#include "cc/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/fonts/character_range.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
-#include "third_party/blink/renderer/platform/fonts/font_fallback_iterator.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
#include "third_party/blink/renderer/platform/fonts/ng_text_fragment_paint_info.h"
#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h"
@@ -464,12 +463,6 @@ void Font::WillUseFontData(const String& text) const {
GetFontDescription(), family.Family(), text);
}
-scoped_refptr<FontFallbackIterator> Font::CreateFontFallbackIterator(
- FontFallbackPriority fallback_priority) const {
- return FontFallbackIterator::Create(font_description_, font_fallback_list_,
- fallback_priority);
-}
-
GlyphData Font::GetEmphasisMarkGlyphData(const AtomicString& mark) const {
if (mark.IsEmpty())
return GlyphData();
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.h b/chromium/third_party/blink/renderer/platform/fonts/font.h
index d13cb218a04..ca24f5f5e49 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.h
@@ -27,6 +27,7 @@
#include "cc/paint/node_id.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
+#include "third_party/blink/renderer/platform/fonts/font_fallback_iterator.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
@@ -53,7 +54,6 @@ namespace blink {
struct CharacterRange;
class FloatPoint;
class FloatRect;
-class FontFallbackIterator;
class FontData;
class FontSelector;
class ShapeCache;
@@ -230,8 +230,11 @@ class PLATFORM_EXPORT Font {
public:
FontSelector* GetFontSelector() const;
- scoped_refptr<FontFallbackIterator> CreateFontFallbackIterator(
- FontFallbackPriority) const;
+ FontFallbackIterator CreateFontFallbackIterator(
+ FontFallbackPriority fallback_priority) const {
+ return FontFallbackIterator(font_description_, font_fallback_list_,
+ fallback_priority);
+ }
void WillUseFontData(const String& text) const;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
index ee8216491bf..b4a7e9509cf 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -115,7 +115,7 @@ FontCache::FontCache()
FontPlatformData* FontCache::SystemFontPlatformData(
const FontDescription& font_description) {
const AtomicString& family = FontCache::SystemFontFamily();
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
if (family.IsEmpty() || family == font_family_names::kSystemUi)
return nullptr;
#else
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
index 4025c77b42a..08c723bc646 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -58,6 +58,10 @@
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
+#if defined(OS_LINUX)
+#include "ui/gfx/font_fallback_linux.h"
+#endif
+
#if defined(OS_WIN)
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
#include "third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h"
@@ -238,17 +242,9 @@ class PLATFORM_EXPORT FontCache {
#endif // defined(OS_ANDROID)
#if defined(OS_LINUX)
- struct PlatformFallbackFont {
- String name;
- std::string filename;
- int fontconfig_interface_id;
- int ttc_index;
- bool is_bold;
- bool is_italic;
- };
- static void GetFontForCharacter(UChar32,
+ static bool GetFontForCharacter(UChar32,
const char* preferred_locale,
- PlatformFallbackFont*);
+ gfx::FallbackFontData*);
#endif // defined(OS_LINUX)
scoped_refptr<SimpleFontData> FontDataFromFontPlatformData(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
index 825ed95642d..1362d480c4b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
@@ -12,14 +12,6 @@
namespace blink {
-scoped_refptr<FontFallbackIterator> FontFallbackIterator::Create(
- const FontDescription& description,
- scoped_refptr<FontFallbackList> fallback_list,
- FontFallbackPriority font_fallback_priority) {
- return base::AdoptRef(new FontFallbackIterator(
- description, std::move(fallback_list), font_fallback_priority));
-}
-
FontFallbackIterator::FontFallbackIterator(
const FontDescription& description,
scoped_refptr<FontFallbackList> fallback_list,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
index 03f264cd632..b17424f89d8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
@@ -20,13 +20,16 @@ class FontDescription;
class FontFallbackList;
class SimpleFontData;
-class FontFallbackIterator : public RefCounted<FontFallbackIterator> {
- USING_FAST_MALLOC(FontFallbackIterator);
+class FontFallbackIterator {
+ STACK_ALLOCATED();
public:
- static scoped_refptr<FontFallbackIterator> Create(const FontDescription&,
- scoped_refptr<FontFallbackList>,
- FontFallbackPriority);
+ FontFallbackIterator(const FontDescription&,
+ scoped_refptr<FontFallbackList>,
+ FontFallbackPriority);
+ FontFallbackIterator(FontFallbackIterator&&) = default;
+ FontFallbackIterator(const FontFallbackIterator&) = delete;
+ FontFallbackIterator& operator=(const FontFallbackIterator&) = delete;
bool HasNext() const { return fallback_stage_ != kOutOfLuck; }
// Returns whether the next call to Next() needs a full hint list, or whether
@@ -43,9 +46,6 @@ class FontFallbackIterator : public RefCounted<FontFallbackIterator> {
scoped_refptr<FontDataForRangeSet> Next(const Vector<UChar32>& hint_list);
private:
- FontFallbackIterator(const FontDescription&,
- scoped_refptr<FontFallbackList>,
- FontFallbackPriority);
bool RangeSetContributesForHint(const Vector<UChar32> hint_list,
const FontDataForRangeSet*);
bool AlreadyLoadingRangeForHintChar(UChar32 hint_char);
@@ -83,8 +83,6 @@ class FontFallbackIterator : public RefCounted<FontFallbackIterator> {
HashSet<uint32_t> unique_font_data_for_range_sets_returned_;
Vector<scoped_refptr<FontDataForRangeSet>> tracked_loading_range_sets_;
FontFallbackPriority font_fallback_priority_;
-
- DISALLOW_COPY_AND_ASSIGN(FontFallbackIterator);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
index be346f33c16..fa1a455e591 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -165,8 +165,16 @@ scoped_refptr<FontData> FontFallbackList::GetFontData(
if (!result)
result = FontCache::GetFontCache()->GetFontData(font_description,
curr_family->Family());
- if (result)
+ if (result) {
+ if (font_selector_) {
+ font_selector_->ReportSuccessfulFontFamilyMatch(
+ curr_family->Family());
+ }
return result;
+ }
+
+ if (font_selector_)
+ font_selector_->ReportFailedFontFamilyMatch(curr_family->Family());
}
}
family_index = kCAllFamiliesScanned;
@@ -229,9 +237,9 @@ const FontData* FontFallbackList::FontDataAt(
// Ask the font cache for the font data.
// We are obtaining this font for the first time. We keep track of the
- // families we've looked at before in |m_familyIndex|, so that we never scan
- // the same spot in the list twice. getFontData will adjust our
- // |m_familyIndex| as it scans for the right font to make.
+ // families we've looked at before in |family_index_|, so that we never scan
+ // the same spot in the list twice. GetFontData will adjust our
+ // |family_index_| as it scans for the right font to make.
DCHECK_EQ(FontCache::GetFontCache()->Generation(), generation_);
scoped_refptr<FontData> result = GetFontData(font_description, family_index_);
if (result) {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
new file mode 100644
index 00000000000..5e1005a2e4d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -0,0 +1,69 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/fonts/font_matching_metrics.h"
+
+#include "services/metrics/public/cpp/metrics_utils.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
+
+namespace {
+
+constexpr double kUkmFontLoadCountBucketSpacing = 1.3;
+
+enum FontLoadContext { kTopLevel = 0, kSubFrame };
+
+template <typename T>
+HashSet<T> Intersection(const HashSet<T>& a, const HashSet<T>& b) {
+ HashSet<T> result;
+ for (const T& a_value : a) {
+ if (b.Contains(a_value))
+ result.insert(a_value);
+ }
+ return result;
+}
+
+} // namespace
+
+namespace blink {
+
+void FontMatchingMetrics::ReportSuccessfulFontFamilyMatch(
+ const AtomicString& font_family_name) {
+ successful_font_families_.insert(font_family_name);
+}
+
+void FontMatchingMetrics::ReportFailedFontFamilyMatch(
+ const AtomicString& font_family_name) {
+ failed_font_families_.insert(font_family_name);
+}
+
+void FontMatchingMetrics::ReportSystemFontFamily(
+ const AtomicString& font_family_name) {
+ system_font_families_.insert(font_family_name);
+}
+
+void FontMatchingMetrics::ReportWebFontFamily(
+ const AtomicString& font_family_name) {
+ web_font_families_.insert(font_family_name);
+}
+
+void FontMatchingMetrics::PublishUkmMetrics() {
+ ukm::builders::FontMatchAttempts(source_id_)
+ .SetLoadContext(top_level_ ? kTopLevel : kSubFrame)
+ .SetSystemFontFamilySuccesses(ukm::GetExponentialBucketMin(
+ Intersection(successful_font_families_, system_font_families_).size(),
+ kUkmFontLoadCountBucketSpacing))
+ .SetSystemFontFamilyFailures(ukm::GetExponentialBucketMin(
+ Intersection(failed_font_families_, system_font_families_).size(),
+ kUkmFontLoadCountBucketSpacing))
+ .SetWebFontFamilySuccesses(ukm::GetExponentialBucketMin(
+ Intersection(successful_font_families_, web_font_families_).size(),
+ kUkmFontLoadCountBucketSpacing))
+ .SetWebFontFamilyFailures(ukm::GetExponentialBucketMin(
+ Intersection(failed_font_families_, web_font_families_).size(),
+ kUkmFontLoadCountBucketSpacing))
+ .Record(ukm_recorder_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
new file mode 100644
index 00000000000..c31be1c51b5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_MATCHING_METRICS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_MATCHING_METRICS_H_
+
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
+
+namespace ukm {
+class UkmRecorder;
+} // namespace ukm
+
+namespace blink {
+
+// Tracks and reports UKM metrics of the number of attempted font family match
+// attempts (both successful and not successful) by the current frame.
+//
+// Only the number of successful / not successful font family match attempts are
+// reported to UKM. The class de-dupes attempts to match the same font family
+// name such that they are counted as one attempt.
+class PLATFORM_EXPORT FontMatchingMetrics {
+ public:
+ FontMatchingMetrics(bool top_level,
+ ukm::UkmRecorder* ukm_recorder,
+ ukm::SourceId source_id)
+ : top_level_(top_level),
+ ukm_recorder_(ukm_recorder),
+ source_id_(source_id) {}
+
+ // Called when a page attempts to match a font family, and the font family is
+ // available.
+ void ReportSuccessfulFontFamilyMatch(const AtomicString& font_family_name);
+
+ // Called when a page attempts to match a font family, and the font family is
+ // not available.
+ void ReportFailedFontFamilyMatch(const AtomicString& font_family_name);
+
+ // Called when a page attempts to match a system font family.
+ void ReportSystemFontFamily(const AtomicString& font_family_name);
+
+ // Called when a page attempts to match a web font family.
+ void ReportWebFontFamily(const AtomicString& font_family_name);
+
+ // Publishes the number of font family matches attempted (both successful and
+ // otherwise) to UKM. Called at page unload.
+ void PublishUkmMetrics();
+
+ private:
+ // Font family names successfully matched.
+ HashSet<AtomicString> successful_font_families_;
+
+ // Font family names that weren't successfully matched.
+ HashSet<AtomicString> failed_font_families_;
+
+ // System font families the page attempted to match.
+ HashSet<AtomicString> system_font_families_;
+
+ // Web font families the page attempted to match.
+ HashSet<AtomicString> web_font_families_;
+
+ // True if this FontMatchingMetrics instance is for a top-level frame, false
+ // otherwise.
+ const bool top_level_ = false;
+
+ ukm::UkmRecorder* const ukm_recorder_;
+ const ukm::SourceId source_id_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_MATCHING_METRICS_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
index 7d1bcb68740..0eaaf9e94fb 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
@@ -61,6 +61,16 @@ class PLATFORM_EXPORT FontSelector : public FontCacheClient {
virtual void ReportNotDefGlyph() const = 0;
+ // Called when a page attempts to match a font family, and the font family is
+ // available.
+ virtual void ReportSuccessfulFontFamilyMatch(
+ const AtomicString& font_family_name) = 0;
+
+ // Called when a page attempts to match a font family, and the font family is
+ // not available.
+ virtual void ReportFailedFontFamilyMatch(
+ const AtomicString& font_family_name) = 0;
+
virtual void RegisterForInvalidationCallbacks(FontSelectorClient*) = 0;
virtual void UnregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc b/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
index 687fff054dc..39edc68d0bc 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/linux/out_of_process_font.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
@@ -50,33 +49,16 @@ void FontCache::SetSystemFontFamily(const AtomicString& family_name) {
MutableSystemFontFamily() = family_name;
}
-void FontCache::GetFontForCharacter(
- UChar32 c,
- const char* preferred_locale,
- FontCache::PlatformFallbackFont* fallback_font) {
+bool FontCache::GetFontForCharacter(UChar32 c,
+ const char* preferred_locale,
+ gfx::FallbackFontData* fallback_font) {
if (Platform::Current()->GetSandboxSupport()) {
- OutOfProcessFont web_fallback_font;
- Platform::Current()->GetSandboxSupport()->GetFallbackFontForCharacter(
- c, preferred_locale, &web_fallback_font);
- fallback_font->name = web_fallback_font.name;
- fallback_font->filename = std::string(web_fallback_font.filename.Data(),
- web_fallback_font.filename.size());
- fallback_font->fontconfig_interface_id =
- web_fallback_font.fontconfig_interface_id;
- fallback_font->ttc_index = web_fallback_font.ttc_index;
- fallback_font->is_bold = web_fallback_font.is_bold;
- fallback_font->is_italic = web_fallback_font.is_italic;
+ return Platform::Current()
+ ->GetSandboxSupport()
+ ->GetFallbackFontForCharacter(c, preferred_locale, fallback_font);
} else {
std::string locale = preferred_locale ? preferred_locale : std::string();
- gfx::FallbackFontData fallback_data =
- gfx::GetFallbackFontForChar(c, locale);
- fallback_font->name = String::FromUTF8(fallback_data.name.data(),
- fallback_data.name.length());
- fallback_font->filename = std::move(fallback_data.filename);
- fallback_font->fontconfig_interface_id = 0;
- fallback_font->ttc_index = fallback_data.ttc_index;
- fallback_font->is_bold = fallback_data.is_bold;
- fallback_font->is_italic = fallback_data.is_italic;
+ return gfx::GetFallbackFontForChar(c, locale, fallback_font);
}
}
@@ -89,7 +71,7 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
// WebFontRendering::setSkiaFontManager. This is used to emulate android fonts
// on linux so we always request the family from the font manager and if none
// is found, we return the LastResort fallback font and avoid using
- // FontCache::getFontForCharacter which would use sandbox support to query the
+ // FontCache::GetFontForCharacter which would use sandbox support to query the
// underlying system for the font family.
if (font_manager_) {
AtomicString family_name = GetFamilyNameForCharacter(
@@ -120,15 +102,15 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
return font_data;
}
- FontCache::PlatformFallbackFont fallback_font;
- FontCache::GetFontForCharacter(
- c, font_description.LocaleOrDefault().Ascii().c_str(), &fallback_font);
- if (fallback_font.name.IsEmpty())
+ gfx::FallbackFontData fallback_font;
+ if (!FontCache::GetFontForCharacter(
+ c, font_description.LocaleOrDefault().Ascii().c_str(),
+ &fallback_font))
return nullptr;
FontFaceCreationParams creation_params;
creation_params = FontFaceCreationParams(
- fallback_font.filename, fallback_font.fontconfig_interface_id,
+ fallback_font.filepath.value(), fallback_font.fontconfig_interface_id,
fallback_font.ttc_index);
// Changes weight and/or italic of given FontDescription depends on
diff --git a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
index 1c3b8d04a6a..62d92b7f412 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
@@ -3,10 +3,11 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.h"
-#include "third_party/blink/public/platform/linux/out_of_process_font.h"
+
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/skia/sktypeface_factory.h"
+#include "ui/gfx/font_fallback_linux.h"
namespace blink {
@@ -14,7 +15,7 @@ FontUniqueNameLookupLinux::~FontUniqueNameLookupLinux() = default;
sk_sp<SkTypeface> FontUniqueNameLookupLinux::MatchUniqueName(
const String& font_unique_name) {
- OutOfProcessFont uniquely_matched_font;
+ gfx::FallbackFontData uniquely_matched_font;
if (!Platform::Current()->GetSandboxSupport()) {
LOG(ERROR) << "@font-face src: local() instantiation only available when "
"connected to browser process.";
@@ -22,12 +23,11 @@ sk_sp<SkTypeface> FontUniqueNameLookupLinux::MatchUniqueName(
return nullptr;
}
- Platform::Current()
- ->GetSandboxSupport()
- ->MatchFontByPostscriptNameOrFullFontName(
- font_unique_name.Utf8(WTF::kStrictUTF8Conversion).c_str(),
- &uniquely_matched_font);
- if (!uniquely_matched_font.filename.size())
+ if (!Platform::Current()
+ ->GetSandboxSupport()
+ ->MatchFontByPostscriptNameOrFullFontName(
+ font_unique_name.Utf8(WTF::kStrictUTF8Conversion).c_str(),
+ &uniquely_matched_font))
return nullptr;
return SkTypeface_Factory::FromFontConfigInterfaceIdAndTtcIndex(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 0b9c2ef61fd..8d01704041c 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -194,16 +194,19 @@ NSFont* MatchNSFontFamily(const AtomicString& desired_family_string,
NSString* desired_family = desired_family_string;
NSFontManager* font_manager = [NSFontManager sharedFontManager];
- // Do a simple case insensitive search for a matching font family.
- // NSFontManager requires exact name matches.
- // This addresses the problem of matching arial to Arial, etc., but perhaps
- // not all the issues.
- NSEnumerator* e = [[font_manager availableFontFamilies] objectEnumerator];
- NSString* available_family;
- while ((available_family = [e nextObject])) {
- if ([desired_family caseInsensitiveCompare:available_family] ==
- NSOrderedSame)
- break;
+ // From Mac OS 10.15 [NSFontManager availableFonts] does not list certain
+ // fonts that availableMembersOfFontFamily actually shows results for, for
+ // example "Hiragino Kaku Gothic ProN" is not listed, only Hiragino Sans is
+ // listed. We previously enumerated availableFontFamilies and looked for a
+ // case-insensitive string match here, but instead, we can rely on
+ // availableMembersOfFontFamily here to do a case-insensitive comparison, then
+ // set available_family to desired_family if the result was not empty.
+ // See https://crbug.com/1000542
+ NSString* available_family = nil;
+ NSArray* fonts_in_family =
+ [font_manager availableMembersOfFontFamily:desired_family];
+ if (fonts_in_family && [fonts_in_family count]) {
+ available_family = desired_family;
}
int app_kit_font_weight = ToAppKitFontWeight(desired_weight);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
index 11baf4df7db..c919c686aa6 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
@@ -855,8 +855,8 @@ void HarfBuzzShaper::ShapeSegment(
font_description.VariantCaps() != FontDescription::kCapsNormal;
OpenTypeCapsSupport caps_support;
- scoped_refptr<FontFallbackIterator> fallback_iterator =
- font->CreateFontFallbackIterator(segment.font_fallback_priority);
+ FontFallbackIterator fallback_iterator(
+ font->CreateFontFallbackIterator(segment.font_fallback_priority));
range_data->reshape_queue.push_back(
ReshapeQueueItem(kReshapeQueueNextFont, 0, 0));
@@ -867,7 +867,7 @@ void HarfBuzzShaper::ShapeSegment(
Vector<UChar32> fallback_chars_hint;
// Reserve sufficient capacity to avoid multiple reallocations, only when a
// full hint list is needed.
- if (fallback_iterator->NeedsHintList()) {
+ if (fallback_iterator.NeedsHintList()) {
fallback_chars_hint.ReserveInitialCapacity(range_data->end -
range_data->start);
}
@@ -877,7 +877,7 @@ void HarfBuzzShaper::ShapeSegment(
if (current_queue_item.action_ == kReshapeQueueNextFont) {
if (!CollectFallbackHintChars(range_data->reshape_queue,
- fallback_iterator->NeedsHintList(),
+ fallback_iterator.NeedsHintList(),
fallback_chars_hint)) {
// Give up shaping since we cannot retrieve a font fallback
// font without a hintlist.
@@ -886,7 +886,7 @@ void HarfBuzzShaper::ShapeSegment(
}
current_font_data_for_range_set =
- fallback_iterator->Next(fallback_chars_hint);
+ fallback_iterator.Next(fallback_chars_hint);
if (!current_font_data_for_range_set->FontData()) {
DCHECK(range_data->reshape_queue.empty());
break;
@@ -959,7 +959,7 @@ void HarfBuzzShaper::ShapeSegment(
ExtractShapeResults(range_data, font_cycle_queued, current_queue_item,
adjusted_font, segment.script, canvas_rotation,
- !fallback_iterator->HasNext(), result);
+ !fallback_iterator.HasNext(), result);
hb_buffer_reset(range_data->buffer);
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.cc b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.cc
index f14586c70d7..7ff2ac7ed86 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.cc
@@ -56,10 +56,6 @@ float FloatPoint3D::AngleBetween(const FloatPoint3D& y) const {
return 0;
}
-FloatPoint3D::operator gfx::Point3F() const {
- return gfx::Point3F(x_, y_, z_);
-}
-
std::ostream& operator<<(std::ostream& ostream, const FloatPoint3D& point) {
return ostream << point.ToString();
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
index a7c5e735849..bbe09db5592 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
@@ -111,7 +111,7 @@ class PLATFORM_EXPORT FloatPoint3D {
float DistanceTo(const FloatPoint3D& a) const;
operator SkPoint3() const { return SkPoint3::Make(x_, y_, z_); }
- operator gfx::Point3F() const;
+ operator gfx::Point3F() const { return gfx::Point3F(x_, y_, z_); }
String ToString() const;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/DEPS b/chromium/third_party/blink/renderer/platform/graphics/DEPS
index 37eff60e8f0..69ebb831274 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/DEPS
@@ -17,6 +17,7 @@ include_rules = [
"+gpu/config",
"+gpu/command_buffer/client/gles2_interface.h",
"+gpu/command_buffer/client/gpu_memory_buffer_manager.h",
+ "+gpu/command_buffer/client/raster_interface.h",
"+gpu/command_buffer/client/shared_image_interface.h",
"+gpu/command_buffer/common/gpu_memory_buffer_support.h",
"+gpu/command_buffer/common/capabilities.h",
diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
index 2bb3f5dbcf3..22135712d5d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/skia/include/core/SkImage.h"
@@ -179,7 +180,7 @@ IntSize AcceleratedStaticBitmapImage::Size() const {
scoped_refptr<StaticBitmapImage>
AcceleratedStaticBitmapImage::MakeUnaccelerated() {
CreateImageFromMailboxIfNeeded();
- return StaticBitmapImage::Create(
+ return UnacceleratedStaticBitmapImage::Create(
skia_texture_holder_->GetSkImage()->makeNonTextureImage());
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
index 4e436b4b9f9..f89408d112d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -29,7 +29,9 @@ class PLATFORM_EXPORT AcceleratedStaticBitmapImage final
: public StaticBitmapImage {
public:
~AcceleratedStaticBitmapImage() override;
+
// SkImage with a texture backing.
+ // DO NOT USE. This is in the process of being removed. See crbug.com/962630.
static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromSkImage(
sk_sp<SkImage>,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc
index a93063f7715..59b9bfe09b7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc
@@ -11,13 +11,13 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h"
#include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -39,8 +39,7 @@ namespace {
std::unique_ptr<Thread> CreateThread(const char* name) {
return Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
- .SetThreadNameForTest(name));
+ ThreadCreationParams(ThreadType::kTestThread).SetThreadNameForTest(name));
}
class MockAnimationWorkletMutator
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
index 8170d9a44b3..0ebbe0c6c5c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
@@ -51,32 +51,8 @@ void BitmapImageMetrics::CountImageJpegDensity(int image_min_side,
// of 0.01 bpp. We don't report for any sample for small images (0 to 99px on
// the smallest dimension).
//
- // The histograms JpegDensity.1000px, JpegDensity.400px and JpegDensity.100px
- // report the number of images decoded for a given bpp value.
- //
// The histogram JpegDensity.KiBWeighted reports the number of KiB decoded for
// a given bpp value.
- if (image_min_side >= 1000) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, density_histogram,
- ("Blink.DecodedImage.JpegDensity.1000px", 1, 1000, 100));
- density_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(density_centi_bpp));
- } else if (image_min_side >= 400) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, density_histogram,
- ("Blink.DecodedImage.JpegDensity.400px", 1, 1000, 100));
- density_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(density_centi_bpp));
- } else if (image_min_side >= 100) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, density_histogram,
- ("Blink.DecodedImage.JpegDensity.100px", 1, 1000, 100));
- density_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(density_centi_bpp));
- } else {
- // We don't report for images with 0 to 99px on the smallest dimension.
- }
if (image_min_side >= 100) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
index b535b55898c..3eaa016dab8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -869,51 +869,6 @@ INSTANTIATE_TEST_SUITE_P(
DecodedImageOrientationHistogramTest,
testing::ValuesIn(kDecodedImageOrientationHistogramTestParams));
-using DecodedImageDensityHistogramTest100px = BitmapHistogramTest<int>;
-
-TEST_P(DecodedImageDensityHistogramTest100px, JpegDensity) {
- RunTest("Blink.DecodedImage.JpegDensity.100px");
-}
-
-const DecodedImageDensityHistogramTest100px::ParamType
- kDecodedImageDensityHistogramTest100pxParams[] = {
- // 64x64 too small to report any metric
- {"rgb-jpeg-red.jpg",
- DecodedImageDensityHistogramTest100px::kNoSamplesReported},
- // 439x154, 23220 bytes --> 2.74 bpp
- {"cropped_mandrill.jpg", 274},
- // 320x320, 74017 bytes --> 5.78
- {"blue-wheel-srgb-color-profile.jpg", 578},
- // 632x475 too big for the 100-399px range.
- {"cat.jpg", DecodedImageDensityHistogramTest100px::kNoSamplesReported}};
-
-INSTANTIATE_TEST_SUITE_P(
- DecodedImageDensityHistogramTest100px,
- DecodedImageDensityHistogramTest100px,
- testing::ValuesIn(kDecodedImageDensityHistogramTest100pxParams));
-
-using DecodedImageDensityHistogramTest400px = BitmapHistogramTest<int>;
-
-TEST_P(DecodedImageDensityHistogramTest400px, JpegDensity) {
- RunTest("Blink.DecodedImage.JpegDensity.400px");
-}
-
-const DecodedImageDensityHistogramTest400px::ParamType
- kDecodedImageDensityHistogramTest400pxParams[] = {
- // 439x154, only one dimension is big enough.
- {"cropped_mandrill.jpg",
- DecodedImageDensityHistogramTest400px::kNoSamplesReported},
- // 320x320, not big enough.
- {"blue-wheel-srgb-color-profile.jpg",
- DecodedImageDensityHistogramTest400px::kNoSamplesReported},
- // 632x475, 68826 bytes --> 1.83
- {"cat.jpg", 183}};
-
-INSTANTIATE_TEST_SUITE_P(
- DecodedImageDensityHistogramTest400px,
- DecodedImageDensityHistogramTest400px,
- testing::ValuesIn(kDecodedImageDensityHistogramTest400pxParams));
-
using DecodedImageDensityHistogramTestKiBWeighted = BitmapHistogramTest<int>;
TEST_P(DecodedImageDensityHistogramTestKiBWeighted, JpegDensity) {
@@ -924,7 +879,7 @@ const DecodedImageDensityHistogramTestKiBWeighted::ParamType
kDecodedImageDensityHistogramTestKiBWeightedParams[] = {
// 64x64 too small to report any metric
{"rgb-jpeg-red.jpg",
- DecodedImageDensityHistogramTest100px::kNoSamplesReported},
+ DecodedImageDensityHistogramTestKiBWeighted::kNoSamplesReported},
// 439x154, 23220 bytes --> 2.74 bpp, 23 KiB (rounded up)
{"cropped_mandrill.jpg", 274, 23},
// 320x320, 74017 bytes --> 5.78, 72 KiB (rounded down)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index ab76937e4b6..7960ab34ac8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -34,6 +34,7 @@
#include "base/timer/elapsed_timer.h"
#include "cc/layers/texture_layer.h"
#include "components/viz/common/resources/transferable_resource.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
@@ -45,6 +46,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -60,8 +62,7 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size,
: logger_(std::make_unique<Logger>()),
have_recorded_draw_commands_(false),
is_hidden_(false),
- is_deferral_enabled_(
- base::FeatureList::IsEnabled(features::kCanvasAlwaysDeferral)),
+ is_being_displayed_(false),
software_rendering_while_hidden_(false),
acceleration_mode_(acceleration_mode),
color_params_(color_params),
@@ -74,25 +75,20 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size,
// Used by browser tests to detect the use of a Canvas2DLayerBridge.
TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation",
TRACE_EVENT_SCOPE_GLOBAL);
- if (is_deferral_enabled_) {
- StartRecording();
+ StartRecording();
- // Clear the background transparent or opaque. Similar code at
- // CanvasResourceProvider::Clear().
- if (IsValid()) {
- DCHECK(recorder_);
- recorder_->getRecordingCanvas()->clear(
- color_params_.GetOpacityMode() == kOpaque ? SK_ColorBLACK
- : SK_ColorTRANSPARENT);
- DidDraw(FloatRect(0.f, 0.f, size_.Width(), size_.Height()));
- }
+ // Clear the background transparent or opaque. Similar code at
+ // CanvasResourceProvider::Clear().
+ if (IsValid()) {
+ DCHECK(recorder_);
+ recorder_->getRecordingCanvas()->clear(
+ color_params_.GetOpacityMode() == kOpaque ? SK_ColorBLACK
+ : SK_ColorTRANSPARENT);
+ DidDraw(FloatRect(0.f, 0.f, size_.Width(), size_.Height()));
}
}
Canvas2DLayerBridge::~Canvas2DLayerBridge() {
- UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DLayerBridgeIsDeferred",
- is_deferral_enabled_);
-
ClearPendingRasterTimers();
if (IsHibernating())
logger_->ReportHibernationEvent(kHibernationEndedWithTeardown);
@@ -114,7 +110,6 @@ Canvas2DLayerBridge::~Canvas2DLayerBridge() {
}
void Canvas2DLayerBridge::StartRecording() {
- DCHECK(is_deferral_enabled_);
recorder_ = std::make_unique<PaintRecorder>();
cc::PaintCanvas* canvas =
recorder_->beginRecording(size_.Width(), size_.Height());
@@ -150,7 +145,7 @@ bool Canvas2DLayerBridge::ShouldAccelerate(AccelerationHint hint) const {
SharedGpuContext::ContextProviderWrapper();
if (accelerate && (!context_provider_wrapper ||
context_provider_wrapper->ContextProvider()
- ->ContextGL()
+ ->RasterInterface()
->GetGraphicsResetStatusKHR() != GL_NO_ERROR)) {
accelerate = false;
}
@@ -340,11 +335,6 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
hibernation_image_.reset();
if (resource_host_) {
- // If deferral is enabled the recorder will play back the transform, so we
- // should not do it here or else it will be applied twice
- if (!is_deferral_enabled_)
- resource_host_->RestoreCanvasMatrixClipStack(resource_provider->Canvas());
-
// shouldBeDirectComposited() may have changed.
resource_host_->SetNeedsCompositingUpdate();
}
@@ -353,11 +343,7 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
cc::PaintCanvas* Canvas2DLayerBridge::DrawingCanvas() {
DCHECK(resource_host_);
- if (is_deferral_enabled_)
- return recorder_->getRecordingCanvas();
- if (GetOrCreateResourceProvider())
- return ResourceProvider()->Canvas();
- return nullptr;
+ return recorder_->getRecordingCanvas();
}
void Canvas2DLayerBridge::UpdateFilterQuality() {
@@ -368,7 +354,7 @@ void Canvas2DLayerBridge::UpdateFilterQuality() {
layer_->SetNearestNeighbor(filter_quality == kNone_SkFilterQuality);
}
-void Canvas2DLayerBridge::SetIsHidden(bool hidden) {
+void Canvas2DLayerBridge::SetIsInHiddenPage(bool hidden) {
if (is_hidden_ == hidden)
return;
@@ -409,10 +395,6 @@ void Canvas2DLayerBridge::SetIsHidden(bool hidden) {
old_resource_provider->Snapshot()->PaintImageForCurrentFrame();
ResourceProvider()->Canvas()->drawImage(snapshot, 0, 0, &copy_paint);
}
- if (resource_host_ && !is_deferral_enabled_) {
- resource_host_->RestoreCanvasMatrixClipStack(
- ResourceProvider()->Canvas());
- }
} else {
// New resource provider could not be created. Stay with old one.
resource_host_->ReplaceResourceProvider(std::move(old_resource_provider));
@@ -422,6 +404,19 @@ void Canvas2DLayerBridge::SetIsHidden(bool hidden) {
GetOrCreateResourceProvider(); // Rude awakening
}
+void Canvas2DLayerBridge::SetIsBeingDisplayed(bool displayed) {
+ is_being_displayed_ = displayed;
+ // If the canvas is no longer being displayed, stop using the rate
+ // limiter.
+ if (!is_being_displayed_) {
+ frames_since_last_commit_ = 0;
+ if (rate_limiter_) {
+ rate_limiter_->Reset();
+ rate_limiter_.reset(nullptr);
+ }
+ }
+}
+
void Canvas2DLayerBridge::DrawFullImage(const cc::PaintImage& image) {
DrawingCanvas()->drawImage(image, 0, 0);
}
@@ -443,23 +438,18 @@ bool Canvas2DLayerBridge::WritePixels(const SkImageInfo& orig_info,
return false;
}
- if (is_deferral_enabled_) {
- // WritePixels is not supported by deferral. Since we are directly
- // rendering, we can't do deferral on top of the canvas. Disable deferral
- // completely.
- last_recording_ = nullptr;
- is_deferral_enabled_ = false;
- have_recorded_draw_commands_ = false;
- recorder_.reset();
- // install the current matrix/clip stack onto the immediate canvas
- if (GetOrCreateResourceProvider()) {
- resource_host_->RestoreCanvasMatrixClipStack(
- ResourceProvider()->Canvas());
- }
+ last_record_tainted_by_write_pixels_ = true;
+ have_recorded_draw_commands_ = false;
+ // Add a save to initialize the transform/clip stack and then restore it after
+ // the draw. This is needed because each recording initializes and the resets
+ // this state after every flush.
+ cc::PaintCanvas* canvas = ResourceProvider()->Canvas();
+ PaintCanvasAutoRestore auto_restore(canvas, true);
+ if (GetOrCreateResourceProvider()) {
+ resource_host_->RestoreCanvasMatrixClipStack(canvas);
}
ResourceProvider()->WritePixels(orig_info, pixels, row_bytes, x, y);
- DidDraw(FloatRect(x, y, orig_info.width(), orig_info.height()));
return true;
}
@@ -470,23 +460,23 @@ void Canvas2DLayerBridge::SkipQueuedDrawCommands() {
have_recorded_draw_commands_ = false;
}
- if (is_deferral_enabled_ && rate_limiter_)
+ if (rate_limiter_)
rate_limiter_->Reset();
}
void Canvas2DLayerBridge::ClearPendingRasterTimers() {
- gpu::gles2::GLES2Interface* gl_interface = nullptr;
+ gpu::raster::RasterInterface* raster_interface = nullptr;
if (IsAccelerated() && SharedGpuContext::ContextProviderWrapper() &&
SharedGpuContext::ContextProviderWrapper()->ContextProvider()) {
- gl_interface = SharedGpuContext::ContextProviderWrapper()
- ->ContextProvider()
- ->ContextGL();
+ raster_interface = SharedGpuContext::ContextProviderWrapper()
+ ->ContextProvider()
+ ->RasterInterface();
}
- if (gl_interface) {
+ if (raster_interface) {
while (!pending_raster_timers_.IsEmpty()) {
RasterTimer rt = pending_raster_timers_.TakeFirst();
- gl_interface->DeleteQueriesEXT(1, &rt.gl_query_id);
+ raster_interface->DeleteQueriesEXT(1, &rt.gl_query_id);
}
} else {
pending_raster_timers_.clear();
@@ -494,7 +484,7 @@ void Canvas2DLayerBridge::ClearPendingRasterTimers() {
}
void Canvas2DLayerBridge::FinishRasterTimers(
- gpu::gles2::GLES2Interface* gl_interface) {
+ gpu::raster::RasterInterface* raster_interface) {
// If the context was lost, then the old queries are not valid anymore
if (!CheckResourceProviderValid()) {
ClearPendingRasterTimers();
@@ -505,7 +495,7 @@ void Canvas2DLayerBridge::FinishRasterTimers(
while (!pending_raster_timers_.IsEmpty()) {
auto it = pending_raster_timers_.begin();
GLuint complete = 1;
- gl_interface->GetQueryObjectuivEXT(
+ raster_interface->GetQueryObjectuivEXT(
it->gl_query_id, GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT,
&complete);
if (!complete) {
@@ -513,8 +503,8 @@ void Canvas2DLayerBridge::FinishRasterTimers(
}
GLuint raw_gpu_duration = 0u;
- gl_interface->GetQueryObjectuivEXT(it->gl_query_id, GL_QUERY_RESULT_EXT,
- &raw_gpu_duration);
+ raster_interface->GetQueryObjectuivEXT(it->gl_query_id, GL_QUERY_RESULT_EXT,
+ &raw_gpu_duration);
base::TimeDelta gpu_duration_microseconds =
base::TimeDelta::FromMicroseconds(raw_gpu_duration);
base::TimeDelta total_time =
@@ -533,7 +523,7 @@ void Canvas2DLayerBridge::FinishRasterTimers(
"Blink.Canvas.RasterDuration.Accelerated.Total", total_time, min, max,
num_buckets);
- gl_interface->DeleteQueriesEXT(1, &it->gl_query_id);
+ raster_interface->DeleteQueriesEXT(1, &it->gl_query_id);
pending_raster_timers_.erase(it);
}
@@ -545,20 +535,18 @@ void Canvas2DLayerBridge::FlushRecording() {
TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecording");
- gpu::gles2::GLES2Interface* gl_interface = nullptr;
+ gpu::raster::RasterInterface* raster_interface = nullptr;
if (IsAccelerated() && SharedGpuContext::ContextProviderWrapper() &&
SharedGpuContext::ContextProviderWrapper()->ContextProvider()) {
- gl_interface = SharedGpuContext::ContextProviderWrapper()
- ->ContextProvider()
- ->ContextGL();
- FinishRasterTimers(gl_interface);
+ raster_interface = SharedGpuContext::ContextProviderWrapper()
+ ->ContextProvider()
+ ->RasterInterface();
+ FinishRasterTimers(raster_interface);
}
// Sample one out of every kRasterMetricProbability frames to time
- // This measurement only makes sense if deferral is enabled
- // If the canvas is accelerated, we also need access to the gl_interface
- bool measure_raster_metric = (gl_interface || !IsAccelerated()) &&
- is_deferral_enabled_ &&
+ // If the canvas is accelerated, we also need access to the raster_interface
+ bool measure_raster_metric = (raster_interface || !IsAccelerated()) &&
bernoulli_distribution_(random_generator_);
RasterTimer rasterTimer;
base::Optional<base::ElapsedTimer> timer;
@@ -566,8 +554,8 @@ void Canvas2DLayerBridge::FlushRecording() {
if (measure_raster_metric) {
if (IsAccelerated()) {
GLuint gl_id = 0u;
- gl_interface->GenQueriesEXT(1, &gl_id);
- gl_interface->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, gl_id);
+ raster_interface->GenQueriesEXT(1, &gl_id);
+ raster_interface->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, gl_id);
rasterTimer.gl_query_id = gl_id;
}
timer.emplace();
@@ -577,8 +565,8 @@ void Canvas2DLayerBridge::FlushRecording() {
cc::PaintCanvas* canvas = ResourceProvider()->Canvas();
last_recording_ = recorder_->finishRecordingAsPicture();
canvas->drawPicture(last_recording_);
- if (!clear_frame_ || !resource_host_ || !resource_host_->IsPrinting() ||
- !is_deferral_enabled_) {
+ last_record_tainted_by_write_pixels_ = false;
+ if (!clear_frame_ || !resource_host_ || !resource_host_->IsPrinting()) {
last_recording_ = nullptr;
clear_frame_ = false;
}
@@ -589,7 +577,7 @@ void Canvas2DLayerBridge::FlushRecording() {
if (measure_raster_metric) {
if (IsAccelerated()) {
rasterTimer.cpu_raster_duration = timer->Elapsed();
- gl_interface->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
+ raster_interface->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
pending_raster_timers_.push_back(rasterTimer);
} else {
UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
@@ -606,11 +594,14 @@ void Canvas2DLayerBridge::FlushRecording() {
if (GetOrCreateResourceProvider())
ResourceProvider()->ReleaseLockedImages();
- if (is_deferral_enabled_)
- StartRecording();
+ StartRecording();
have_recorded_draw_commands_ = false;
}
+bool Canvas2DLayerBridge::HasRateLimiterForTesting() {
+ return !!rate_limiter_;
+}
+
bool Canvas2DLayerBridge::IsValid() {
return CheckResourceProviderValid();
}
@@ -640,14 +631,17 @@ bool Canvas2DLayerBridge::Restore() {
return false;
DCHECK(!ResourceProvider());
- gpu::gles2::GLES2Interface* shared_gl = nullptr;
+ gpu::raster::RasterInterface* shared_raster_interface = nullptr;
layer_->ClearTexture();
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper =
SharedGpuContext::ContextProviderWrapper();
- if (context_provider_wrapper)
- shared_gl = context_provider_wrapper->ContextProvider()->ContextGL();
+ if (context_provider_wrapper) {
+ shared_raster_interface =
+ context_provider_wrapper->ContextProvider()->RasterInterface();
+ }
- if (shared_gl && shared_gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
+ if (shared_raster_interface &&
+ shared_raster_interface->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
CanvasResourceProvider* resource_provider =
resource_host_->GetOrCreateCanvasResourceProviderImpl(
kPreferAcceleration);
@@ -722,8 +716,7 @@ cc::Layer* Canvas2DLayerBridge::Layer() {
}
void Canvas2DLayerBridge::DidDraw(const FloatRect& /* rect */) {
- if (is_deferral_enabled_)
- have_recorded_draw_commands_ = true;
+ have_recorded_draw_commands_ = true;
}
void Canvas2DLayerBridge::FinalizeFrame() {
@@ -735,13 +728,16 @@ void Canvas2DLayerBridge::FinalizeFrame() {
return;
FlushRecording();
- ++frames_since_last_commit_;
- if (frames_since_last_commit_ >= 2) {
- if (IsAccelerated() && !rate_limiter_) {
- // Make sure the GPU is never more than two animation frames behind.
- constexpr unsigned kMaxCanvasAnimationBacklog = 2;
- rate_limiter_ = std::make_unique<SharedContextRateLimiter>(
- kMaxCanvasAnimationBacklog);
+ if (is_being_displayed_) {
+ ++frames_since_last_commit_;
+ // Make sure the GPU is never more than two animation frames behind.
+ constexpr unsigned kMaxCanvasAnimationBacklog = 2;
+ if (frames_since_last_commit_ >=
+ static_cast<int>(kMaxCanvasAnimationBacklog)) {
+ if (IsAccelerated() && !rate_limiter_) {
+ rate_limiter_ = std::make_unique<SharedContextRateLimiter>(
+ kMaxCanvasAnimationBacklog);
+ }
}
}
@@ -759,7 +755,7 @@ scoped_refptr<StaticBitmapImage> Canvas2DLayerBridge::NewImageSnapshot(
if (snapshot_state_ == kInitialSnapshotState)
snapshot_state_ = kDidAcquireSnapshot;
if (IsHibernating())
- return StaticBitmapImage::Create(hibernation_image_);
+ return UnacceleratedStaticBitmapImage::Create(hibernation_image_);
if (!IsValid())
return nullptr;
// GetOrCreateResourceProvider needs to be called before FlushRecording, to
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
index 06c069f13a3..16a2bcf63d9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
@@ -38,7 +38,7 @@
#include "cc/layers/texture_layer_client.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
@@ -99,7 +99,8 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
override;
void FinalizeFrame();
- void SetIsHidden(bool);
+ void SetIsInHiddenPage(bool);
+ void SetIsBeingDisplayed(bool);
void DidDraw(const FloatRect&);
void DoPaintInvalidation(const FloatRect& dirty_rect);
cc::Layer* Layer();
@@ -136,6 +137,14 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
cc::TextureLayer* layer_for_testing() { return layer_.get(); }
+ // TODO(jochin): Remove this function completely once recorder_ has been
+ // moved into CanvasResourceProvider.
+ sk_sp<cc::PaintRecord> record_for_testing() {
+ sk_sp<cc::PaintRecord> record = recorder_->finishRecordingAsPicture();
+ StartRecording();
+ return record;
+ }
+
// The values of the enum entries must not change because they are used for
// usage metrics histograms. New values can be added to the end.
enum HibernationEvent {
@@ -170,12 +179,15 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
CanvasResourceProvider* ResourceProvider() const;
void FlushRecording();
- sk_sp<cc::PaintRecord> getLastRecord() { return last_recording_; }
+ sk_sp<cc::PaintRecord> getLastRecord() {
+ return last_record_tainted_by_write_pixels_ ? nullptr : last_recording_;
+ }
// This is called when the Canvas element has cleared the frame, so the 2D
// bridge knows that there's no previous content on the resource.
void ClearFrame() { clear_frame_ = true; }
- bool IsDeferralEnabled() const { return is_deferral_enabled_; }
+
+ bool HasRateLimiterForTesting();
private:
friend class Canvas2DLayerBridgeTest;
@@ -199,13 +211,17 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
int frames_since_last_commit_ = 0;
bool have_recorded_draw_commands_;
bool is_hidden_;
- bool is_deferral_enabled_;
+ bool is_being_displayed_;
bool software_rendering_while_hidden_;
bool hibernation_scheduled_ = false;
bool dont_use_idle_scheduling_for_testing_ = false;
bool context_lost_ = false;
bool clear_frame_ = true;
+ // WritePixels content is not saved in recording. If a call was made to
+ // WritePixels, the recording is now missing that information.
+ bool last_record_tainted_by_write_pixels_ = false;
+
const AccelerationMode acceleration_mode_;
const CanvasColorParams color_params_;
const IntSize size_;
@@ -217,7 +233,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
mutable SnapshotState snapshot_state_;
void ClearPendingRasterTimers();
- void FinishRasterTimers(gpu::gles2::GLES2Interface*);
+ void FinishRasterTimers(gpu::raster::RasterInterface*);
struct RasterTimer {
// The id for querying the duration of the gpu-side of the draw
GLuint gl_query_id = 0u;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
index aa146496726..438e238d047 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -120,12 +120,6 @@ class ImageTrackingDecodeCache : public cc::StubDecodeCache {
bool disallow_cache_use_ = false;
};
-class MockCanvasResourceHost : public blink::FakeCanvasResourceHost {
- public:
- MockCanvasResourceHost(const IntSize& size) : FakeCanvasResourceHost(size) {}
- MOCK_CONST_METHOD1(RestoreCanvasMatrixClipStack, void(cc::PaintCanvas*));
-};
-
} // anonymous namespace
class Canvas2DLayerBridgeTest : public Test {
@@ -134,15 +128,16 @@ class Canvas2DLayerBridgeTest : public Test {
const IntSize& size,
Canvas2DLayerBridge::AccelerationMode acceleration_mode,
const CanvasColorParams& color_params,
- bool disable_deferral = false) {
+ std::unique_ptr<FakeCanvasResourceHost> custom_host = nullptr) {
std::unique_ptr<Canvas2DLayerBridge> bridge =
std::make_unique<Canvas2DLayerBridge>(size, acceleration_mode,
color_params);
bridge->DontUseIdleSchedulingForTesting();
+ if (custom_host)
+ host_ = std::move(custom_host);
if (!host_)
- host_ = std::make_unique<MockCanvasResourceHost>(size);
+ host_ = std::make_unique<FakeCanvasResourceHost>(size);
bridge->SetCanvasResourceHost(host_.get());
- bridge->is_deferral_enabled_ = !disable_deferral;
return bridge;
}
@@ -159,7 +154,7 @@ class Canvas2DLayerBridgeTest : public Test {
test_context_provider_.reset();
}
- MockCanvasResourceHost* Host() {
+ FakeCanvasResourceHost* Host() {
DCHECK(host_);
return host_.get();
}
@@ -167,7 +162,7 @@ class Canvas2DLayerBridgeTest : public Test {
protected:
scoped_refptr<viz::TestContextProvider> test_context_provider_;
ImageTrackingDecodeCache image_decode_cache_;
- std::unique_ptr<MockCanvasResourceHost> host_;
+ std::unique_ptr<FakeCanvasResourceHost> host_;
};
TEST_F(Canvas2DLayerBridgeTest, DisableAcceleration) {
@@ -439,7 +434,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationLifeCycle)
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
@@ -452,7 +447,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationLifeCycle)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationEndedNormally));
- bridge->SetIsHidden(false);
+ bridge->SetIsInHiddenPage(false);
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_TRUE(bridge->IsAccelerated());
@@ -483,11 +478,11 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
// Toggle visibility before the task that enters hibernation gets a
// chance to run.
- bridge->SetIsHidden(false);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(false);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
@@ -500,7 +495,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationEndedNormally));
- bridge->SetIsHidden(false);
+ bridge->SetIsInHiddenPage(false);
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_TRUE(bridge->IsAccelerated());
@@ -508,56 +503,6 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry)
EXPECT_TRUE(bridge->IsValid());
}
-#if CANVAS2D_HIBERNATION_ENABLED
-TEST_F(Canvas2DLayerBridgeTest,
- HibernationLifeCycleWithDeferredRenderingDisabled)
-#else
-TEST_F(Canvas2DLayerBridgeTest,
- DISABLED_HibernationLifeCycleWithDeferredRenderingDisabled)
-#endif
-{
- ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
-
- std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), true);
- EXPECT_CALL(*Host(), RestoreCanvasMatrixClipStack(_)).Times(AnyNumber());
-
- bridge->DontUseIdleSchedulingForTesting();
- DrawSomething(bridge.get());
-
- // Register an alternate Logger for tracking hibernation events
- std::unique_ptr<MockLogger> mock_logger = std::make_unique<MockLogger>();
- MockLogger* mock_logger_ptr = mock_logger.get();
- bridge->SetLoggerForTesting(std::move(mock_logger));
-
- // Test entering hibernation
- EXPECT_CALL(
- *mock_logger_ptr,
- ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
- EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
- platform->RunUntilIdle();
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- testing::Mock::VerifyAndClearExpectations(host_.get());
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_TRUE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Test exiting hibernation
- EXPECT_CALL(
- *mock_logger_ptr,
- ReportHibernationEvent(Canvas2DLayerBridge::kHibernationEndedNormally));
- EXPECT_CALL(*Host(), RestoreCanvasMatrixClipStack(_))
- .Times(AtLeast(1)); // Because deferred rendering is disabled
- bridge->SetIsHidden(false);
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- testing::Mock::VerifyAndClearExpectations(Host());
- EXPECT_TRUE(bridge->IsAccelerated());
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-}
-
#if CANVAS2D_HIBERNATION_ENABLED && CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU
TEST_F(Canvas2DLayerBridgeTest, BackgroundRenderingWhileHibernating)
#else
@@ -581,7 +526,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_BackgroundRenderingWhileHibernating)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_FALSE(bridge->IsAccelerated());
@@ -600,7 +545,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_BackgroundRenderingWhileHibernating)
EXPECT_TRUE(bridge->IsValid());
// Unhide
- bridge->SetIsHidden(false);
+ bridge->SetIsInHiddenPage(false);
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_TRUE(
bridge->IsAccelerated()); // Becoming visible causes switch back to GPU
@@ -608,65 +553,6 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_BackgroundRenderingWhileHibernating)
EXPECT_TRUE(bridge->IsValid());
}
-#if CANVAS2D_HIBERNATION_ENABLED && CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU
-TEST_F(Canvas2DLayerBridgeTest,
- BackgroundRenderingWhileHibernatingWithDeferredRenderingDisabled)
-#else
-TEST_F(
- Canvas2DLayerBridgeTest,
- DISABLED_BackgroundRenderingWhileHibernatingWithDeferredRenderingDisabled)
-#endif
-{
- ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
- std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
- bridge->DontUseIdleSchedulingForTesting();
- DrawSomething(bridge.get());
- EXPECT_CALL(*Host(), RestoreCanvasMatrixClipStack(_)).Times(AnyNumber());
-
- // Register an alternate Logger for tracking hibernation events
- std::unique_ptr<MockLogger> mock_logger = std::make_unique<MockLogger>();
- MockLogger* mock_logger_ptr = mock_logger.get();
- bridge->SetLoggerForTesting(std::move(mock_logger));
-
- // Test entering hibernation
- EXPECT_CALL(
- *mock_logger_ptr,
- ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
- EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
- platform->RunUntilIdle();
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- testing::Mock::VerifyAndClearExpectations(Host());
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_TRUE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Rendering in the background -> temp switch to SW
- EXPECT_CALL(*mock_logger_ptr,
- ReportHibernationEvent(
- Canvas2DLayerBridge::
- kHibernationEndedWithSwitchToBackgroundRendering));
- EXPECT_CALL(*Host(), RestoreCanvasMatrixClipStack(_)).Times(AtLeast(1));
- DrawSomething(bridge.get());
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- testing::Mock::VerifyAndClearExpectations(Host());
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Unhide
- EXPECT_CALL(*Host(), RestoreCanvasMatrixClipStack(_)).Times(AtLeast(1));
- bridge->SetIsHidden(false);
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- testing::Mock::VerifyAndClearExpectations(Host());
- EXPECT_TRUE(
- bridge->IsAccelerated()); // Becoming visible causes switch back to GPU
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-}
-
#if CANVAS2D_HIBERNATION_ENABLED
TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernating)
#else
@@ -690,7 +576,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernating)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_FALSE(bridge->IsAccelerated());
@@ -728,7 +614,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_SnapshotWhileHibernating)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_FALSE(bridge->IsAccelerated());
@@ -751,7 +637,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_SnapshotWhileHibernating)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationEndedNormally))
.Times(1);
- bridge->SetIsHidden(false);
+ bridge->SetIsInHiddenPage(false);
}
#if CANVAS2D_HIBERNATION_ENABLED
@@ -776,7 +662,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernationIsPending)
EXPECT_CALL(
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
bridge.reset();
// In production, we would expect a
// HibernationAbortedDueToDestructionWhileHibernatePending event to be
@@ -815,8 +701,8 @@ TEST_F(Canvas2DLayerBridgeTest,
ReportHibernationEvent(
Canvas2DLayerBridge::kHibernationAbortedDueToVisibilityChange))
.Times(1);
- bridge->SetIsHidden(true);
- bridge->SetIsHidden(false);
+ bridge->SetIsInHiddenPage(true);
+ bridge->SetIsInHiddenPage(false);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_TRUE(bridge->IsAccelerated());
@@ -853,7 +739,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationAbortedDueToLostContext)
Canvas2DLayerBridge::kHibernationAbortedDueGpuContextLoss))
.Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
EXPECT_FALSE(bridge->IsHibernating());
@@ -882,7 +768,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileHibernating)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
@@ -926,7 +812,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileBackgroundRendering)
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
platform->RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
@@ -1010,7 +896,7 @@ TEST_F(Canvas2DLayerBridgeTest, NoResourceRecyclingWhenPageHidden) {
// resource should be dropped.
callbacks[0]->Run(gpu::SyncToken(), false);
EXPECT_EQ(test_context_provider_->TestContextGL()->NumTextures(), 2u);
- bridge->SetIsHidden(true);
+ bridge->SetIsInHiddenPage(true);
EXPECT_EQ(test_context_provider_->TestContextGL()->NumTextures(), 1u);
// Release second frame, this resource is not released because its the current
@@ -1047,7 +933,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseResourcesAfterBridgeDestroyed) {
TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
auto color_params =
- CanvasColorParams(kSRGBCanvasColorSpace, kF16CanvasPixelFormat, kOpaque);
+ CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
+ kOpaque, CanvasForceRGBA::kNotForced);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
@@ -1071,8 +958,9 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
}
TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
- auto color_params = CanvasColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kOpaque);
+ auto color_params =
+ CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kRGBA8,
+ kOpaque, CanvasForceRGBA::kNotForced);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
color_params);
@@ -1095,10 +983,11 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
auto color_params =
- CanvasColorParams(kSRGBCanvasColorSpace, kF16CanvasPixelFormat, kOpaque);
+ CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
+ kOpaque, CanvasForceRGBA::kNotForced);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params, true);
+ color_params);
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -1114,12 +1003,17 @@ TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
// First 2 images are budgeted, they should remain locked after the op.
bridge->DrawingCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
bridge->DrawingCanvas()->drawImage(images[1].paint_image(), 0u, 0u, nullptr);
+ // TODO(jochin): Can just call provider::FlushSkia() once we move recorder_
+ // to the resource provider. The following is a temp workaround.
+ cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
+ canvas->drawPicture(bridge->record_for_testing());
EXPECT_EQ(image_decode_cache_.num_locked_images(), 2);
// Next image is not budgeted, we should unlock all images other than the last
// image.
image_decode_cache_.set_budget_exceeded(true);
bridge->DrawingCanvas()->drawImage(images[2].paint_image(), 0u, 0u, nullptr);
+ canvas->drawPicture(bridge->record_for_testing());
EXPECT_EQ(image_decode_cache_.num_locked_images(), 1);
// Ask the provider to release everything, no locked images should remain.
@@ -1129,16 +1023,22 @@ TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
auto color_params =
- CanvasColorParams(kSRGBCanvasColorSpace, kF16CanvasPixelFormat, kOpaque);
+ CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
+ kOpaque, CanvasForceRGBA::kNotForced);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params, true);
+ color_params);
auto image =
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
SkIRect::MakeWH(10, 10), kNone_SkFilterQuality,
SkMatrix::I(), 0u, color_params.GetStorageGfxColorSpace());
bridge->DrawingCanvas()->drawImage(image.paint_image(), 0u, 0u, nullptr);
+
+ // TODO(jochin): Can just call provider::FlushSkia() once we move recorder_
+ // to the resource provider. The following is a temp workaround.
+ cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
+ canvas->drawPicture(bridge->record_for_testing());
EXPECT_EQ(image_decode_cache_.num_locked_images(), 1);
base::RunLoop().RunUntilIdle();
@@ -1147,10 +1047,11 @@ TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
TEST_F(Canvas2DLayerBridgeTest, ImageCacheOnContextLost) {
auto color_params =
- CanvasColorParams(kSRGBCanvasColorSpace, kF16CanvasPixelFormat, kOpaque);
+ CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
+ kOpaque, CanvasForceRGBA::kNotForced);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params, true);
+ color_params);
PaintFlags flags;
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -1191,5 +1092,72 @@ TEST_F(Canvas2DLayerBridgeTest,
&release_callback2));
EXPECT_EQ(release_callback2, nullptr);
}
+class CustomFakeCanvasResourceHost : public FakeCanvasResourceHost {
+ public:
+ explicit CustomFakeCanvasResourceHost(const IntSize& size)
+ : FakeCanvasResourceHost(size) {}
+ void RestoreCanvasMatrixClipStack(cc::PaintCanvas* canvas) const override {
+ // Alter canvas' matrix to emulate a restore
+ canvas->translate(5, 0);
+ }
+};
+
+TEST_F(Canvas2DLayerBridgeTest, WritePixelsRestoresClipStack) {
+ CanvasColorParams color_params(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kF16, kOpaque,
+ CanvasForceRGBA::kNotForced);
+ IntSize size = IntSize(300, 300);
+ auto host = std::make_unique<CustomFakeCanvasResourceHost>(size);
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration, color_params,
+ std::move(host));
+ PaintFlags flags;
+
+ EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+ 0);
+
+ cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
+ bridge->WritePixels(SkImageInfo::MakeN32Premul(10, 10), nullptr, 10, 0, 0);
+ // Recording canvas maintain clip stack, while underlying SkCanvas should not.
+ EXPECT_EQ(canvas->getTotalMatrix().get(SkMatrix::kMTransX), 0);
+ EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+ 5);
+
+ bridge->DrawingCanvas()->drawLine(0, 0, 2, 2, flags);
+ // Flush recording. Recording canvas should maintain matrix, while SkCanvas
+ // should not.
+ DrawSomething(bridge.get());
+ EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+ 5);
+ EXPECT_EQ(canvas->getTotalMatrix().get(SkMatrix::kMTransX), 0);
+}
+
+TEST_F(Canvas2DLayerBridgeTest, DisplayedCanvasIsRateLimited) {
+ std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
+ IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
+ CanvasColorParams());
+ EXPECT_TRUE(bridge->IsValid());
+ bridge->SetIsBeingDisplayed(true);
+ EXPECT_FALSE(bridge->HasRateLimiterForTesting());
+ bridge->FinalizeFrame();
+ bridge->FinalizeFrame();
+ EXPECT_TRUE(bridge->HasRateLimiterForTesting());
+}
+
+TEST_F(Canvas2DLayerBridgeTest, NonDisplayedCanvasIsNotRateLimited) {
+ std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
+ IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
+ CanvasColorParams());
+ EXPECT_TRUE(bridge->IsValid());
+ bridge->SetIsBeingDisplayed(true);
+ bridge->FinalizeFrame();
+ bridge->FinalizeFrame();
+ EXPECT_TRUE(bridge->HasRateLimiterForTesting());
+ bridge->SetIsBeingDisplayed(false);
+ EXPECT_FALSE(bridge->HasRateLimiterForTesting());
+ bridge->FinalizeFrame();
+ bridge->FinalizeFrame();
+ EXPECT_FALSE(bridge->HasRateLimiterForTesting());
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
index 1aedba288ae..a947db5fb56 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
@@ -20,14 +20,14 @@ namespace {
gfx::ColorSpace::PrimaryID GetPrimaryID(CanvasColorSpace color_space) {
gfx::ColorSpace::PrimaryID primary_id = gfx::ColorSpace::PrimaryID::BT709;
switch (color_space) {
- case kSRGBCanvasColorSpace:
- case kLinearRGBCanvasColorSpace:
+ case CanvasColorSpace::kSRGB:
+ case CanvasColorSpace::kLinearRGB:
primary_id = gfx::ColorSpace::PrimaryID::BT709;
break;
- case kRec2020CanvasColorSpace:
+ case CanvasColorSpace::kRec2020:
primary_id = gfx::ColorSpace::PrimaryID::BT2020;
break;
- case kP3CanvasColorSpace:
+ case CanvasColorSpace::kP3:
primary_id = gfx::ColorSpace::PrimaryID::SMPTEST432_1;
break;
}
@@ -40,16 +40,11 @@ CanvasColorParams::CanvasColorParams() = default;
CanvasColorParams::CanvasColorParams(CanvasColorSpace color_space,
CanvasPixelFormat pixel_format,
- OpacityMode opacity_mode)
+ OpacityMode opacity_mode,
+ CanvasForceRGBA force_rgba)
: color_space_(color_space),
pixel_format_(pixel_format),
- opacity_mode_(opacity_mode) {}
-
-CanvasColorParams::CanvasColorParams(const CanvasColorParams& params,
- bool force_rgba)
- : color_space_(params.color_space_),
- pixel_format_(params.pixel_format_),
- opacity_mode_(params.opacity_mode_),
+ opacity_mode_(opacity_mode),
force_rgba_(force_rgba) {}
CanvasColorParams::CanvasColorParams(const SkImageInfo& info)
@@ -68,9 +63,10 @@ bool CanvasColorParams::NeedsColorConversion(
}
SkColorType CanvasColorParams::GetSkColorType() const {
- if (pixel_format_ == kF16CanvasPixelFormat)
+ if (pixel_format_ == CanvasPixelFormat::kF16)
return kRGBA_F16_SkColorType;
- return force_rgba_ ? kRGBA_8888_SkColorType : kN32_SkColorType;
+ return force_rgba_ == CanvasForceRGBA::kForced ? kRGBA_8888_SkColorType
+ : kN32_SkColorType;
}
SkAlphaType CanvasColorParams::GetSkAlphaType() const {
@@ -95,7 +91,7 @@ gfx::ColorSpace CanvasColorParams::GetSamplerGfxColorSpace() const {
// will be sampled in linear or nonlinear space.
gfx::ColorSpace::TransferID transfer_id =
gfx::ColorSpace::TransferID::IEC61966_2_1;
- if (pixel_format_ == kF16CanvasPixelFormat)
+ if (pixel_format_ == CanvasPixelFormat::kF16)
transfer_id = gfx::ColorSpace::TransferID::LINEAR_HDR;
return gfx::ColorSpace(primary_id, transfer_id);
@@ -108,7 +104,7 @@ gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const {
gfx::ColorSpace::TransferID::IEC61966_2_1;
// Only sRGB and e-sRGB use sRGB transfer function. Other canvas color spaces,
// i.e., linear-rgb, p3 and rec2020 use linear transfer function.
- if (color_space_ != kSRGBCanvasColorSpace)
+ if (color_space_ != CanvasColorSpace::kSRGB)
transfer_id = gfx::ColorSpace::TransferID::LINEAR_HDR;
return gfx::ColorSpace(primary_id, transfer_id);
@@ -118,16 +114,16 @@ sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpace() const {
skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB;
skcms_TransferFunction transferFn = SkNamedTransferFn::kSRGB;
switch (color_space_) {
- case kSRGBCanvasColorSpace:
+ case CanvasColorSpace::kSRGB:
break;
- case kLinearRGBCanvasColorSpace:
+ case CanvasColorSpace::kLinearRGB:
transferFn = SkNamedTransferFn::kLinear;
break;
- case kRec2020CanvasColorSpace:
+ case CanvasColorSpace::kRec2020:
gamut = SkNamedGamut::kRec2020;
transferFn = SkNamedTransferFn::kLinear;
break;
- case kP3CanvasColorSpace:
+ case CanvasColorSpace::kP3:
gamut = SkNamedGamut::kDCIP3;
transferFn = SkNamedTransferFn::kLinear;
break;
@@ -213,37 +209,37 @@ viz::ResourceFormat CanvasColorParams::TransferableResourceFormat() const {
CanvasColorParams::CanvasColorParams(const sk_sp<SkColorSpace> color_space,
SkColorType color_type) {
- color_space_ = kSRGBCanvasColorSpace;
- pixel_format_ = kRGBA8CanvasPixelFormat;
+ color_space_ = CanvasColorSpace::kSRGB;
+ pixel_format_ = CanvasPixelFormat::kRGBA8;
// When there is no color space information, the SkImage is in legacy mode and
// the color type is kN32_SkColorType (which translates to kRGBA8 canvas pixel
// format).
if (!color_space)
return;
- // kSRGBCanvasColorSpace covers sRGB and e-sRGB. We need to check for
+ // CanvasColorSpace::kSRGB covers sRGB and e-sRGB. We need to check for
// linear-rgb, rec2020 and p3.
if (SkColorSpace::Equals(color_space.get(),
SkColorSpace::MakeSRGB()->makeLinearGamma().get())) {
- color_space_ = kLinearRGBCanvasColorSpace;
+ color_space_ = CanvasColorSpace::kLinearRGB;
} else if (SkColorSpace::Equals(
color_space.get(),
SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
SkNamedGamut::kRec2020)
.get())) {
- color_space_ = kRec2020CanvasColorSpace;
+ color_space_ = CanvasColorSpace::kRec2020;
} else if (SkColorSpace::Equals(
color_space.get(),
SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
SkNamedGamut::kDCIP3)
.get())) {
- color_space_ = kP3CanvasColorSpace;
+ color_space_ = CanvasColorSpace::kP3;
}
if (color_type == kRGBA_F16_SkColorType)
- pixel_format_ = kF16CanvasPixelFormat;
+ pixel_format_ = CanvasPixelFormat::kF16;
else if (color_type == kRGBA_8888_SkColorType)
- force_rgba_ = true;
+ force_rgba_ = CanvasForceRGBA::kForced;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
index 11a140fa4a9..5c1dfde62a9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
@@ -25,31 +25,37 @@ class ColorSpace;
namespace blink {
-enum CanvasColorSpace {
- kSRGBCanvasColorSpace,
- kLinearRGBCanvasColorSpace,
- kRec2020CanvasColorSpace,
- kP3CanvasColorSpace,
+enum class CanvasColorSpace {
+ kSRGB,
+ kLinearRGB,
+ kRec2020,
+ kP3,
};
-enum CanvasPixelFormat {
- kRGBA8CanvasPixelFormat,
- kF16CanvasPixelFormat,
+enum class CanvasPixelFormat {
+ kRGBA8,
+ kF16,
};
+// todo(crbug/1021986) remove force_rgba in canvasColorParams
+enum class CanvasForceRGBA { kForced, kNotForced };
+
class PLATFORM_EXPORT CanvasColorParams {
DISALLOW_NEW();
public:
// The default constructor will create an output-blended 8-bit surface.
CanvasColorParams();
- CanvasColorParams(CanvasColorSpace, CanvasPixelFormat, OpacityMode);
- CanvasColorParams(const CanvasColorParams& params, bool force_rgba);
+ CanvasColorParams(CanvasColorSpace,
+ CanvasPixelFormat,
+ OpacityMode,
+ CanvasForceRGBA);
explicit CanvasColorParams(const SkImageInfo&);
CanvasColorSpace ColorSpace() const { return color_space_; }
CanvasPixelFormat PixelFormat() const { return pixel_format_; }
OpacityMode GetOpacityMode() const { return opacity_mode_; }
+ CanvasForceRGBA GetForceRGBA() const { return force_rgba_; }
void SetCanvasColorSpace(CanvasColorSpace c) { color_space_ = c; }
void SetCanvasPixelFormat(CanvasPixelFormat f) { pixel_format_ = f; }
@@ -92,10 +98,10 @@ class PLATFORM_EXPORT CanvasColorParams {
CanvasColorParams(const sk_sp<SkColorSpace> color_space,
SkColorType color_type);
- CanvasColorSpace color_space_ = kSRGBCanvasColorSpace;
- CanvasPixelFormat pixel_format_ = kRGBA8CanvasPixelFormat;
+ CanvasColorSpace color_space_ = CanvasColorSpace::kSRGB;
+ CanvasPixelFormat pixel_format_ = CanvasPixelFormat::kRGBA8;
OpacityMode opacity_mode_ = kNonOpaque;
- bool force_rgba_ = false;
+ CanvasForceRGBA force_rgba_ = CanvasForceRGBA::kNotForced;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
index 2b3d5ac5471..352fa6c89a0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
@@ -18,14 +18,15 @@ namespace blink {
// spaces are approximately the same for different CanvasColorParam objects.
TEST(CanvasColorParamsTest, MatchSkColorSpaceWithGfxColorSpace) {
CanvasColorSpace canvas_color_spaces[] = {
- kSRGBCanvasColorSpace,
- kLinearRGBCanvasColorSpace,
- kRec2020CanvasColorSpace,
- kP3CanvasColorSpace,
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kLinearRGB,
+ CanvasColorSpace::kRec2020,
+ CanvasColorSpace::kP3,
};
for (int iter_color_space = 0; iter_color_space < 4; iter_color_space++) {
CanvasColorParams color_params(canvas_color_spaces[iter_color_space],
- kF16CanvasPixelFormat, kNonOpaque);
+ CanvasPixelFormat::kF16, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
sk_sp<SkColorSpace> canvas_drawing_color_space =
color_params.GetSkColorSpace();
sk_sp<SkColorSpace> canvas_media_color_space =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
index f6b8014c19c..429b7c2fab1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -13,6 +13,7 @@
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
@@ -23,6 +24,7 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -71,17 +73,28 @@ void CanvasResource::OnDestroy() {
#endif
}
+gpu::InterfaceBase* CanvasResource::InterfaceBase() const {
+ if (!ContextProviderWrapper())
+ return nullptr;
+ return ContextProviderWrapper()->ContextProvider()->InterfaceBase();
+}
+
gpu::gles2::GLES2Interface* CanvasResource::ContextGL() const {
if (!ContextProviderWrapper())
return nullptr;
return ContextProviderWrapper()->ContextProvider()->ContextGL();
}
+gpu::raster::RasterInterface* CanvasResource::RasterInterface() const {
+ if (!ContextProviderWrapper())
+ return nullptr;
+ return ContextProviderWrapper()->ContextProvider()->RasterInterface();
+}
+
void CanvasResource::WaitSyncToken(const gpu::SyncToken& sync_token) {
if (sync_token.HasData()) {
- auto* gl = ContextGL();
- if (gl)
- gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
+ if (auto* interface_base = InterfaceBase())
+ interface_base->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
}
@@ -92,6 +105,9 @@ static void ReleaseFrameResources(
bool lost_resource) {
resource->WaitSyncToken(sync_token);
+ if (resource_provider)
+ resource_provider->NotifyTexParamsModified(resource.get());
+
// TODO(khushalsagar): If multiple readers had access to this resource, losing
// it once should make sure subsequent releases don't try to recycle this
// resource.
@@ -127,8 +143,7 @@ bool CanvasResource::PrepareAcceleratedTransferableResource(
"CanvasResource::PrepareAcceleratedTransferableResource");
// Gpu compositing is a prerequisite for compositing an accelerated resource
DCHECK(SharedGpuContext::IsGpuCompositingEnabled());
- auto* gl = ContextGL();
- if (!gl)
+ if (!ContextProviderWrapper())
return false;
const gpu::Mailbox& mailbox = GetOrCreateGpuMailbox(sync_mode);
if (mailbox.IsZero())
@@ -242,7 +257,7 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedBitmap::Bitmap() {
static_cast<CanvasResourceSharedBitmap*>(resource_to_unref)->Release();
},
this);
- auto image = StaticBitmapImage::Create(sk_image);
+ auto image = UnacceleratedStaticBitmapImage::Create(sk_image);
image->SetOriginClean(is_origin_clean_);
return image;
}
@@ -362,11 +377,11 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
// Wait for the mailbox to be ready to be used.
WaitSyncToken(shared_image_interface->GenUnverifiedSyncToken());
- auto* gl = ContextGL();
- DCHECK(gl);
+ auto* raster_interface = RasterInterface();
+ DCHECK(raster_interface);
owning_thread_data().shared_image_mailbox = shared_image_mailbox;
owning_thread_data().texture_id_for_read_access =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(shared_image_mailbox.name);
+ raster_interface->CreateAndConsumeForGpuRaster(shared_image_mailbox);
// For the non-accelerated case, writes are done on the CPU. So we don't need
// a texture for writes.
@@ -374,7 +389,7 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
return;
if (allow_concurrent_read_write_access) {
owning_thread_data().texture_id_for_write_access =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(shared_image_mailbox.name);
+ raster_interface->CreateAndConsumeForGpuRaster(shared_image_mailbox);
} else {
owning_thread_data().texture_id_for_write_access =
owning_thread_data().texture_id_for_read_access;
@@ -415,24 +430,26 @@ void CanvasResourceSharedImage::TearDown() {
DCHECK(!is_cross_thread());
if (ContextProviderWrapper()) {
- auto* gl = ContextGL();
+ auto* raster_interface = RasterInterface();
auto* shared_image_interface =
ContextProviderWrapper()->ContextProvider()->SharedImageInterface();
- if (gl && shared_image_interface) {
+ if (raster_interface && shared_image_interface) {
gpu::SyncToken shared_image_sync_token;
- gl->GenUnverifiedSyncTokenCHROMIUM(shared_image_sync_token.GetData());
+ raster_interface->GenUnverifiedSyncTokenCHROMIUM(
+ shared_image_sync_token.GetData());
shared_image_interface->DestroySharedImage(shared_image_sync_token,
mailbox());
}
- if (gl) {
+ if (raster_interface) {
if (owning_thread_data().texture_id_for_read_access) {
- gl->DeleteTextures(1, &owning_thread_data().texture_id_for_read_access);
+ raster_interface->DeleteGpuRasterTexture(
+ owning_thread_data().texture_id_for_read_access);
}
if (owning_thread_data().texture_id_for_write_access &&
owning_thread_data().texture_id_for_write_access !=
owning_thread_data().texture_id_for_read_access) {
- gl->DeleteTextures(1,
- &owning_thread_data().texture_id_for_write_access);
+ raster_interface->DeleteGpuRasterTexture(
+ owning_thread_data().texture_id_for_write_access);
}
}
}
@@ -458,10 +475,6 @@ void CanvasResourceSharedImage::WillDraw() {
if (!is_accelerated_)
return;
- // If skia is accessing the resource, it can modify the texture's filter
- // params. Make sure to set them to the desired value before sending the
- // resource to the display compositor.
- owning_thread_data().needs_gl_filter_reset = true;
owning_thread_data().mailbox_needs_new_sync_token = true;
}
@@ -486,17 +499,12 @@ void CanvasResourceSharedImage::OnBitmapImageDestroyed(
resource->owning_thread_data().bitmap_image_read_refs--;
if (resource->owning_thread_data().bitmap_image_read_refs == 0u &&
- resource->ContextGL()) {
- resource->ContextGL()->EndSharedImageAccessDirectCHROMIUM(
+ resource->RasterInterface()) {
+ resource->RasterInterface()->EndSharedImageAccessDirectCHROMIUM(
resource->owning_thread_data().texture_id_for_read_access);
}
}
- // The StaticBitmapImage is used for readbacks which may modify the texture
- // params. Note that this is racy, since the modification and resetting of the
- // param is not atomic so the display may draw with incorrect params, but its
- // a good enough fix for now.
- resource->owning_thread_data().needs_gl_filter_reset = true;
auto weak_provider = resource->WeakProvider();
ReleaseFrameResources(std::move(weak_provider), std::move(resource),
sync_token, is_lost);
@@ -506,10 +514,6 @@ void CanvasResourceSharedImage::Transfer() {
if (is_cross_thread() || !ContextProviderWrapper())
return;
- // Initialize GLFilter first so that the generated sync token includes this
- // update.
- SetGLFilterIfNeeded();
-
// TODO(khushalsagar): This is for consistency with MailboxTextureHolder
// transfer path. Its unclear why the verification can not be deferred until
// the resource needs to be transferred cross-process.
@@ -529,7 +533,8 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedImage::Bitmap() {
gpu_memory_buffer_->stride(0));
auto sk_image = SkImage::MakeRasterCopy(pixmap);
gpu_memory_buffer_->Unmap();
- return sk_image ? StaticBitmapImage::Create(sk_image) : nullptr;
+ return sk_image ? UnacceleratedStaticBitmapImage::Create(sk_image)
+ : nullptr;
}
// In order to avoid creating multiple representations for this shared image
@@ -546,8 +551,9 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedImage::Bitmap() {
if (has_read_ref_on_texture) {
texture_id_for_image = owning_thread_data().texture_id_for_read_access;
owning_thread_data().bitmap_image_read_refs++;
- if (owning_thread_data().bitmap_image_read_refs == 1u && ContextGL()) {
- ContextGL()->BeginSharedImageAccessDirectCHROMIUM(
+ if (owning_thread_data().bitmap_image_read_refs == 1u &&
+ RasterInterface()) {
+ RasterInterface()->BeginSharedImageAccessDirectCHROMIUM(
texture_id_for_image, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
}
}
@@ -571,13 +577,6 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedImage::Bitmap() {
context_provider_wrapper_, owning_thread_id_, is_origin_top_left_,
std::move(release_callback));
- // The StaticBitmapImage is used for readbacks which may modify the texture
- // params. We reset this when the image is destroyed but it is important to
- // also do it here in case we try to send the resource to the display
- // compositor while the |image| is still alive.
- if (!is_cross_thread())
- owning_thread_data().needs_gl_filter_reset = true;
-
DCHECK(image);
return image;
}
@@ -603,30 +602,11 @@ void CanvasResourceSharedImage::CopyRenderingResultsToGpuMemoryBuffer(
const gpu::Mailbox& CanvasResourceSharedImage::GetOrCreateGpuMailbox(
MailboxSyncMode sync_mode) {
if (!is_cross_thread()) {
- SetGLFilterIfNeeded();
owning_thread_data().mailbox_sync_mode = sync_mode;
}
return mailbox();
}
-void CanvasResourceSharedImage::SetGLFilterIfNeeded() {
- DCHECK(!is_cross_thread());
-
- if (!owning_thread_data().needs_gl_filter_reset || !ContextGL() ||
- !WeakProvider())
- return;
-
- ContextGL()->BindTexture(texture_target_, GetTextureIdForReadAccess());
- ContextGL()->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER,
- GLFilter());
- ContextGL()->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER,
- GLFilter());
- ContextGL()->BindTexture(texture_target_, 0u);
- owning_thread_data().mailbox_needs_new_sync_token = true;
- owning_thread_data().needs_gl_filter_reset = false;
- Provider()->NotifyTexParamsModified(this);
-}
-
bool CanvasResourceSharedImage::HasGpuMailbox() const {
return !mailbox().IsZero();
}
@@ -644,9 +624,10 @@ const gpu::SyncToken CanvasResourceSharedImage::GetSyncToken() {
}
if (mailbox_needs_new_sync_token()) {
- auto* gl = ContextGL();
- DCHECK(gl); // caller should already have early exited if !gl.
- gl->GenUnverifiedSyncTokenCHROMIUM(
+ auto* raster_interface = RasterInterface();
+ DCHECK(raster_interface); // caller should already have early exited if
+ // !raster_interface.
+ raster_interface->GenUnverifiedSyncTokenCHROMIUM(
owning_thread_data().sync_token.GetData());
owning_thread_data().mailbox_needs_new_sync_token = false;
}
@@ -654,9 +635,9 @@ const gpu::SyncToken CanvasResourceSharedImage::GetSyncToken() {
if (owning_thread_data().mailbox_sync_mode == kVerifiedSyncToken &&
!owning_thread_data().sync_token.verified_flush()) {
int8_t* token_data = owning_thread_data().sync_token.GetData();
- auto* gl = ContextGL();
- gl->ShallowFlushCHROMIUM();
- gl->VerifySyncTokensCHROMIUM(&token_data, 1);
+ auto* raster_interface = RasterInterface();
+ raster_interface->ShallowFlushCHROMIUM();
+ raster_interface->VerifySyncTokensCHROMIUM(&token_data, 1);
owning_thread_data().sync_token.SetVerifyFlush();
}
@@ -666,9 +647,6 @@ const gpu::SyncToken CanvasResourceSharedImage::GetSyncToken() {
void CanvasResourceSharedImage::NotifyResourceLost() {
owning_thread_data().is_lost = true;
- // Since the texture params are in an unknown state, reset the cached tex
- // params state for the resource.
- owning_thread_data().needs_gl_filter_reset = true;
if (WeakProvider())
Provider()->NotifyTexParamsModified(this);
}
@@ -688,12 +666,13 @@ scoped_refptr<ExternalCanvasResource> ExternalCanvasResource::Create(
const CanvasColorParams& color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
base::WeakPtr<CanvasResourceProvider> provider,
- SkFilterQuality filter_quality) {
+ SkFilterQuality filter_quality,
+ bool is_origin_top_left) {
TRACE_EVENT0("blink", "ExternalCanvasResource::Create");
- auto resource = AdoptRef(
- new ExternalCanvasResource(mailbox, size, texture_target, color_params,
- std::move(context_provider_wrapper),
- std::move(provider), filter_quality));
+ auto resource = AdoptRef(new ExternalCanvasResource(
+ mailbox, size, texture_target, color_params,
+ std::move(context_provider_wrapper), std::move(provider), filter_quality,
+ is_origin_top_left));
return resource->IsValid() ? resource : nullptr;
}
@@ -706,7 +685,7 @@ bool ExternalCanvasResource::IsValid() const {
}
void ExternalCanvasResource::Abandon() {
- // We don't need to do anything since we don't own the mailbox.
+ // We don't need to destroy the shared image mailbox since we don't own it.
}
void ExternalCanvasResource::TakeSkImage(sk_sp<SkImage> image) {
@@ -714,8 +693,23 @@ void ExternalCanvasResource::TakeSkImage(sk_sp<SkImage> image) {
}
scoped_refptr<StaticBitmapImage> ExternalCanvasResource::Bitmap() {
- NOTREACHED();
- return nullptr;
+ TRACE_EVENT0("blink", "ExternalCanvasResource::Bitmap");
+ if (!IsValid())
+ return nullptr;
+
+ // The |release_callback| keeps a ref on this resource to ensure the backing
+ // shared image is kept alive until the lifetime of the image.
+ auto release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
+ [](scoped_refptr<ExternalCanvasResource> resource,
+ const gpu::SyncToken& sync_token, bool is_lost) {
+ // Do nothing but hold onto the refptr.
+ },
+ base::RetainedRef(this)));
+
+ return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
+ mailbox_, GetSyncToken(), /*shared_image_texture_id=*/0u,
+ CreateSkImageInfo(), texture_target_, context_provider_wrapper_,
+ owning_thread_id_, is_origin_top_left_, std::move(release_callback));
}
void ExternalCanvasResource::TearDown() {
@@ -755,12 +749,14 @@ ExternalCanvasResource::ExternalCanvasResource(
const CanvasColorParams& color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
base::WeakPtr<CanvasResourceProvider> provider,
- SkFilterQuality filter_quality)
+ SkFilterQuality filter_quality,
+ bool is_origin_top_left)
: CanvasResource(std::move(provider), filter_quality, color_params),
context_provider_wrapper_(std::move(context_provider_wrapper)),
size_(size),
+ mailbox_(mailbox),
texture_target_(texture_target),
- mailbox_(mailbox) {}
+ is_origin_top_left_(is_origin_top_left) {}
// CanvasResourceSwapChain
//==============================================================================
@@ -826,12 +822,14 @@ void CanvasResourceSwapChain::Abandon() {
void CanvasResourceSwapChain::TearDown() {
if (!context_provider_wrapper_)
return;
- auto* gl = context_provider_wrapper_->ContextProvider()->ContextGL();
- DCHECK(gl);
- gl->EndSharedImageAccessDirectCHROMIUM(front_buffer_texture_id_);
- gl->DeleteTextures(1u, &front_buffer_texture_id_);
- gl->EndSharedImageAccessDirectCHROMIUM(back_buffer_texture_id_);
- gl->DeleteTextures(1u, &back_buffer_texture_id_);
+ auto* raster_interface =
+ context_provider_wrapper_->ContextProvider()->RasterInterface();
+ DCHECK(raster_interface);
+ raster_interface->EndSharedImageAccessDirectCHROMIUM(
+ front_buffer_texture_id_);
+ raster_interface->DeleteGpuRasterTexture(front_buffer_texture_id_);
+ raster_interface->EndSharedImageAccessDirectCHROMIUM(back_buffer_texture_id_);
+ raster_interface->DeleteGpuRasterTexture(back_buffer_texture_id_);
// No synchronization is needed here because the GL SharedImageRepresentation
// will keep the backing alive on the service until the textures are deleted.
auto* sii =
@@ -861,35 +859,30 @@ void CanvasResourceSwapChain::PresentSwapChain() {
DCHECK(context_provider_wrapper_);
TRACE_EVENT0("blink", "CanvasResourceSwapChain::PresentSwapChain");
- auto* gl = context_provider_wrapper_->ContextProvider()->ContextGL();
- DCHECK(gl);
-
- // Skia could've changed the filter state if the front buffer was exported as
- // a bitmap image. This will be a nop on the service side most of the time.
- gl->BindTexture(GL_TEXTURE_2D, front_buffer_texture_id_);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GLFilter());
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GLFilter());
+ auto* raster_interface =
+ context_provider_wrapper_->ContextProvider()->RasterInterface();
+ DCHECK(raster_interface);
auto* sii =
context_provider_wrapper_->ContextProvider()->SharedImageInterface();
DCHECK(sii);
// Synchronize presentation and rendering.
- gl->GenUnverifiedSyncTokenCHROMIUM(sync_token_.GetData());
+ raster_interface->GenUnverifiedSyncTokenCHROMIUM(sync_token_.GetData());
sii->PresentSwapChain(sync_token_, back_buffer_mailbox_);
// This only gets called via the CanvasResourceDispatcher export path so a
// verified sync token will be needed ultimately.
sync_token_ = sii->GenVerifiedSyncToken();
- gl->WaitSyncTokenCHROMIUM(sync_token_.GetData());
+ raster_interface->WaitSyncTokenCHROMIUM(sync_token_.GetData());
// PresentSwapChain() flips the front and back buffers, but the mailboxes
// still refer to the current front and back buffer after present. So the
// front buffer contains the content we just rendered, and it needs to be
// copied into the back buffer to support a retained mode like canvas expects.
// The wait sync token ensure that the present executes before we do the copy.
- gl->CopySubTextureCHROMIUM(
- front_buffer_texture_id_, 0, GL_TEXTURE_2D, back_buffer_texture_id_, 0, 0,
- 0, 0, 0, size_.Width(), size_.Height(), GL_FALSE, GL_FALSE, GL_FALSE);
+ raster_interface->CopySubTexture(front_buffer_mailbox_, back_buffer_mailbox_,
+ GL_TEXTURE_2D, 0, 0, 0, 0, size_.Width(),
+ size_.Height());
}
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
@@ -926,18 +919,19 @@ CanvasResourceSwapChain::CanvasResourceSwapChain(
sync_token_ = sii->GenVerifiedSyncToken();
// Wait for the mailboxes to be ready to be used.
- auto* gl = context_provider_wrapper_->ContextProvider()->ContextGL();
- DCHECK(gl);
- gl->WaitSyncTokenCHROMIUM(sync_token_.GetData());
+ auto* raster_interface =
+ context_provider_wrapper_->ContextProvider()->RasterInterface();
+ DCHECK(raster_interface);
+ raster_interface->WaitSyncTokenCHROMIUM(sync_token_.GetData());
front_buffer_texture_id_ =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(front_buffer_mailbox_.name);
- gl->BeginSharedImageAccessDirectCHROMIUM(
+ raster_interface->CreateAndConsumeForGpuRaster(front_buffer_mailbox_);
+ raster_interface->BeginSharedImageAccessDirectCHROMIUM(
front_buffer_texture_id_, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
back_buffer_texture_id_ =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(back_buffer_mailbox_.name);
- gl->BeginSharedImageAccessDirectCHROMIUM(
+ raster_interface->CreateAndConsumeForGpuRaster(back_buffer_mailbox_);
+ raster_interface->BeginSharedImageAccessDirectCHROMIUM(
back_buffer_texture_id_, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
index 2442ab2425c..b5f09b1d63d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -25,6 +25,14 @@ class GpuMemoryBuffer;
} // namespace gfx
+namespace gpu {
+namespace raster {
+
+class RasterInterface;
+
+} // namespace raster
+} // namespace gpu
+
namespace viz {
class SingleReleaseCallback;
@@ -152,6 +160,7 @@ class PLATFORM_EXPORT CanvasResource
Abandon();
}
+ void SetFilterQuality(SkFilterQuality filter) { filter_quality_ = filter; }
// The filter quality to use when the resource is drawn by the compositor.
SkFilterQuality FilterQuality() const { return filter_quality_; }
@@ -183,7 +192,9 @@ class PLATFORM_EXPORT CanvasResource
// was created.
virtual void TearDown() = 0;
+ gpu::InterfaceBase* InterfaceBase() const;
gpu::gles2::GLES2Interface* ContextGL() const;
+ gpu::raster::RasterInterface* RasterInterface() const;
GLenum GLFilter() const;
GrContext* GetGrContext() const;
virtual base::WeakPtr<WebGraphicsContext3DProviderWrapper>
@@ -311,7 +322,6 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
bool mailbox_needs_new_sync_token = true;
gpu::Mailbox shared_image_mailbox;
gpu::SyncToken sync_token;
- bool needs_gl_filter_reset = true;
size_t bitmap_image_read_refs = 0u;
MailboxSyncMode mailbox_sync_mode = kVerifiedSyncToken;
bool is_lost = false;
@@ -350,7 +360,6 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
bool is_origin_top_left,
bool allow_concurrent_read_write_access,
bool is_accelerated);
- void SetGLFilterIfNeeded();
OwningThreadData& owning_thread_data() {
DCHECK_EQ(base::PlatformThread::CurrentId(), owning_thread_id_);
@@ -406,7 +415,8 @@ class PLATFORM_EXPORT ExternalCanvasResource final : public CanvasResource {
const CanvasColorParams&,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
base::WeakPtr<CanvasResourceProvider>,
- SkFilterQuality);
+ SkFilterQuality,
+ bool is_origin_top_left);
~ExternalCanvasResource() override;
bool IsRecycleable() const final { return IsValid(); }
bool IsAccelerated() const final { return true; }
@@ -437,13 +447,16 @@ class PLATFORM_EXPORT ExternalCanvasResource final : public CanvasResource {
const CanvasColorParams&,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
base::WeakPtr<CanvasResourceProvider>,
- SkFilterQuality);
+ SkFilterQuality,
+ bool is_origin_top_left);
const base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper_;
const IntSize size_;
+ const gpu::Mailbox mailbox_;
const GLenum texture_target_;
- gpu::Mailbox mailbox_;
+ const bool is_origin_top_left_;
+
gpu::SyncToken sync_token_;
bool is_origin_clean_ = true;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
index e1ee697308a..48e1f492be5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/debug/stack_trace.h"
#include "base/single_thread_task_runner.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/texture_draw_quad.h"
@@ -84,8 +85,6 @@ CanvasResourceDispatcher::~CanvasResourceDispatcher() = default;
namespace {
void UpdatePlaceholderImage(
- base::WeakPtr<CanvasResourceDispatcher> dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
int placeholder_canvas_id,
scoped_refptr<blink::CanvasResource> canvas_resource,
viz::ResourceId resource_id) {
@@ -94,12 +93,24 @@ void UpdatePlaceholderImage(
OffscreenCanvasPlaceholder::GetPlaceholderCanvasById(
placeholder_canvas_id);
if (placeholder_canvas) {
- placeholder_canvas->SetOffscreenCanvasFrame(
- std::move(canvas_resource), std::move(dispatcher),
- std::move(task_runner), resource_id);
+ placeholder_canvas->SetOffscreenCanvasResource(std::move(canvas_resource),
+ resource_id);
}
}
+void UpdatePlaceholderDispatcher(
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ int placeholder_canvas_id) {
+ OffscreenCanvasPlaceholder* placeholder_canvas =
+ OffscreenCanvasPlaceholder::GetPlaceholderCanvasById(
+ placeholder_canvas_id);
+ // Note that the placeholder canvas may be destroyed when this post task get
+ // to executed.
+ if (placeholder_canvas)
+ placeholder_canvas->SetOffscreenCanvasDispatcher(dispatcher, task_runner);
+}
+
} // namespace
void CanvasResourceDispatcher::PostImageToPlaceholderIfNotBlocked(
@@ -131,17 +142,13 @@ void CanvasResourceDispatcher::PostImageToPlaceholder(
viz::ResourceId resource_id) {
scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner =
Thread::Current()->GetTaskRunner();
-
// After this point, |canvas_resource| can only be used on the main thread,
// until it is returned.
canvas_resource->Transfer();
-
PostCrossThreadTask(
*Thread::MainThread()->Scheduler()->CompositorTaskRunner(), FROM_HERE,
- CrossThreadBindOnce(UpdatePlaceholderImage, this->GetWeakPtr(),
- WTF::Passed(std::move(dispatcher_task_runner)),
- placeholder_canvas_id_, std::move(canvas_resource),
- resource_id));
+ CrossThreadBindOnce(UpdatePlaceholderImage, placeholder_canvas_id_,
+ std::move(canvas_resource), resource_id));
}
void CanvasResourceDispatcher::DispatchFrameSync(
@@ -405,6 +412,32 @@ void CanvasResourceDispatcher::DidDeleteSharedBitmap(
sink_->DidDeleteSharedBitmap(std::move(id));
}
+void CanvasResourceDispatcher::SetFilterQuality(
+ SkFilterQuality filter_quality) {
+ if (Client())
+ Client()->SetFilterQualityInResource(filter_quality);
+}
+
+void CanvasResourceDispatcher::SetPlaceholderCanvasDispatcher(
+ int placeholder_canvas_id) {
+ scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner =
+ Thread::Current()->GetTaskRunner();
+
+ // If the offscreencanvas is in the same tread as the canvas, we will update
+ // the canvas resource dispatcher directly. So Offscreen Canvas can behave in
+ // a more synchronous way when it's on the main thread.
+ if (IsMainThread()) {
+ UpdatePlaceholderDispatcher(this->GetWeakPtr(), dispatcher_task_runner,
+ placeholder_canvas_id);
+ } else {
+ PostCrossThreadTask(
+ *Thread::MainThread()->Scheduler()->CompositorTaskRunner(), FROM_HERE,
+ CrossThreadBindOnce(UpdatePlaceholderDispatcher, this->GetWeakPtr(),
+ WTF::Passed(std::move(dispatcher_task_runner)),
+ placeholder_canvas_id));
+ }
+}
+
void CanvasResourceDispatcher::ReclaimResourceInternal(
viz::ResourceId resource_id) {
auto it = resources_.find(resource_id);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
index 30710a8e31b..9a6ac41b2fb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
@@ -23,6 +23,7 @@ class CanvasResource;
class CanvasResourceDispatcherClient {
public:
virtual bool BeginFrame() = 0;
+ virtual void SetFilterQualityInResource(SkFilterQuality filter_quality) = 0;
};
class PLATFORM_EXPORT CanvasResourceDispatcher
@@ -81,6 +82,9 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
::gpu::mojom::blink::MailboxPtr id);
void DidDeleteSharedBitmap(::gpu::mojom::blink::MailboxPtr id);
+ void SetFilterQuality(SkFilterQuality filter_quality);
+ void SetPlaceholderCanvasDispatcher(int placeholder_canvas_id);
+
private:
friend class CanvasResourceDispatcherTest;
struct FrameResource;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
index ce82e6a0cb2..da54b134ac3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
@@ -280,5 +280,7 @@ const TestParams kTestCases[] = {
{true, false},
{true, true}};
-INSTANTIATE_TEST_SUITE_P(, CanvasResourceDispatcherTest, ValuesIn(kTestCases));
+INSTANTIATE_TEST_SUITE_P(All,
+ CanvasResourceDispatcherTest,
+ ValuesIn(kTestCases));
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index 749a1f77dfa..5ae4615f80f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -12,13 +12,15 @@
#include "cc/tiles/software_image_decode_cache.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
-#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace blink {
@@ -88,7 +90,6 @@ class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap {
}
~CanvasResourceProviderSharedBitmap() override = default;
bool SupportsDirectCompositing() const override { return true; }
- bool SupportsSingleBuffering() const override { return true; }
private:
scoped_refptr<CanvasResource> CreateResource() final {
@@ -96,7 +97,7 @@ class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap {
if (!IsBitmapFormatSupported(color_params.TransferableResourceFormat())) {
// If the rendering format is not supported, downgrate to 8-bits.
// TODO(junov): Should we try 12-12-12-12 and 10-10-10-2?
- color_params.SetCanvasPixelFormat(kRGBA8CanvasPixelFormat);
+ color_params.SetCanvasPixelFormat(CanvasPixelFormat::kRGBA8);
}
return CanvasResourceSharedBitmap::Create(Size(), color_params,
@@ -143,7 +144,11 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
filter_quality,
// TODO(khushalsagar): The software path seems to be assuming N32
// somewhere in the later pipeline but for offscreen canvas only.
- CanvasColorParams(color_params, is_accelerated /* force_rgba */),
+ CanvasColorParams(color_params.ColorSpace(),
+ color_params.PixelFormat(),
+ color_params.GetOpacityMode(),
+ is_accelerated ? CanvasForceRGBA::kForced
+ : CanvasForceRGBA::kNotForced),
is_origin_top_left,
std::move(context_provider_wrapper),
std::move(resource_dispatcher)),
@@ -217,6 +222,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// readers.
EndWriteAccess();
scoped_refptr<CanvasResource> resource = resource_;
+ resource->SetFilterQuality(FilterQuality());
if (ContextProviderWrapper()
->ContextProvider()
->GetCapabilities()
@@ -283,7 +289,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (surface_) {
// Take read access to the outgoing resource for the skia copy below.
if (!old_resource_shared_image->has_read_access()) {
- ContextGL()->BeginSharedImageAccessDirectCHROMIUM(
+ RasterInterface()->BeginSharedImageAccessDirectCHROMIUM(
old_resource_shared_image->GetTextureIdForReadAccess(),
GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
}
@@ -291,7 +297,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
GetGrSurfaceOrigin());
surface_->flush();
if (!old_resource_shared_image->has_read_access()) {
- ContextGL()->EndSharedImageAccessDirectCHROMIUM(
+ RasterInterface()->EndSharedImageAccessDirectCHROMIUM(
old_resource_shared_image->GetTextureIdForReadAccess());
}
}
@@ -388,7 +394,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (is_accelerated_) {
auto texture_id = resource()->GetTextureIdForWriteAccess();
- ContextGL()->BeginSharedImageAccessDirectCHROMIUM(
+ RasterInterface()->BeginSharedImageAccessDirectCHROMIUM(
texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
}
@@ -408,7 +414,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// Issue any skia work using this resource before releasing write access.
FlushGrContext();
auto texture_id = resource()->GetTextureIdForWriteAccess();
- ContextGL()->EndSharedImageAccessDirectCHROMIUM(texture_id);
+ RasterInterface()->EndSharedImageAccessDirectCHROMIUM(texture_id);
} else {
if (DoCopyOnWrite())
resource_ = NewOrRecycledResource();
@@ -446,13 +452,14 @@ class CanvasResourceProviderPassThrough final : public CanvasResourceProvider {
const CanvasColorParams& color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
+ base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
+ bool is_origin_top_left)
: CanvasResourceProvider(kPassThrough,
size,
/*msaa_sample_count=*/0,
filter_quality,
color_params,
- /*is_origin_top_left=*/true,
+ is_origin_top_left,
std::move(context_provider_wrapper),
std::move(resource_dispatcher)) {}
@@ -480,8 +487,10 @@ class CanvasResourceProviderPassThrough final : public CanvasResourceProvider {
}
scoped_refptr<StaticBitmapImage> Snapshot() override {
- NOTREACHED();
- return nullptr;
+ auto resource = GetImportedResource();
+ if (IsGpuContextLost() || !resource)
+ return nullptr;
+ return resource->Bitmap();
}
};
@@ -543,7 +552,12 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
scoped_refptr<StaticBitmapImage> Snapshot() override {
TRACE_EVENT0("blink", "CanvasResourceProviderSwapChain::Snapshot");
- return SnapshotInternal();
+
+ // Use ProduceCanvasResource to ensure any queued commands are flushed and
+ // the resource is updated.
+ if (auto resource = ProduceCanvasResource())
+ return resource->Bitmap();
+ return nullptr;
}
sk_sp<SkSurface> CreateSkSurface() const override {
@@ -575,12 +589,11 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
namespace {
enum class CanvasResourceType {
- kDirect3DSwapChain,
+ kDirect3DPassThrough,
kDirect2DSwapChain,
- kDirect3DGpuMemoryBuffer,
+ kSharedImage,
kSharedBitmap,
kBitmap,
- kSharedImage,
};
const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
@@ -620,14 +633,13 @@ const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
// from an external source. The external site should take care of
// using SharedImages since the resource will be used by the display
// compositor.
- CanvasResourceType::kDirect3DSwapChain,
- CanvasResourceType::kDirect3DGpuMemoryBuffer,
+ CanvasResourceType::kDirect3DPassThrough,
// The rest is equal to |kCompositedFallbackList|.
CanvasResourceType::kSharedImage,
CanvasResourceType::kSharedBitmap,
CanvasResourceType::kBitmap,
});
- DCHECK(std::equal(kAcceleratedDirect3DFallbackList.begin() + 2,
+ DCHECK(std::equal(kAcceleratedDirect3DFallbackList.begin() + 1,
kAcceleratedDirect3DFallbackList.end(),
kCompositedFallbackList.begin(),
kCompositedFallbackList.end()));
@@ -696,39 +708,34 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
bool is_origin_top_left) {
std::unique_ptr<CanvasResourceProvider> provider;
- if (context_provider_wrapper) {
- const int max_texture_size = context_provider_wrapper->ContextProvider()
- ->GetCapabilities()
- .max_texture_size;
+ bool is_gpu_memory_buffer_image_allowed = false;
+ bool is_swap_chain_allowed = false;
+
+ if (SharedGpuContext::IsGpuCompositingEnabled() && context_provider_wrapper) {
+ const auto& context_capabilities =
+ context_provider_wrapper->ContextProvider()->GetCapabilities();
+
+ const int max_texture_size = context_capabilities.max_texture_size;
+
if (size.Width() > max_texture_size || size.Height() > max_texture_size)
usage = ResourceUsage::kSoftwareResourceUsage;
+
+ is_gpu_memory_buffer_image_allowed =
+ (presentation_mode & kAllowImageChromiumPresentationMode) &&
+ Platform::Current()->GetGpuMemoryBufferManager() &&
+ gpu::IsImageSizeValidForGpuMemoryBufferFormat(
+ gfx::Size(size), color_params.GetBufferFormat()) &&
+ gpu::IsImageFromGpuMemoryBufferFormatSupported(
+ color_params.GetBufferFormat(), context_capabilities);
+
+ is_swap_chain_allowed =
+ (presentation_mode & kAllowSwapChainPresentationMode) &&
+ context_capabilities.shared_image_swap_chain;
}
const Vector<CanvasResourceType>& fallback_list =
GetResourceTypeFallbackList(usage);
-#if defined(OS_ANDROID)
- // TODO(khushalsagar): Re-enable these if we're using SurfaceControl and
- // GMBs allow us to overlay these resources.
- const bool is_gpu_memory_buffer_image_allowed = false;
-#else
- const bool is_gpu_memory_buffer_image_allowed =
- SharedGpuContext::IsGpuCompositingEnabled() && context_provider_wrapper &&
- (presentation_mode & kAllowImageChromiumPresentationMode) &&
- gpu::IsImageSizeValidForGpuMemoryBufferFormat(
- gfx::Size(size), color_params.GetBufferFormat()) &&
- gpu::IsImageFromGpuMemoryBufferFormatSupported(
- color_params.GetBufferFormat(),
- context_provider_wrapper->ContextProvider()->GetCapabilities());
-#endif
-
- const bool is_swap_chain_allowed =
- SharedGpuContext::IsGpuCompositingEnabled() && context_provider_wrapper &&
- context_provider_wrapper->ContextProvider()
- ->GetCapabilities()
- .shared_image_swap_chain &&
- (presentation_mode & kAllowSwapChainPresentationMode);
-
for (CanvasResourceType resource_type : fallback_list) {
// Note: We are deliberately not using std::move() on
// |context_provider_wrapper| and |resource_dispatcher| to ensure that the
@@ -742,19 +749,12 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
size, msaa_sample_count, filter_quality, color_params,
context_provider_wrapper, resource_dispatcher);
break;
- case CanvasResourceType::kDirect3DSwapChain:
- if (!is_swap_chain_allowed)
- continue;
- provider = std::make_unique<CanvasResourceProviderPassThrough>(
- size, filter_quality, color_params, context_provider_wrapper,
- resource_dispatcher);
- break;
- case CanvasResourceType::kDirect3DGpuMemoryBuffer:
- if (!is_gpu_memory_buffer_image_allowed)
+ case CanvasResourceType::kDirect3DPassThrough:
+ if (!is_gpu_memory_buffer_image_allowed && !is_swap_chain_allowed)
continue;
provider = std::make_unique<CanvasResourceProviderPassThrough>(
size, filter_quality, color_params, context_provider_wrapper,
- resource_dispatcher);
+ resource_dispatcher, is_origin_top_left);
break;
case CanvasResourceType::kSharedBitmap:
if (!resource_dispatcher)
@@ -773,14 +773,16 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
if (!context_provider_wrapper)
continue;
- const bool usage_wants_single_buffered =
- usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect3DResourceUsage ||
- usage == ResourceUsage::kSoftwareCompositedDirect2DResourceUsage;
- const bool usage_wants_overlays =
- usage_wants_single_buffered ||
+ const bool is_accelerated =
+ usage == ResourceUsage::kAcceleratedResourceUsage ||
usage == ResourceUsage::kAcceleratedCompositedResourceUsage ||
- usage == ResourceUsage::kSoftwareCompositedResourceUsage;
+ usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
+ usage == ResourceUsage::kAcceleratedDirect3DResourceUsage;
+
+ // If the rendering will be in software and we don't have GMB support,
+ // fallback to bitmap provider type.
+ if (!is_accelerated && !is_gpu_memory_buffer_image_allowed)
+ continue;
// texture_storage_image is required to create shared images supporting
// scanout usage.
@@ -790,29 +792,21 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
->GetCapabilities()
.texture_storage_image;
- const bool can_use_gmbs =
- is_gpu_memory_buffer_image_allowed &&
- Platform::Current()->GetGpuMemoryBufferManager();
-
const bool is_overlay_candidate =
- usage_wants_overlays && can_use_overlays;
- const bool is_accelerated =
- usage == ResourceUsage::kAcceleratedResourceUsage ||
- usage == ResourceUsage::kAcceleratedCompositedResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect3DResourceUsage;
-
- // If the rendering will be in software and we don't have GMB support,
- // fallback to bitmap provider type.
- if (!is_accelerated && !can_use_gmbs)
- continue;
-
- // TODO(khushalsagar) Single buffering requires concurrent
- // read/write access to the resource which is sub-optimal for software
- // raster since that would require concurrent access to the resource on
- // the CPU and GPU. Check if we should disable it in software mode.
+ (usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
+ usage == ResourceUsage::kAcceleratedDirect3DResourceUsage ||
+ usage == ResourceUsage::kAcceleratedCompositedResourceUsage ||
+ usage == ResourceUsage::kSoftwareCompositedResourceUsage) &&
+ can_use_overlays;
+
+ // Single buffering requires concurrent read/write access to the
+ // resource which is sub-optimal for software raster since that would
+ // require concurrent access to the resource on the CPU and GPU, so
+ // enable it for accelerated low latency canvas only.
const bool maybe_single_buffered =
- usage_wants_single_buffered && can_use_gmbs;
+ (usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
+ usage == ResourceUsage::kAcceleratedDirect3DResourceUsage) &&
+ is_gpu_memory_buffer_image_allowed;
provider = std::make_unique<CanvasResourceProviderSharedImage>(
size, msaa_sample_count, filter_quality, color_params,
@@ -1038,11 +1032,8 @@ scoped_refptr<StaticBitmapImage> CanvasResourceProvider::SnapshotInternal() {
return nullptr;
auto paint_image = MakeImageSnapshot();
- if (paint_image.GetSkImage()->isTextureBacked() && ContextProviderWrapper()) {
- return StaticBitmapImage::Create(paint_image.GetSkImage(),
- ContextProviderWrapper());
- }
- return StaticBitmapImage::Create(std::move(paint_image));
+ DCHECK(!paint_image.GetSkImage()->isTextureBacked());
+ return UnacceleratedStaticBitmapImage::Create(std::move(paint_image));
}
cc::PaintImage CanvasResourceProvider::MakeImageSnapshot() {
@@ -1073,6 +1064,12 @@ gpu::gles2::GLES2Interface* CanvasResourceProvider::ContextGL() const {
return context_provider_wrapper_->ContextProvider()->ContextGL();
}
+gpu::raster::RasterInterface* CanvasResourceProvider::RasterInterface() const {
+ if (!context_provider_wrapper_)
+ return nullptr;
+ return context_provider_wrapper_->ContextProvider()->RasterInterface();
+}
+
GrContext* CanvasResourceProvider::GetGrContext() const {
if (!context_provider_wrapper_)
return nullptr;
@@ -1084,8 +1081,9 @@ void CanvasResourceProvider::FlushSkia() const {
}
bool CanvasResourceProvider::IsGpuContextLost() const {
- auto* gl = ContextGL();
- return !gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
+ auto* raster_interface = RasterInterface();
+ return !raster_interface ||
+ raster_interface->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
}
bool CanvasResourceProvider::WritePixels(const SkImageInfo& orig_info,
@@ -1195,4 +1193,14 @@ bool CanvasResourceProvider::ImportResource(
return true;
}
+scoped_refptr<CanvasResource> CanvasResourceProvider::GetImportedResource()
+ const {
+ if (!IsSingleBuffered() || !SupportsSingleBuffering())
+ return nullptr;
+ DCHECK_LE(canvas_resources_.size(), 1u);
+ if (canvas_resources_.IsEmpty())
+ return nullptr;
+ return canvas_resources_.back();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
index c4b6c912330..910b0e526c0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -23,6 +23,12 @@ namespace gles2 {
class GLES2Interface;
} // namespace gles2
+
+namespace raster {
+
+class RasterInterface;
+
+} // namespace raster
} // namespace gpu
namespace blink {
@@ -57,7 +63,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
kAcceleratedCompositedResourceUsage = 3,
kAcceleratedDirect2DResourceUsage = 4,
kAcceleratedDirect3DResourceUsage = 5,
- kSoftwareCompositedDirect2DResourceUsage = 6,
+ kSoftwareCompositedDirect2DResourceUsage = 6, // deprecated
kMaxValue = kSoftwareCompositedDirect2DResourceUsage,
};
@@ -144,7 +150,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
// queue, thus reducing latency, but with the possible side effects of tearing
// (in cases where the resource is scanned out directly) and irregular frame
// rate.
- bool IsSingleBuffered() { return is_single_buffered_; }
+ bool IsSingleBuffered() const { return is_single_buffered_; }
// Attempt to enable single buffering mode on this resource provider. May
// fail if the CanvasResourcePRovider subclass does not support this mode of
@@ -192,6 +198,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
protected:
gpu::gles2::GLES2Interface* ContextGL() const;
+ gpu::raster::RasterInterface* RasterInterface() const;
GrContext* GetGrContext() const;
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper() {
return context_provider_wrapper_;
@@ -203,6 +210,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
}
SkFilterQuality FilterQuality() const { return filter_quality_; }
scoped_refptr<StaticBitmapImage> SnapshotInternal();
+ scoped_refptr<CanvasResource> GetImportedResource() const;
CanvasResourceProvider(const ResourceProviderType&,
const IntSize&,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
index 1f0eb8f969d..85b64c72473 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.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_gpu_memory_buffer_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -18,6 +19,8 @@
#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h"
#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/skia/include/core/SkFilterQuality.h"
+#include "ui/gfx/buffer_types.h"
using testing::_;
using testing::InSequence;
@@ -28,12 +31,15 @@ namespace blink {
namespace {
+constexpr int kMaxTextureSize = 1024;
+
class MockCanvasResourceDispatcherClient
: public CanvasResourceDispatcherClient {
public:
MockCanvasResourceDispatcherClient() = default;
MOCK_METHOD0(BeginFrame, bool());
+ MOCK_METHOD1(SetFilterQualityInResource, void(SkFilterQuality));
};
} // anonymous namespace
@@ -42,6 +48,16 @@ class CanvasResourceProviderTest : public Test {
public:
void SetUp() override {
test_context_provider_ = viz::TestContextProvider::Create();
+ auto* test_gl = test_context_provider_->UnboundTestContextGL();
+ test_gl->set_max_texture_size(kMaxTextureSize);
+ test_gl->set_support_texture_storage_image(true);
+ test_gl->set_supports_shared_image_swap_chain(true);
+ test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::RGBA_8888,
+ true);
+ test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::BGRA_8888,
+ true);
+ test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::RGBA_F16,
+ true);
InitializeSharedGpuContext(test_context_provider_.get(),
&image_decode_cache_);
context_provider_wrapper_ = SharedGpuContext::ContextProviderWrapper();
@@ -49,37 +65,6 @@ class CanvasResourceProviderTest : public Test {
void TearDown() override { SharedGpuContext::ResetForTesting(); }
- // Adds |buffer_format| to the context capabilities if it's not supported.
- void EnsureBufferFormatIsSupported(gfx::BufferFormat buffer_format) {
- auto* context_provider = context_provider_wrapper_->ContextProvider();
- if (context_provider->GetCapabilities().gpu_memory_buffer_formats.Has(
- buffer_format)) {
- return;
- }
-
- auto capabilities = context_provider->GetCapabilities();
- capabilities.gpu_memory_buffer_formats.Add(buffer_format);
-
- static_cast<FakeWebGraphicsContext3DProvider*>(context_provider)
- ->SetCapabilities(capabilities);
- }
-
- void EnsureOverlaysSupported() {
- auto* context_provider = context_provider_wrapper_->ContextProvider();
- auto capabilities = context_provider->GetCapabilities();
- capabilities.texture_storage_image = true;
- capabilities.max_texture_size = 1024;
- static_cast<FakeWebGraphicsContext3DProvider*>(context_provider)
- ->SetCapabilities(capabilities);
- }
-
- bool PlatformSupportsGMBs() {
-#if defined(OS_ANDROID)
- return false;
-#endif
- return true;
- }
-
protected:
cc::StubDecodeCache image_decode_cache_;
scoped_refptr<viz::TestContextProvider> test_context_provider_;
@@ -89,10 +74,9 @@ class CanvasResourceProviderTest : public Test {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
- EnsureOverlaysSupported();
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -106,7 +90,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
EXPECT_TRUE(provider->IsValid());
EXPECT_TRUE(provider->IsAccelerated());
EXPECT_TRUE(provider->SupportsDirectCompositing());
- EXPECT_EQ(provider->SupportsSingleBuffering(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
@@ -114,19 +98,20 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
EXPECT_FALSE(provider->IsSingleBuffered());
provider->TryEnableSingleBuffering();
- EXPECT_EQ(provider->IsSingleBuffered(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->IsSingleBuffered());
}
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize, CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
+ CanvasResourceProvider::kDefaultPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
EXPECT_EQ(provider->Size(), kSize);
@@ -144,10 +129,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
- EnsureOverlaysSupported();
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -161,8 +145,11 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
EXPECT_FALSE(provider->IsAccelerated());
- EXPECT_EQ(provider->SupportsDirectCompositing(), PlatformSupportsGMBs());
- EXPECT_EQ(provider->SupportsSingleBuffering(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+
+ // We do not support single buffering for unaccelerated low latency canvas.
+ EXPECT_FALSE(provider->SupportsSingleBuffering());
+
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
@@ -174,9 +161,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderSharedImageResourceRecycling) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -228,9 +215,9 @@ TEST_F(CanvasResourceProviderTest,
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderSharedImageStaticBitmapImage) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -272,9 +259,9 @@ TEST_F(CanvasResourceProviderTest,
fake_context->SetCapabilities(caps);
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -295,8 +282,9 @@ TEST_F(CanvasResourceProviderTest,
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize, CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
@@ -320,8 +308,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
MockCanvasResourceDispatcherClient client;
CanvasResourceDispatcher resource_dispatcher(
@@ -340,7 +329,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
EXPECT_TRUE(provider->IsValid());
EXPECT_FALSE(provider->IsAccelerated());
EXPECT_TRUE(provider->SupportsDirectCompositing());
- EXPECT_TRUE(provider->SupportsSingleBuffering());
+ EXPECT_FALSE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
@@ -348,16 +337,15 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
EXPECT_FALSE(provider->IsSingleBuffered());
provider->TryEnableSingleBuffering();
- EXPECT_TRUE(provider->IsSingleBuffered());
+ EXPECT_FALSE(provider->IsSingleBuffered());
}
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderDirect2DGpuMemoryBuffer) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
- EnsureOverlaysSupported();
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -371,7 +359,7 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_TRUE(provider->IsValid());
EXPECT_TRUE(provider->IsAccelerated());
EXPECT_TRUE(provider->SupportsDirectCompositing());
- EXPECT_EQ(provider->SupportsSingleBuffering(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
@@ -379,15 +367,15 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_FALSE(provider->IsSingleBuffered());
provider->TryEnableSingleBuffering();
- EXPECT_EQ(provider->IsSingleBuffered(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->IsSingleBuffered());
}
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderDirect3DGpuMemoryBuffer) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -401,7 +389,7 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_TRUE(provider->IsValid());
EXPECT_TRUE(provider->IsAccelerated());
EXPECT_TRUE(provider->SupportsDirectCompositing());
- EXPECT_EQ(provider->SupportsSingleBuffering(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
@@ -409,16 +397,14 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_FALSE(provider->IsSingleBuffered());
provider->TryEnableSingleBuffering();
- EXPECT_EQ(provider->IsSingleBuffered(), PlatformSupportsGMBs());
+ EXPECT_TRUE(provider->IsSingleBuffered());
- if (!PlatformSupportsGMBs())
- return;
gpu::Mailbox mailbox = gpu::Mailbox::Generate();
scoped_refptr<ExternalCanvasResource> resource =
ExternalCanvasResource::Create(
mailbox, kSize, GL_TEXTURE_2D, kColorParams,
SharedGpuContext::ContextProviderWrapper(), provider->CreateWeakPtr(),
- kMedium_SkFilterQuality);
+ kMedium_SkFilterQuality, /*is_origin_top_left=*/true);
// NewOrRecycledResource() would return nullptr before an ImportResource().
EXPECT_TRUE(provider->ImportResource(resource));
@@ -429,10 +415,11 @@ TEST_F(CanvasResourceProviderTest,
// Verifies that Accelerated Direct 3D resources are backed by SharedImages.
// https://crbug.com/985366
-TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3D) {
+TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -467,13 +454,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3D) {
}
TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
- const CanvasColorParams kColorParams(kSRGBCanvasColorSpace,
- kRGBA8CanvasPixelFormat, kNonOpaque);
- const int max_texture_size = context_provider_wrapper_->ContextProvider()
- ->GetCapabilities()
- .max_texture_size;
- EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat());
- EnsureOverlaysSupported();
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
for (int i = 0;
i < static_cast<int>(CanvasResourceProvider::ResourceUsage::kMaxValue);
@@ -490,8 +473,7 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedDirect2DResourceUsage:
- should_support_compositing = PlatformSupportsGMBs();
- break;
+ FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::
@@ -507,7 +489,7 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
}
auto provider = CanvasResourceProvider::Create(
- IntSize(max_texture_size - 1, max_texture_size), usage,
+ IntSize(kMaxTextureSize - 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
@@ -516,7 +498,7 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
should_support_compositing);
provider = CanvasResourceProvider::Create(
- IntSize(max_texture_size, max_texture_size), usage,
+ IntSize(kMaxTextureSize, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
@@ -525,7 +507,7 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
should_support_compositing);
provider = CanvasResourceProvider::Create(
- IntSize(max_texture_size + 1, max_texture_size), usage,
+ IntSize(kMaxTextureSize + 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
@@ -534,4 +516,33 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
}
}
+TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
+ const IntSize kSize(10, 10);
+ const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8, kNonOpaque,
+ CanvasForceRGBA::kNotForced);
+
+ auto provider = CanvasResourceProvider::Create(
+ kSize,
+ CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
+ context_provider_wrapper_, 0 /* msaa_sample_count */,
+ kLow_SkFilterQuality, kColorParams,
+ CanvasResourceProvider::kAllowSwapChainPresentationMode,
+ nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+
+ EXPECT_EQ(provider->Size(), kSize);
+ EXPECT_TRUE(provider->IsValid());
+ EXPECT_TRUE(provider->IsAccelerated());
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+ EXPECT_TRUE(provider->SupportsSingleBuffering());
+ EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
+ EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
+ kColorParams.GetOpacityMode());
+
+ EXPECT_FALSE(provider->IsSingleBuffered());
+ provider->TryEnableSingleBuffering();
+ EXPECT_TRUE(provider->IsSingleBuffered());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
index 482341c5ac6..680b810bf83 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
@@ -209,7 +209,7 @@ bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest(
}
skcms_PixelFormat dst_pixel_format = skcms_PixelFormat_RGBA_8888;
- if (dst_canvas_pixel_format == kF16CanvasPixelFormat) {
+ if (dst_canvas_pixel_format == CanvasPixelFormat::kF16) {
dst_pixel_format = (pixel_format_for_f16_canvas == kPixelFormat_hhhh)
? skcms_PixelFormat_RGBA_hhhh
: skcms_PixelFormat_RGBA_ffff;
@@ -219,15 +219,16 @@ bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest(
src_sk_color_space =
CanvasColorParams(src_color_space,
(src_storage_format == kUint8ClampedArrayStorageFormat)
- ? kRGBA8CanvasPixelFormat
- : kF16CanvasPixelFormat,
- kNonOpaque)
+ ? CanvasPixelFormat::kRGBA8
+ : CanvasPixelFormat::kF16,
+ kNonOpaque, CanvasForceRGBA::kNotForced)
.GetSkColorSpaceForSkSurfaces();
if (!src_sk_color_space.get())
src_sk_color_space = SkColorSpace::MakeSRGB();
sk_sp<SkColorSpace> dst_sk_color_space =
- CanvasColorParams(dst_color_space, dst_canvas_pixel_format, kNonOpaque)
+ CanvasColorParams(dst_color_space, dst_canvas_pixel_format, kNonOpaque,
+ CanvasForceRGBA::kNotForced)
.GetSkColorSpaceForSkSurfaces();
if (!dst_sk_color_space.get())
dst_sk_color_space = SkColorSpace::MakeSRGB();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index 9889add4240..cdaf3e8115e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -27,141 +27,32 @@ ContentLayerClientImpl::ContentLayerClientImpl()
raster_invalidator_(
base::BindRepeating(&ContentLayerClientImpl::InvalidateRect,
base::Unretained(this))),
- layer_state_(PropertyTreeState::Uninitialized()) {
- cc_picture_layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
-}
+ layer_state_(PropertyTreeState::Uninitialized()) {}
ContentLayerClientImpl::~ContentLayerClientImpl() {
cc_picture_layer_->ClearClient();
}
-static int GetTransformId(const TransformPaintPropertyNode* transform,
- ContentLayerClientImpl::LayerAsJSONContext& context) {
- if (!transform)
- return 0;
-
- auto transform_lookup_result = context.transform_id_map.find(transform);
- if (transform_lookup_result != context.transform_id_map.end())
- return transform_lookup_result->value;
-
- int parent_id = GetTransformId(transform->Parent(), context);
- if (transform->IsIdentity() && !transform->RenderingContextId()) {
- context.transform_id_map.Set(transform, parent_id);
- return parent_id;
- }
-
- int transform_id = context.next_transform_id++;
- context.transform_id_map.Set(transform, transform_id);
-
- auto json = std::make_unique<JSONObject>();
- json->SetInteger("id", transform_id);
- if (parent_id)
- json->SetInteger("parent", parent_id);
-
- if (!transform->IsIdentity())
- json->SetArray("transform", TransformAsJSONArray(transform->SlowMatrix()));
-
- if (!transform->IsIdentityOr2DTranslation() &&
- !transform->Matrix().IsIdentityOrTranslation())
- json->SetArray("origin", PointAsJSONArray(transform->Origin()));
-
- if (!transform->FlattensInheritedTransform())
- json->SetBoolean("flattenInheritedTransform", false);
-
- if (auto rendering_context = transform->RenderingContextId()) {
- auto context_lookup_result =
- context.rendering_context_map.find(rendering_context);
- int rendering_id = context.rendering_context_map.size() + 1;
- if (context_lookup_result == context.rendering_context_map.end())
- context.rendering_context_map.Set(rendering_context, rendering_id);
- else
- rendering_id = context_lookup_result->value;
-
- json->SetInteger("renderingContext", rendering_id);
- }
-
- if (!context.transforms_json)
- context.transforms_json = std::make_unique<JSONArray>();
- context.transforms_json->PushObject(std::move(json));
-
- return transform_id;
-}
-
-// This is the CAP version of GraphicsLayer::LayerAsJSONInternal().
-std::unique_ptr<JSONObject> ContentLayerClientImpl::LayerAsJSON(
- LayerAsJSONContext& context) const {
- auto json = std::make_unique<JSONObject>();
- json->SetString("name", debug_name_);
-
- if (context.flags & kLayerTreeIncludesDebugInfo)
- json->SetString("this", String::Format("%p", cc_picture_layer_.get()));
-
- FloatPoint position(cc_picture_layer_->offset_to_transform_parent().x(),
- cc_picture_layer_->offset_to_transform_parent().y());
- if (position != FloatPoint())
- json->SetArray("position", PointAsJSONArray(position));
-
- IntSize bounds(cc_picture_layer_->bounds().width(),
- cc_picture_layer_->bounds().height());
- if (!bounds.IsEmpty())
- json->SetArray("bounds", SizeAsJSONArray(bounds));
-
- if (cc_picture_layer_->contents_opaque())
- json->SetBoolean("contentsOpaque", true);
-
- if (!cc_picture_layer_->DrawsContent())
- json->SetBoolean("drawsContent", false);
-
- if (!cc_picture_layer_->double_sided())
- json->SetString("backfaceVisibility", "hidden");
-
- Color background_color(cc_picture_layer_->background_color());
- if (background_color.Alpha()) {
- json->SetString("backgroundColor",
- background_color.NameForLayoutTreeAsText());
- }
-
+void ContentLayerClientImpl::AppendAdditionalInfoAsJSON(
+ LayerTreeFlags flags,
+ const cc::Layer& layer,
+ JSONObject& json) const {
#if DCHECK_IS_ON()
- if (context.flags & kLayerTreeIncludesDebugInfo)
- json->SetValue("paintChunkContents", paint_chunk_debug_data_->Clone());
+ if (flags & kLayerTreeIncludesDebugInfo)
+ json.SetValue("paintChunkContents", paint_chunk_debug_data_->Clone());
#endif
- if ((context.flags & kLayerTreeIncludesPaintInvalidations) &&
+ if ((flags & kLayerTreeIncludesPaintInvalidations) &&
raster_invalidator_.GetTracking())
- raster_invalidator_.GetTracking()->AsJSON(json.get());
-
- if (int transform_id = GetTransformId(&layer_state_.Transform(), context))
- json->SetInteger("transform", transform_id);
+ raster_invalidator_.GetTracking()->AsJSON(&json);
#if DCHECK_IS_ON()
- if (context.flags & kLayerTreeIncludesPaintRecords) {
+ if (flags & kLayerTreeIncludesPaintRecords) {
LoggingCanvas canvas;
cc_display_item_list_->Raster(&canvas);
- json->SetValue("paintRecord", canvas.Log());
+ json.SetValue("paintRecord", canvas.Log());
}
#endif
-
- return json;
-}
-
-std::unique_ptr<base::trace_event::TracedValue>
-ContentLayerClientImpl::TakeDebugInfo(const cc::Layer* layer) {
- DCHECK_EQ(layer, cc_picture_layer_.get());
- auto traced_value = std::make_unique<base::trace_event::TracedValue>();
- traced_value->SetString("layer_name", LayerDebugName(layer));
- if (auto* tracking = raster_invalidator_.GetTracking()) {
- tracking->AddToTracedValue(*traced_value);
- tracking->ClearInvalidations();
- }
- // TODO(wangxianzhu): Do we need compositing_reasons,
- // squashing_disallowed_reasons and owner_node_id?
- return traced_value;
-}
-
-std::string ContentLayerClientImpl::LayerDebugName(
- const cc::Layer* layer) const {
- DCHECK_EQ(layer, cc_picture_layer_.get());
- return debug_name_.Utf8();
}
scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
@@ -174,8 +65,6 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
else
id_ = base::nullopt;
- // TODO(wangxianzhu): Avoid calling DebugName() in official release build.
- debug_name_ = paint_chunks[0].id.client.DebugName();
const auto& display_item_list = paint_artifact->GetDisplayItemList();
#if DCHECK_IS_ON()
@@ -215,7 +104,7 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
params.emplace(*raster_invalidator_.GetTracking(),
IntRect(0, 0, layer_bounds.width(), layer_bounds.height()),
- debug_name_);
+ paint_chunks[0].id.client.DebugName());
}
cc_display_item_list_ = PaintChunksToCcLayer::Convert(
paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(),
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
index 03d76178613..5ce14faec81 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
@@ -7,8 +7,8 @@
#include "base/macros.h"
#include "cc/layers/content_layer_client.h"
-#include "cc/layers/layer_client.h"
#include "cc/layers/picture_layer.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -23,7 +23,7 @@ class PaintArtifact;
class PaintChunkSubset;
class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
- public cc::LayerClient {
+ public LayerAsJSONClient {
USING_FAST_MALLOC(ContentLayerClientImpl);
public:
@@ -44,27 +44,18 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
return 0;
}
- // cc::LayerClient
- std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
- const cc::Layer*) override;
- std::string LayerDebugName(const cc::Layer*) const override;
- void DidChangeScrollbarsHiddenIfOverlay(bool) override {}
+ // LayerAsJSONClient implementation
+ void AppendAdditionalInfoAsJSON(LayerTreeFlags,
+ const cc::Layer&,
+ JSONObject&) const override;
+
+ const cc::Layer& Layer() const { return *cc_picture_layer_.get(); }
+ const PropertyTreeState& State() const { return layer_state_; }
bool Matches(const PaintChunk& paint_chunk) const {
return id_ && paint_chunk.Matches(*id_);
}
- struct LayerAsJSONContext {
- LayerAsJSONContext(LayerTreeFlags flags) : flags(flags) {}
-
- const LayerTreeFlags flags;
- int next_transform_id = 1;
- std::unique_ptr<JSONArray> transforms_json;
- HashMap<const TransformPaintPropertyNode*, int> transform_id_map;
- HashMap<int, int> rendering_context_map;
- };
- std::unique_ptr<JSONObject> LayerAsJSON(LayerAsJSONContext&) const;
-
scoped_refptr<cc::PictureLayer> UpdateCcPictureLayer(
scoped_refptr<const PaintArtifact>,
const PaintChunkSubset&,
@@ -90,8 +81,6 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
std::unique_ptr<JSONArray> paint_chunk_debug_data_;
#endif
- base::WeakPtrFactory<ContentLayerClientImpl> weak_ptr_factory_{this};
-
DISALLOW_COPY_AND_ASSIGN(ContentLayerClientImpl);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
new file mode 100644
index 00000000000..318662e15cc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
@@ -0,0 +1,154 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
+
+#include "cc/layers/layer.h"
+#include "third_party/blink/renderer/platform/geometry/float_point.h"
+#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
+
+namespace blink {
+
+namespace {
+
+String PointerAsString(const void* ptr) {
+ WTF::TextStream ts;
+ ts << ptr;
+ return ts.Release();
+}
+
+} // namespace
+
+// Create a JSON version of the specified |layer|.
+std::unique_ptr<JSONObject> CCLayerAsJSON(
+ const cc::Layer* layer,
+ LayerTreeFlags flags,
+ const FloatPoint& offset_from_transform_node) {
+ auto json = std::make_unique<JSONObject>();
+
+ if (flags & kLayerTreeIncludesDebugInfo) {
+ json->SetString("this", PointerAsString(layer));
+ json->SetInteger("ccLayerId", layer->id());
+ }
+
+ json->SetString("name", String(layer->DebugName().c_str()));
+
+ if (offset_from_transform_node != FloatPoint())
+ json->SetArray("position", PointAsJSONArray(offset_from_transform_node));
+
+ // This is testing against gfx::Size(), *not* whether the size is empty.
+ if (layer->bounds() != gfx::Size())
+ json->SetArray("bounds", SizeAsJSONArray(IntSize(layer->bounds())));
+
+ if (layer->contents_opaque())
+ json->SetBoolean("contentsOpaque", true);
+
+ if (!layer->DrawsContent())
+ json->SetBoolean("drawsContent", false);
+
+ if (!layer->double_sided())
+ json->SetString("backfaceVisibility", "hidden");
+
+ if (Color(layer->background_color()).Alpha()) {
+ json->SetString("backgroundColor",
+ Color(layer->background_color()).NameForLayoutTreeAsText());
+ }
+
+ if (flags &
+ (kLayerTreeIncludesDebugInfo | kLayerTreeIncludesCompositingReasons)) {
+ if (layer->debug_info()) {
+ auto compositing_reasons_json = std::make_unique<JSONArray>();
+ for (const char* name : layer->debug_info()->compositing_reasons)
+ compositing_reasons_json->PushString(name);
+ json->SetArray("compositingReasons", std::move(compositing_reasons_json));
+ }
+ }
+
+ return json;
+}
+
+LayersAsJSON::LayersAsJSON(LayerTreeFlags flags)
+ : flags_(flags),
+ next_transform_id_(1),
+ layers_json_(std::make_unique<JSONArray>()),
+ transforms_json_(std::make_unique<JSONArray>()) {}
+
+int LayersAsJSON::AddTransformJSON(
+ const TransformPaintPropertyNode& transform) {
+ auto it = transform_id_map_.find(&transform);
+ if (it != transform_id_map_.end())
+ return it->value;
+
+ int parent_id = 0;
+ if (transform.Parent())
+ parent_id = AddTransformJSON(*transform.Parent());
+ if (transform.IsIdentity() && !transform.RenderingContextId()) {
+ transform_id_map_.Set(&transform, parent_id);
+ return parent_id;
+ }
+
+ auto transform_json = std::make_unique<JSONObject>();
+ int transform_id = next_transform_id_++;
+ transform_id_map_.Set(&transform, transform_id);
+ transform_json->SetInteger("id", transform_id);
+ if (parent_id)
+ transform_json->SetInteger("parent", parent_id);
+
+ if (!transform.IsIdentity()) {
+ transform_json->SetArray("transform",
+ TransformAsJSONArray(transform.SlowMatrix()));
+ }
+
+ if (!transform.IsIdentityOr2DTranslation() &&
+ !transform.Matrix().IsIdentityOrTranslation())
+ transform_json->SetArray("origin", PointAsJSONArray(transform.Origin()));
+
+ if (!transform.FlattensInheritedTransform())
+ transform_json->SetBoolean("flattenInheritedTransform", false);
+
+ if (auto rendering_context = transform.RenderingContextId()) {
+ auto context_lookup_result = rendering_context_map_.find(rendering_context);
+ int rendering_id = rendering_context_map_.size() + 1;
+ if (context_lookup_result == rendering_context_map_.end())
+ rendering_context_map_.Set(rendering_context, rendering_id);
+ else
+ rendering_id = context_lookup_result->value;
+
+ transform_json->SetInteger("renderingContext", rendering_id);
+ }
+
+ transforms_json_->PushObject(std::move(transform_json));
+ return transform_id;
+}
+
+void LayersAsJSON::AddLayer(const cc::Layer& layer,
+ const FloatPoint& offset,
+ const TransformPaintPropertyNode& transform,
+ const LayerAsJSONClient* json_client) {
+ if (!(flags_ & kLayerTreeIncludesAllLayers) && !layer.DrawsContent())
+ return;
+
+ auto layer_json = CCLayerAsJSON(&layer, flags_, offset);
+ if (json_client) {
+ json_client->AppendAdditionalInfoAsJSON(flags_, layer, *(layer_json.get()));
+ }
+ int transform_id = AddTransformJSON(transform);
+ if (transform_id)
+ layer_json->SetInteger("transform", transform_id);
+ layers_json_->PushObject(std::move(layer_json));
+}
+
+std::unique_ptr<JSONObject> LayersAsJSON::Finalize() {
+ auto json = std::make_unique<JSONObject>();
+ json->SetArray("layers", std::move(layers_json_));
+ if (transforms_json_->size())
+ json->SetArray("transforms", std::move(transforms_json_));
+ return json;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h
new file mode 100644
index 00000000000..0008f97f94a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h
@@ -0,0 +1,77 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_LAYERS_AS_JSON_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_LAYERS_AS_JSON_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+
+namespace cc {
+class Layer;
+}
+
+namespace blink {
+
+class FloatPoint;
+class JSONArray;
+class JSONObject;
+class TransformPaintPropertyNode;
+
+// These values need to be kept consistent with the layer tree flags in
+// core/testing/Internals.idl.
+enum {
+ kLayerTreeNormal = 0,
+ // Dump extra debugging info like layer addresses.
+ kLayerTreeIncludesDebugInfo = 1 << 0,
+ kLayerTreeIncludesPaintInvalidations = 1 << 1,
+ kLayerTreeIncludesPaintingPhases = 1 << 2,
+ kLayerTreeIncludesAllLayers = 1 << 3,
+ kLayerTreeIncludesCompositingReasons = 1 << 5,
+ kLayerTreeIncludesPaintRecords = 1 << 6,
+ // Outputs all layers as a layer tree. The default is output children
+ // (excluding the root) as a layer list, in paint (preorder) order.
+ kOutputAsLayerTree = 0x4000,
+};
+typedef unsigned LayerTreeFlags;
+
+class PLATFORM_EXPORT LayerAsJSONClient {
+ public:
+ virtual void AppendAdditionalInfoAsJSON(LayerTreeFlags,
+ const cc::Layer&,
+ JSONObject&) const = 0;
+};
+
+class PLATFORM_EXPORT LayersAsJSON {
+ public:
+ LayersAsJSON(LayerTreeFlags);
+
+ void AddLayer(const cc::Layer& layer,
+ const FloatPoint& offset,
+ const TransformPaintPropertyNode& transform,
+ const LayerAsJSONClient* json_client);
+
+ std::unique_ptr<JSONObject> Finalize();
+
+ private:
+ int AddTransformJSON(const TransformPaintPropertyNode&);
+
+ LayerTreeFlags flags_;
+ int next_transform_id_;
+ std::unique_ptr<JSONArray> layers_json_;
+ HashMap<const TransformPaintPropertyNode*, int> transform_id_map_;
+ std::unique_ptr<JSONArray> transforms_json_;
+ HashMap<int, int> rendering_context_map_;
+};
+
+PLATFORM_EXPORT std::unique_ptr<JSONObject> CCLayerAsJSON(
+ const cc::Layer* layer,
+ LayerTreeFlags flags,
+ const FloatPoint& position);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_LAYERS_AS_JSON_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index ec618961a3a..76d426253a5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -42,25 +43,13 @@ namespace blink {
static int g_s_property_tree_sequence_number = 1;
PaintArtifactCompositor::PaintArtifactCompositor(
- base::RepeatingCallback<void(const gfx::ScrollOffset&,
- const cc::ElementId&)> scroll_callback)
- : scroll_callback_(std::move(scroll_callback)),
- tracks_raster_invalidations_(false),
- needs_update_(true) {
+ base::WeakPtr<CompositorScrollCallbacks> scroll_callbacks)
+ : scroll_callbacks_(std::move(scroll_callbacks)) {
root_layer_ = cc::Layer::Create();
}
PaintArtifactCompositor::~PaintArtifactCompositor() {}
-void PaintArtifactCompositor::EnableExtraDataForTesting() {
- if (extra_data_for_testing_enabled_)
- return;
- extra_data_for_testing_enabled_ = true;
- extra_data_for_testing_ = std::make_unique<ExtraDataForTesting>();
- // Ensure |extra_data_for_testing_| is populated.
- SetNeedsUpdate();
-}
-
void PaintArtifactCompositor::SetTracksRasterInvalidations(bool should_track) {
tracks_raster_invalidations_ = should_track;
for (auto& client : content_layer_clients_)
@@ -69,27 +58,57 @@ void PaintArtifactCompositor::SetTracksRasterInvalidations(bool should_track) {
void PaintArtifactCompositor::WillBeRemovedFromFrame() {
root_layer_->RemoveAllChildren();
- if (extra_data_for_testing_enabled_) {
- extra_data_for_testing_->content_layers.clear();
- extra_data_for_testing_->synthesized_clip_layers.clear();
- extra_data_for_testing_->scroll_hit_test_layers.clear();
- }
}
-std::unique_ptr<JSONObject> PaintArtifactCompositor::LayersAsJSON(
- LayerTreeFlags flags) const {
- if (!tracks_raster_invalidations_)
- flags &= ~kLayerTreeIncludesPaintInvalidations;
- ContentLayerClientImpl::LayerAsJSONContext context(flags);
- auto layers_json = std::make_unique<JSONArray>();
- for (const auto& client : content_layer_clients_) {
- layers_json->PushObject(client->LayerAsJSON(context));
+// Get a JSON representation of what layers exist for this PAC. Note that
+// |paint_artifact| is only needed for pre-CAP mode.
+std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
+ LayerTreeFlags flags,
+ const PaintArtifact* paint_artifact) const {
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ paint_artifact);
+ LayersAsJSON layers_as_json(flags);
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ for (const auto& layer : root_layer_->children()) {
+ const LayerAsJSONClient* json_client = nullptr;
+ const TransformPaintPropertyNode* transform = nullptr;
+ for (const auto& client : content_layer_clients_) {
+ if (&client->Layer() == layer.get()) {
+ json_client = client.get();
+ transform = &client->State().Transform();
+ break;
+ }
+ }
+ if (!transform) {
+ for (const auto& pending_layer : pending_layers_) {
+ if (pending_layer.property_tree_state.Transform().CcNodeId(
+ layer->property_tree_sequence_number()) ==
+ layer->transform_tree_index()) {
+ transform = &pending_layer.property_tree_state.Transform();
+ break;
+ }
+ }
+ }
+ DCHECK(transform);
+ layers_as_json.AddLayer(*layer,
+ FloatPoint(layer->offset_to_transform_parent()),
+ *transform, json_client);
+ }
+ } else {
+ for (const auto& paint_chunk : paint_artifact->PaintChunks()) {
+ const auto& display_item =
+ paint_artifact->GetDisplayItemList()[paint_chunk.begin_index];
+ DCHECK(display_item.IsForeignLayer());
+ const auto& foreign_layer_display_item =
+ static_cast<const ForeignLayerDisplayItem&>(display_item);
+ cc::Layer* layer = foreign_layer_display_item.GetLayer();
+ layers_as_json.AddLayer(
+ *layer, foreign_layer_display_item.Offset(),
+ paint_chunk.properties.Transform(),
+ foreign_layer_display_item.GetLayerAsJSONClient());
+ }
}
- auto json = std::make_unique<JSONObject>();
- json->SetArray("layers", std::move(layers_json));
- if (context.transforms_json)
- json->SetArray("transforms", std::move(context.transforms_json));
- return json;
+ return layers_as_json.Finalize();
}
static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk(
@@ -104,11 +123,11 @@ static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk(
if (!display_item.IsForeignLayer())
return nullptr;
- // When a foreign layer's offset_to_transform_parent() changes, we don't call
- // PaintArtifaceCompositor::SetNeedsUpdate() because the update won't change
- // anything but cause unnecessary commit. Though UpdateTouchActionRects()
- // depends on offset_to_transform_parent(), a foreign layer chunk doesn't have
- // hit_test_data.
+ // When a foreign layer's offset_to_transform_parent() changes, we don't
+ // call PaintArtifaceCompositor::SetNeedsUpdate() because the update won't
+ // change anything but cause unnecessary commit. Though
+ // UpdateTouchActionRects() depends on offset_to_transform_parent(), a
+ // foreign layer chunk doesn't have hit_test_data.
DCHECK(!paint_chunk.hit_test_data);
const auto& foreign_layer_display_item =
@@ -139,14 +158,15 @@ const HitTestData::ScrollHitTest*
PaintArtifactCompositor::ScrollHitTestForLayer(
const PaintArtifact& paint_artifact,
const PendingLayer& pending_layer) {
- auto paint_chunks =
- paint_artifact.GetPaintChunkSubset(pending_layer.paint_chunk_indices);
- DCHECK(paint_chunks.size());
- const auto& first_paint_chunk = paint_chunks[0];
- if (first_paint_chunk.size() != 1)
+ if (pending_layer.paint_chunk_indices.size() != 1)
+ return nullptr;
+
+ const auto& paint_chunk =
+ paint_artifact.PaintChunks()[pending_layer.paint_chunk_indices[0]];
+ if (paint_chunk.size() != 1)
return nullptr;
- const HitTestData* hit_test_data = first_paint_chunk.hit_test_data.get();
+ const HitTestData* hit_test_data = paint_chunk.hit_test_data.get();
if (!hit_test_data)
return nullptr;
@@ -190,15 +210,56 @@ PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer(
// |scroll_hit_test->scroll_container_bounds|.
auto bounds = scroll_node.ContainerRect().Size();
// Mark the layer as scrollable.
- // TODO(pdr): When CAP launches this parameter for bounds will not be needed.
+ // TODO(pdr): When CAP launches this parameter for bounds will not be
+ // needed.
scroll_layer->SetScrollable(static_cast<gfx::Size>(bounds));
// Set the layer's bounds equal to the container because the scroll layer
// does not scroll.
scroll_layer->SetBounds(static_cast<gfx::Size>(bounds));
- scroll_layer->set_did_scroll_callback(scroll_callback_);
return scroll_layer;
}
+scoped_refptr<cc::Layer> PaintArtifactCompositor::ScrollbarLayerForPendingLayer(
+ const PaintArtifact& paint_artifact,
+ const PendingLayer& pending_layer) {
+ if (pending_layer.paint_chunk_indices.size() != 1)
+ return nullptr;
+
+ const auto& paint_chunk =
+ paint_artifact.PaintChunks()[pending_layer.paint_chunk_indices[0]];
+ if (paint_chunk.size() != 1)
+ return nullptr;
+
+ const auto& item =
+ paint_artifact.GetDisplayItemList()[paint_chunk.begin_index];
+ if (!item.IsScrollbar())
+ return nullptr;
+
+ const auto& scrollbar_item = static_cast<const ScrollbarDisplayItem&>(item);
+ scoped_refptr<cc::Layer> scrollbar_layer;
+ for (auto& existing_layer : scrollbar_layers_) {
+ if (existing_layer->element_id() == scrollbar_item.ElementId())
+ scrollbar_layer = existing_layer;
+ }
+ if (scrollbar_layer) {
+ cc::Scrollbar* scrollbar = scrollbar_item.GetScrollbar();
+ if (scrollbar->NeedsRepaintPart(cc::THUMB) ||
+ scrollbar->NeedsRepaintPart(cc::TRACK_BUTTONS_TICKMARKS))
+ scrollbar_layer->SetNeedsDisplay();
+ } else {
+ scrollbar_layer = scrollbar_item.CreateLayer();
+ }
+
+ // We should never decomposite scroll translations, so we don't need to adjust
+ // the layer's offset for decomposited transforms.
+ DCHECK_EQ(FloatPoint(), pending_layer.offset_of_decomposited_transforms);
+ const IntRect& rect = scrollbar_item.GetRect();
+ scrollbar_layer->SetOffsetToTransformParent(
+ gfx::Vector2dF(FloatPoint(rect.Location())));
+ scrollbar_layer->SetBounds(gfx::Size(rect.Size()));
+ return scrollbar_layer;
+}
+
std::unique_ptr<ContentLayerClientImpl>
PaintArtifactCompositor::ClientForPaintChunk(const PaintChunk& paint_chunk) {
// TODO(chrishtr): for now, just using a linear walk. In the future we can
@@ -220,7 +281,8 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
scoped_refptr<const PaintArtifact> paint_artifact,
const PendingLayer& pending_layer,
Vector<std::unique_ptr<ContentLayerClientImpl>>& new_content_layer_clients,
- Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers) {
+ Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers,
+ Vector<scoped_refptr<cc::Layer>>& new_scrollbar_layers) {
auto paint_chunks =
paint_artifact->GetPaintChunkSubset(pending_layer.paint_chunk_indices);
DCHECK(paint_chunks.size());
@@ -232,8 +294,6 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
*paint_artifact, first_paint_chunk,
pending_layer.offset_of_decomposited_transforms)) {
DCHECK_EQ(paint_chunks.size(), 1u);
- if (extra_data_for_testing_enabled_)
- extra_data_for_testing_->content_layers.push_back(foreign_layer);
return foreign_layer;
}
@@ -241,11 +301,15 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
if (scoped_refptr<cc::Layer> scroll_layer =
ScrollHitTestLayerForPendingLayer(*paint_artifact, pending_layer)) {
new_scroll_hit_test_layers.push_back(scroll_layer);
- if (extra_data_for_testing_enabled_)
- extra_data_for_testing_->scroll_hit_test_layers.push_back(scroll_layer);
return scroll_layer;
}
+ if (scoped_refptr<cc::Layer> scrollbar_layer =
+ ScrollbarLayerForPendingLayer(*paint_artifact, pending_layer)) {
+ new_scrollbar_layers.push_back(scrollbar_layer);
+ return scrollbar_layer;
+ }
+
// The common case: create or reuse a PictureLayer for painted content.
std::unique_ptr<ContentLayerClientImpl> content_layer_client =
ClientForPaintChunk(first_paint_chunk);
@@ -258,8 +322,6 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
cc_layer->SetIsDrawable(false);
new_content_layer_clients.push_back(std::move(content_layer_client));
- if (extra_data_for_testing_enabled_)
- extra_data_for_testing_->content_layers.push_back(cc_layer);
// Set properties that foreign layers would normally control for themselves
// here to avoid changing foreign layers. This includes things set by
@@ -272,9 +334,6 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
void PaintArtifactCompositor::UpdateTouchActionRects(
cc::Layer* layer,
- // TODO(wangxianzhu): Remove this parameter and use
- // layer->offset_to_transform_parent() after we fully launch
- // BlinkGenPropertyTrees.
const gfx::Vector2dF& layer_offset,
const PropertyTreeState& layer_state,
const PaintChunkSubset& paint_chunks) {
@@ -303,9 +362,6 @@ void PaintArtifactCompositor::UpdateTouchActionRects(
void PaintArtifactCompositor::UpdateNonFastScrollableRegions(
cc::Layer* layer,
- // TODO(wangxianzhu): Remove this parameter and use
- // layer->offset_to_transform_parent() after we fully launch
- // BlinkGenPropertyTrees.
const gfx::Vector2dF& layer_offset,
const PropertyTreeState& layer_state,
const PaintChunkSubset& paint_chunks) {
@@ -316,9 +372,10 @@ void PaintArtifactCompositor::UpdateNonFastScrollableRegions(
if (!hit_test_data || !hit_test_data->scroll_hit_test)
continue;
- // Skip the scroll hit test rect if it is for scrolling this cc::Layer. This
- // is only needed for CompositeAfterPaint because pre-CompositeAfterPaint
- // does not paint scroll hit test data for composited scrollers.
+ // Skip the scroll hit test rect if it is for scrolling this cc::Layer.
+ // This is only needed for CompositeAfterPaint because
+ // pre-CompositeAfterPaint does not paint scroll hit test data for
+ // composited scrollers.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (layer->scrollable()) {
const auto* scroll_offset =
@@ -369,19 +426,19 @@ bool PaintArtifactCompositor::PropertyTreeStateChanged(
PaintArtifactCompositor::PendingLayer::PendingLayer(
const PaintChunk& first_paint_chunk,
wtf_size_t chunk_index,
- bool chunk_requires_own_layer)
+ bool requires_own_layer)
: bounds(first_paint_chunk.bounds),
rect_known_to_be_opaque(
first_paint_chunk.known_to_be_opaque ? bounds : FloatRect()),
property_tree_state(
first_paint_chunk.properties.GetPropertyTreeState().Unalias()),
- requires_own_layer(chunk_requires_own_layer) {
+ compositing_type(requires_own_layer ? kRequiresOwnLayer : kOther) {
paint_chunk_indices.push_back(chunk_index);
}
void PaintArtifactCompositor::PendingLayer::Merge(const PendingLayer& guest) {
- DCHECK(!requires_own_layer && !guest.requires_own_layer);
-
+ DCHECK(compositing_type != kRequiresOwnLayer &&
+ guest.compositing_type != kRequiresOwnLayer);
paint_chunk_indices.AppendVector(guest.paint_chunk_indices);
FloatClipRect guest_bounds_in_home(guest.bounds);
GeometryMapper::LocalToAncestorVisualRect(
@@ -395,11 +452,14 @@ void PaintArtifactCompositor::PendingLayer::Merge(const PendingLayer& guest) {
static bool CanUpcastTo(const PropertyTreeState& guest,
const PropertyTreeState& home);
+
bool PaintArtifactCompositor::PendingLayer::CanMerge(
const PendingLayer& guest,
const PropertyTreeState& guest_state) const {
- if (requires_own_layer || guest.requires_own_layer)
+ if (compositing_type == kRequiresOwnLayer ||
+ guest.compositing_type == kRequiresOwnLayer) {
return false;
+ }
if (&property_tree_state.Effect().Unalias() !=
&guest_state.Effect().Unalias()) {
return false;
@@ -409,7 +469,7 @@ bool PaintArtifactCompositor::PendingLayer::CanMerge(
void PaintArtifactCompositor::PendingLayer::Upcast(
const PropertyTreeState& new_state) {
- DCHECK(!requires_own_layer);
+ DCHECK(compositing_type != kRequiresOwnLayer);
FloatClipRect float_clip_rect(bounds);
GeometryMapper::LocalToAncestorVisualRect(property_tree_state, new_state,
float_clip_rect);
@@ -444,14 +504,15 @@ static bool IsNonCompositingAncestorOf(
// Determines whether drawings based on the 'guest' state can be painted into
// a layer with the 'home' state. A number of criteria need to be met:
// 1. The guest effect must be a descendant of the home effect. However this
-// check is enforced by the layerization recursion. Here we assume the guest
-// has already been upcasted to the same effect.
+// check is enforced by the layerization recursion. Here we assume the
+// guest has already been upcasted to the same effect.
// 2. The guest transform and the home transform have compatible backface
// visibility.
// 3. The guest clip must be a descendant of the home clip.
// 4. The local space of each clip and effect node on the ancestor chain must
// be within compositing boundary of the home transform space.
-// 5. The guest transform space must be within compositing boundary of the home
+// 5. The guest transform space must be within compositing boundary of the
+// home
// transform space.
static bool CanUpcastTo(const PropertyTreeState& guest,
const PropertyTreeState& home) {
@@ -522,7 +583,7 @@ bool PaintArtifactCompositor::DecompositeEffect(
PendingLayer& layer = pending_layers_[layer_index];
if (&layer.property_tree_state.Effect().Unalias() != &unaliased_effect)
return false;
- if (layer.requires_own_layer)
+ if (layer.compositing_type == PendingLayer::kRequiresOwnLayer)
return false;
if (unaliased_effect.HasDirectCompositingReasons())
return false;
@@ -566,9 +627,9 @@ static bool SkipGroupIfEffectivelyInvisible(
const EffectPaintPropertyNode& unaliased_group,
Vector<PaintChunk>::const_iterator& chunk_it) {
// In pre-CompositeAfterPaint, existence of composited layers is decided
- // during compositing update before paint. Each chunk contains a foreign layer
- // corresponding a composited layer. We should not skip any of them to ensure
- // correct composited hit testing and animation.
+ // during compositing update before paint. Each chunk contains a foreign
+ // layer corresponding a composited layer. We should not skip any of them to
+ // ensure correct composited hit testing and animation.
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return false;
@@ -596,6 +657,24 @@ static bool SkipGroupIfEffectivelyInvisible(
return true;
}
+static bool IsCompositedScrollHitTest(const DisplayItem& item) {
+ if (!item.IsScrollHitTest())
+ return false;
+ const auto* scroll_offset_node =
+ static_cast<const ScrollHitTestDisplayItem&>(item).scroll_offset_node();
+ return scroll_offset_node &&
+ scroll_offset_node->HasDirectCompositingReasons();
+}
+
+static bool IsCompositedScrollbar(const DisplayItem& item) {
+ if (!item.IsScrollbar())
+ return false;
+ const auto* scroll_translation =
+ static_cast<const ScrollbarDisplayItem&>(item).ScrollTranslation();
+ return scroll_translation &&
+ scroll_translation->HasDirectCompositingReasons();
+}
+
void PaintArtifactCompositor::LayerizeGroup(
const PaintArtifact& paint_artifact,
const Settings& settings,
@@ -615,17 +694,17 @@ void PaintArtifactCompositor::LayerizeGroup(
// for overlapping.
// d = (sum of) the depth of property trees.
// The analysis as follows:
- // Every paint chunk will be visited by the main loop below for exactly once,
- // except for chunks that enter or exit groups (case B & C below).
- // For normal chunk visit (case A), the only cost is determining squash,
- // which costs O(qd), where d came from "canUpcastTo" and geometry mapping.
+ // Every paint chunk will be visited by the main loop below for exactly
+ // once, except for chunks that enter or exit groups (case B & C below). For
+ // normal chunk visit (case A), the only cost is determining squash, which
+ // costs O(qd), where d came from "canUpcastTo" and geometry mapping.
// Subtotal: O(pqd)
// For group entering and exiting, it could cost O(d) for each group, for
// searching the shallowest subgroup (strictChildOfAlongPath), thus O(d^2)
// in total.
// Also when exiting group, the group may be decomposited and squashed to a
- // previous layer. Again finding the host costs O(qd). Merging would cost O(p)
- // due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd)
+ // previous layer. Again finding the host costs O(qd). Merging would cost
+ // O(p) due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd)
// Assuming p > d, the total complexity would be O(pqd + qd^2 + pd) = O(pqd)
while (chunk_it != paint_artifact.PaintChunks().end()) {
// Look at the effect node of the next chunk. There are 3 possible cases:
@@ -635,15 +714,13 @@ void PaintArtifactCompositor::LayerizeGroup(
const auto& chunk_effect = chunk_it->properties.Effect().Unalias();
if (&chunk_effect == &unaliased_group) {
// Case A: The next chunk belongs to the current group but no subgroup.
- const auto& last_display_item =
+ const auto& first_display_item =
paint_artifact.GetDisplayItemList()[chunk_it->begin_index];
- bool item_for_scrolling = last_display_item.IsScrollHitTest() &&
- !last_display_item.IsResizerScrollHitTest() &&
- !last_display_item.IsPluginScrollHitTest();
- bool requires_own_layer = last_display_item.IsForeignLayer() ||
- // TODO(pdr): This should require a direct
- // compositing reason.
- item_for_scrolling;
+ bool requires_own_layer = first_display_item.IsForeignLayer() ||
+ IsCompositedScrollHitTest(first_display_item) ||
+ IsCompositedScrollbar(first_display_item);
+ DCHECK(!requires_own_layer || chunk_it->size() == 1u);
+
pending_layers_.emplace_back(
*chunk_it, chunk_it - paint_artifact.PaintChunks().begin(),
requires_own_layer);
@@ -662,10 +739,10 @@ void PaintArtifactCompositor::LayerizeGroup(
wtf_size_t first_layer_in_subgroup = pending_layers_.size();
LayerizeGroup(paint_artifact, settings, *unaliased_subgroup, chunk_it);
// The above LayerizeGroup generated new layers in pending_layers_
- // [first_layer_in_subgroup .. pending_layers.size() - 1]. If it generated
- // 2 or more layer that we already know can't be merged together, we
- // should not decomposite and try to merge any of them into the previous
- // layers.
+ // [first_layer_in_subgroup .. pending_layers.size() - 1]. If it
+ // generated 2 or more layer that we already know can't be merged
+ // together, we should not decomposite and try to merge any of them into
+ // the previous layers.
if (first_layer_in_subgroup != pending_layers_.size() - 1)
continue;
if (!DecompositeEffect(unaliased_group, first_layer_in_current_group,
@@ -676,8 +753,8 @@ void PaintArtifactCompositor::LayerizeGroup(
// "decomposited" subgroup or a layer created from a chunk we just
// processed. Now determine whether it could be merged into a previous
// layer.
- const PendingLayer& new_layer = pending_layers_.back();
- DCHECK(!new_layer.requires_own_layer);
+ PendingLayer& new_layer = pending_layers_.back();
+ DCHECK(new_layer.compositing_type != PendingLayer::kRequiresOwnLayer);
DCHECK_EQ(&unaliased_group, &new_layer.property_tree_state.Effect());
// This iterates pending_layers_[first_layer_in_current_group:-1] in
// reverse.
@@ -689,8 +766,10 @@ void PaintArtifactCompositor::LayerizeGroup(
pending_layers_.pop_back();
break;
}
- if (MightOverlap(new_layer, candidate_layer))
+ if (MightOverlap(new_layer, candidate_layer)) {
+ new_layer.compositing_type = PendingLayer::kOverlap;
break;
+ }
}
}
}
@@ -805,6 +884,13 @@ static void UpdateCompositorViewportProperties(
const PaintArtifactCompositor::ViewportProperties& properties,
PropertyTreeManager& property_tree_manager,
cc::LayerTreeHost* layer_tree_host) {
+ // The inner and outer viewports' existence is linked. That is, either they're
+ // both null or they both exist.
+ DCHECK_EQ(static_cast<bool>(properties.outer_scroll_translation),
+ static_cast<bool>(properties.inner_scroll_translation));
+ DCHECK(!properties.outer_clip ||
+ static_cast<bool>(properties.inner_scroll_translation));
+
cc::LayerTreeHost::ViewportPropertyIds ids;
if (properties.overscroll_elasticity_transform) {
ids.overscroll_elasticity_transform =
@@ -827,11 +913,8 @@ static void UpdateCompositorViewportProperties(
ids.outer_scroll = property_tree_manager.EnsureCompositorScrollNode(
*properties.outer_scroll_translation);
}
- } else {
- // Outer viewport properties exist only if inner viewport property exists.
- DCHECK(!properties.outer_clip);
- DCHECK(!properties.outer_scroll_translation);
}
+
layer_tree_host->RegisterViewportPropertyIds(ids);
}
@@ -859,10 +942,10 @@ void PaintArtifactCompositor::DecompositeTransforms(
for (const auto& pending_layer : pending_layers_) {
const auto& property_state = pending_layer.property_tree_state;
- // Lambda to handle marking a transform node false, and walking up all true
- // parents and marking them false as well. This also handles inserting
- // transform_node if it isn't in the map, and keeps track of clips or
- // effects.
+ // Lambda to handle marking a transform node false, and walking up all
+ // true parents and marking them false as well. This also handles
+ // inserting transform_node if it isn't in the map, and keeps track of
+ // clips or effects.
auto mark_not_decompositable =
[&can_be_decomposited](
const TransformPaintPropertyNode* transform_node) {
@@ -954,9 +1037,7 @@ void PaintArtifactCompositor::Update(
TRACE_EVENT0("blink", "PaintArtifactCompositor::Update");
- if (extra_data_for_testing_enabled_)
- extra_data_for_testing_.reset(new ExtraDataForTesting);
-
+ host->property_trees()->scroll_tree.SetScrollCallbacks(scroll_callbacks_);
root_layer_->set_property_tree_sequence_number(
g_s_property_tree_sequence_number);
@@ -972,9 +1053,10 @@ void PaintArtifactCompositor::Update(
Vector<std::unique_ptr<ContentLayerClientImpl>> new_content_layer_clients;
new_content_layer_clients.ReserveCapacity(pending_layers_.size());
Vector<scoped_refptr<cc::Layer>> new_scroll_hit_test_layers;
+ Vector<scoped_refptr<cc::Layer>> new_scrollbar_layers;
- // Maps from cc effect id to blink effects. Containing only the effects having
- // composited layers.
+ // Maps from cc effect id to blink effects. Containing only the effects
+ // having composited layers.
Vector<const EffectPaintPropertyNode*> blink_effects;
for (auto& entry : synthesized_clip_cache_)
@@ -983,14 +1065,15 @@ void PaintArtifactCompositor::Update(
// See if we can de-composite any transforms.
DecompositeTransforms(*paint_artifact);
+ const PendingLayer* previous_pending_layer = nullptr;
for (auto& pending_layer : pending_layers_) {
const auto& property_state = pending_layer.property_tree_state;
const auto& transform = property_state.Transform();
const auto& clip = property_state.Clip();
if (&clip.LocalTransformSpace() == &transform) {
- // Limit layer bounds to hide the areas that will be never visible because
- // of the clip.
+ // Limit layer bounds to hide the areas that will be never visible
+ // because of the clip.
pending_layer.bounds.Intersect(clip.ClipRect().Rect());
} else if (const auto* scroll = transform.ScrollNode()) {
// Limit layer bounds to the scroll range to hide the areas that will
@@ -1001,7 +1084,7 @@ void PaintArtifactCompositor::Update(
scoped_refptr<cc::Layer> layer = CompositedLayerForPendingLayer(
paint_artifact, pending_layer, new_content_layer_clients,
- new_scroll_hit_test_layers);
+ new_scroll_hit_test_layers, new_scrollbar_layers);
// In Pre-CompositeAfterPaint, touch action rects and non-fast scrollable
// regions are updated through ScrollingCoordinator.
@@ -1043,24 +1126,45 @@ void PaintArtifactCompositor::Update(
layer->SetDoubleSided(!backface_hidden);
layer->SetShouldCheckBackfaceVisibility(backface_hidden);
- layer->set_owner_node_id(
- pending_layer.FirstPaintChunk(*paint_artifact).id.client.OwnerNodeId());
- // TODO(wangxianzhu): cc_picture_layer_->set_compositing_reasons(...);
-
- // If the property tree state has changed between the layer and the root, we
- // need to inform the compositor so damage can be calculated.
- // Calling |PropertyTreeStateChanged| for every pending layer is
- // O(|property nodes|^2) and could be optimized by caching the lookup of
- // nodes known to be changed/unchanged.
+ // If the property tree state has changed between the layer and the root,
+ // we need to inform the compositor so damage can be calculated. Calling
+ // |PropertyTreeStateChanged| for every pending layer is O(|property
+ // nodes|^2) and could be optimized by caching the lookup of nodes known
+ // to be changed/unchanged.
if (layer->subtree_property_changed() ||
PropertyTreeStateChanged(property_state)) {
layer->SetSubtreePropertyChanged();
root_layer_->SetNeedsCommit();
}
+
+ if (!layer_debug_info_enabled_) {
+ layer->ClearDebugInfo();
+ } else if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ !layer->debug_info()) {
+ // About the above condition: in pre-CompositeAfterPaint, debug info of
+ // cc::Layers that are created by GraphicsLayers are updated in
+ // LocalFrameView, so here we only update the other layers that don't
+ // have debug info yet.
+ RasterInvalidationTracking* tracking = nullptr;
+ if (new_content_layer_clients.size() &&
+ &new_content_layer_clients.back()->Layer() == layer) {
+ tracking = new_content_layer_clients.back()
+ ->GetRasterInvalidator()
+ .GetTracking();
+ }
+ UpdateLayerDebugInfo(
+ layer.get(), pending_layer.FirstPaintChunk(*paint_artifact).id,
+ GetCompositingReasons(pending_layer, previous_pending_layer,
+ *paint_artifact),
+ tracking);
+ }
+ previous_pending_layer = &pending_layer;
}
+
property_tree_manager.Finalize();
content_layer_clients_.swap(new_content_layer_clients);
scroll_hit_test_layers_.swap(new_scroll_hit_test_layers);
+ scrollbar_layers_.swap(new_scrollbar_layers);
auto pos = std::remove_if(synthesized_clip_cache_.begin(),
synthesized_clip_cache_.end(),
@@ -1068,13 +1172,6 @@ void PaintArtifactCompositor::Update(
synthesized_clip_cache_.begin();
synthesized_clip_cache_.EraseAt(pos, synthesized_clip_cache_.size() - pos);
- if (extra_data_for_testing_enabled_) {
- for (const auto& entry : synthesized_clip_cache_) {
- extra_data_for_testing_->synthesized_clip_layers.push_back(
- entry.synthesized_clip->Layer());
- }
- }
-
// This should be done before UpdateRenderSurfaceForEffects() for which to
// get property tree node ids from the layers.
host->property_trees()->sequence_number = g_s_property_tree_sequence_number;
@@ -1098,7 +1195,8 @@ void PaintArtifactCompositor::Update(
if (VLOG_IS_ON(2)) {
static String s_previous_output;
LayerTreeFlags flags = VLOG_IS_ON(3) ? 0xffffffff : 0;
- String new_output = LayersAsJSON(flags)->ToPrettyJSONString();
+ String new_output =
+ GetLayersAsJSON(flags, paint_artifact.get())->ToPrettyJSONString();
if (new_output != s_previous_output) {
LOG(ERROR) << "PaintArtifactCompositor::Update() done\n"
<< "Composited layers:\n"
@@ -1110,9 +1208,9 @@ void PaintArtifactCompositor::Update(
}
cc::PropertyTrees* PaintArtifactCompositor::GetPropertyTreesForDirectUpdate() {
- // Don't try to retrieve property trees if we need an update. The full update
- // will update all of the nodes, so a direct update doesn't need to do
- // anything.
+ // Don't try to retrieve property trees if we need an update. The full
+ // update will update all of the nodes, so a direct update doesn't need to
+ // do anything.
if (needs_update_)
return nullptr;
@@ -1199,10 +1297,11 @@ static cc::RenderSurfaceReason GetRenderSurfaceCandidateReason(
return cc::RenderSurfaceReason::kNone;
}
-// Every effect is supposed to have render surface enabled for grouping, but we
-// can omit one if the effect is opacity- or blend-mode-only, render surface is
-// not forced, and the effect has only one compositing child. This is both for
-// optimization and not introducing sub-pixel differences in web tests.
+// Every effect is supposed to have render surface enabled for grouping, but
+// we can omit one if the effect is opacity- or blend-mode-only, render
+// surface is not forced, and the effect has only one compositing child. This
+// is both for optimization and not introducing sub-pixel differences in web
+// tests.
// TODO(crbug.com/504464): There is ongoing work in cc to delay render surface
// decision until later phase of the pipeline. Remove premature optimization
// here once the work is ready.
@@ -1210,8 +1309,8 @@ void PaintArtifactCompositor::UpdateRenderSurfaceForEffects(
cc::EffectTree& effect_tree,
const cc::LayerList& layers,
const Vector<const EffectPaintPropertyNode*>& blink_effects) {
- // This vector is indexed by effect node id. The value is the number of layers
- // and sub-render-surfaces controlled by this effect.
+ // This vector is indexed by effect node id. The value is the number of
+ // layers and sub-render-surfaces controlled by this effect.
Vector<int> effect_layer_counts(effect_tree.size());
// Initialize the vector to count directly controlled layers.
for (const auto& layer : layers) {
@@ -1251,6 +1350,97 @@ void PaintArtifactCompositor::UpdateRenderSurfaceForEffects(
}
}
+void PaintArtifactCompositor::SetLayerDebugInfoEnabled(bool enabled) {
+ if (enabled == layer_debug_info_enabled_)
+ return;
+
+ DCHECK(needs_update_);
+ layer_debug_info_enabled_ = enabled;
+
+ if (enabled)
+ root_layer_->EnsureDebugInfo().name = "root";
+ else
+ root_layer_->ClearDebugInfo();
+}
+
+void PaintArtifactCompositor::UpdateLayerDebugInfo(
+ cc::Layer* layer,
+ const PaintChunk::Id& id,
+ CompositingReasons compositing_reasons,
+ RasterInvalidationTracking* raster_invalidation_tracking) {
+ cc::LayerDebugInfo& debug_info = layer->EnsureDebugInfo();
+
+ debug_info.name = id.client.DebugName().Utf8();
+ if (id.type == DisplayItem::kForeignLayerContentsWrapper) {
+ // This is for backward compatibility in pre-CompositeAfterPaint mode.
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ debug_info.name = std::string("ContentsLayer for ") + debug_info.name;
+ }
+
+ debug_info.compositing_reasons =
+ CompositingReason::Descriptions(compositing_reasons);
+ debug_info.owner_node_id = id.client.OwnerNodeId();
+
+ if (RasterInvalidationTracking::IsTracingRasterInvalidations() &&
+ raster_invalidation_tracking) {
+ raster_invalidation_tracking->AddToLayerDebugInfo(debug_info);
+ raster_invalidation_tracking->ClearInvalidations();
+ }
+}
+
+CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
+ const PendingLayer& layer,
+ const PendingLayer* previous_layer,
+ const PaintArtifact& paint_artifact) const {
+ DCHECK(layer_debug_info_enabled_);
+
+ if (layer.compositing_type == PendingLayer::kOverlap)
+ return CompositingReason::kOverlap;
+
+ if (layer.compositing_type == PendingLayer::kRequiresOwnLayer) {
+ const auto& display_item =
+ paint_artifact.GetDisplayItemList()
+ [layer.FirstPaintChunk(paint_artifact).begin_index];
+ switch (display_item.GetType()) {
+ case DisplayItem::kForeignLayerCanvas:
+ return CompositingReason::kCanvas;
+ case DisplayItem::kForeignLayerPlugin:
+ return CompositingReason::kPlugin;
+ case DisplayItem::kForeignLayerVideo:
+ return CompositingReason::kVideo;
+ case DisplayItem::kScrollHitTest:
+ return CompositingReason::kOverflowScrolling;
+ case DisplayItem::kScrollbarHorizontal:
+ return CompositingReason::kLayerForHorizontalScrollbar;
+ case DisplayItem::kScrollbarVertical:
+ return CompositingReason::kLayerForVerticalScrollbar;
+ default:
+ return CompositingReason::kLayerForOther;
+ }
+ }
+
+ CompositingReasons reasons = CompositingReason::kNone;
+ if (!previous_layer || &layer.property_tree_state.Transform() !=
+ &previous_layer->property_tree_state.Transform()) {
+ reasons |= layer.property_tree_state.Transform()
+ .DirectCompositingReasonsForDebugging();
+ }
+ if (!previous_layer || &layer.property_tree_state.Effect() !=
+ &previous_layer->property_tree_state.Effect()) {
+ reasons |= layer.property_tree_state.Effect()
+ .DirectCompositingReasonsForDebugging();
+ }
+ return reasons;
+}
+
+Vector<cc::Layer*> PaintArtifactCompositor::SynthesizedClipLayersForTesting()
+ const {
+ Vector<cc::Layer*> synthesized_clip_layers;
+ for (const auto& entry : synthesized_clip_cache_)
+ synthesized_clip_layers.push_back(entry.synthesized_clip->Layer());
+ return synthesized_clip_layers;
+}
+
void LayerListBuilder::Add(scoped_refptr<cc::Layer> layer) {
DCHECK(list_valid_);
list_.push_back(layer);
@@ -1262,16 +1452,10 @@ cc::LayerList LayerListBuilder::Finalize() {
return std::move(list_);
}
-cc::Layer*
-PaintArtifactCompositor::ExtraDataForTesting::ScrollHitTestWebLayerAt(
- unsigned index) {
- return scroll_hit_test_layers[index].get();
-}
-
#if DCHECK_IS_ON()
void PaintArtifactCompositor::ShowDebugData() {
- LOG(ERROR) << LayersAsJSON(kLayerTreeIncludesDebugInfo |
- kLayerTreeIncludesPaintInvalidations)
+ LOG(ERROR) << GetLayersAsJSON(kLayerTreeIncludesDebugInfo |
+ kLayerTreeIncludesPaintInvalidations)
->ToPrettyJSONString()
.Utf8();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
index 8d2beeb08e5..25abeddc235 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -7,28 +7,23 @@
#include <memory>
-#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/picture_layer.h"
+#include "cc/trees/property_tree.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h"
+#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
-namespace cc {
-struct ElementId;
-class EffectTree;
-class Layer;
-}
-
namespace gfx {
class Vector2dF;
-class ScrollOffset;
}
namespace blink {
@@ -39,6 +34,8 @@ class PaintArtifact;
class SynthesizedClip;
struct PaintChunk;
+using CompositorScrollCallbacks = cc::ScrollCallbacks;
+
class LayerListBuilder {
public:
void Add(scoped_refptr<cc::Layer>);
@@ -114,8 +111,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
public:
PaintArtifactCompositor(
- base::RepeatingCallback<void(const gfx::ScrollOffset&,
- const cc::ElementId&)> scroll_callback);
+ base::WeakPtr<CompositorScrollCallbacks> scroll_callbacks);
~PaintArtifactCompositor();
struct ViewportProperties {
@@ -146,29 +142,15 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// The root layer of the tree managed by this object.
cc::Layer* RootLayer() const { return root_layer_.get(); }
- // Returns extra information recorded during unit tests.
- // While not part of the normal output of this class, this provides a simple
- // way of locating the layers of interest, since there are still a slew of
- // placeholder layers required.
- struct PLATFORM_EXPORT ExtraDataForTesting {
- cc::Layer* ScrollHitTestWebLayerAt(unsigned index);
-
- Vector<scoped_refptr<cc::Layer>> content_layers;
- Vector<scoped_refptr<cc::Layer>> synthesized_clip_layers;
- Vector<scoped_refptr<cc::Layer>> scroll_hit_test_layers;
- };
- void EnableExtraDataForTesting();
- ExtraDataForTesting* GetExtraDataForTesting() const {
- return extra_data_for_testing_.get();
- }
-
void SetTracksRasterInvalidations(bool);
// Called when the local frame view that owns this compositor is
// going to be removed from its frame.
void WillBeRemovedFromFrame();
- std::unique_ptr<JSONObject> LayersAsJSON(LayerTreeFlags) const;
+ std::unique_ptr<JSONObject> GetLayersAsJSON(
+ LayerTreeFlags,
+ const PaintArtifact* = nullptr) const;
#if DCHECK_IS_ON()
void ShowDebugData();
@@ -202,6 +184,17 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// on any of the PropertyTrees constructed by |Update|.
bool HasComposited(CompositorElementId element_id) const;
+ void SetLayerDebugInfoEnabled(bool);
+
+ // TODO(wangxianzhu): Make this private and refactor when removing
+ // pre-CompositeAfterPaint.
+ static void UpdateLayerDebugInfo(cc::Layer* layer,
+ const PaintChunk::Id&,
+ CompositingReasons,
+ RasterInvalidationTracking*);
+
+ Vector<cc::Layer*> SynthesizedClipLayersForTesting() const;
+
private:
// A pending layer is a collection of paint chunks that will end up in
// the same cc::Layer.
@@ -233,7 +226,12 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
Vector<wtf_size_t> paint_chunk_indices;
PropertyTreeState property_tree_state;
FloatPoint offset_of_decomposited_transforms;
- bool requires_own_layer;
+
+ enum {
+ kRequiresOwnLayer,
+ kOverlap,
+ kOther,
+ } compositing_type;
};
void DecompositeTransforms(const PaintArtifact&);
@@ -275,7 +273,8 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const PendingLayer&,
Vector<std::unique_ptr<ContentLayerClientImpl>>&
new_content_layer_clients,
- Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers);
+ Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers,
+ Vector<scoped_refptr<cc::Layer>>& new_scrollbar_layers);
bool PropertyTreeStateChanged(const PropertyTreeState&) const;
@@ -294,6 +293,11 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const PaintArtifact&,
const PendingLayer&);
+ // Finds an existing or creates a new scrollbar layer for the pending layer,
+ // returning nullptr if the layer is not a scrollbar layer.
+ scoped_refptr<cc::Layer> ScrollbarLayerForPendingLayer(const PaintArtifact&,
+ const PendingLayer&);
+
// Finds a client among the current vector of clients that matches the paint
// chunk's id, or otherwise allocates a new one.
std::unique_ptr<ContentLayerClientImpl> ClientForPaintChunk(
@@ -316,12 +320,16 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
cc::PropertyTrees* GetPropertyTreesForDirectUpdate();
- // Provides a callback for notifying blink of composited scrolling.
- base::RepeatingCallback<void(const gfx::ScrollOffset&, const cc::ElementId&)>
- scroll_callback_;
+ CompositingReasons GetCompositingReasons(const PendingLayer& layer,
+ const PendingLayer* previous_layer,
+ const PaintArtifact&) const;
+
+ // For notifying blink of composited scrolling.
+ base::WeakPtr<CompositorScrollCallbacks> scroll_callbacks_;
- bool tracks_raster_invalidations_;
- bool needs_update_;
+ bool tracks_raster_invalidations_ = false;
+ bool needs_update_ = true;
+ bool layer_debug_info_enabled_ = false;
scoped_refptr<cc::Layer> root_layer_;
Vector<std::unique_ptr<ContentLayerClientImpl>> content_layer_clients_;
@@ -333,12 +341,10 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
Vector<SynthesizedClipEntry> synthesized_clip_cache_;
Vector<scoped_refptr<cc::Layer>> scroll_hit_test_layers_;
+ Vector<scoped_refptr<cc::Layer>> scrollbar_layers_;
Vector<PendingLayer, 0> pending_layers_;
- bool extra_data_for_testing_enabled_ = false;
- std::unique_ptr<ExtraDataForTesting> extra_data_for_testing_;
-
friend class StubChromeClientForCAP;
friend class PaintArtifactCompositorTest;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index c98d8f2ec88..e5df1538463 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -65,19 +65,20 @@ void SetTransform(PaintChunk& chunk,
chunk.properties = RefCountedPropertyTreeState(properties);
}
-class FakeScrollClient {
- DISALLOW_NEW();
-
+class MockScrollCallbacks : public CompositorScrollCallbacks {
public:
- FakeScrollClient() : did_scroll_count(0) {}
-
- void DidScroll(const gfx::ScrollOffset& offset, const CompositorElementId&) {
- did_scroll_count++;
- last_scroll_offset = offset;
+ MOCK_METHOD3(DidScroll,
+ void(CompositorElementId,
+ const gfx::ScrollOffset&,
+ const base::Optional<cc::TargetSnapAreaElementIds>&));
+ MOCK_METHOD2(DidChangeScrollbarsHidden, void(CompositorElementId, bool));
+
+ base::WeakPtr<MockScrollCallbacks> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
}
- gfx::ScrollOffset last_scroll_offset;
- unsigned did_scroll_count;
+ private:
+ base::WeakPtrFactory<MockScrollCallbacks> weak_ptr_factory_{this};
};
class PaintArtifactCompositorTest : public testing::Test,
@@ -89,10 +90,8 @@ class PaintArtifactCompositorTest : public testing::Test,
void SetUp() override {
// Delay constructing the compositor until after the feature is set.
- paint_artifact_compositor_ =
- std::make_unique<PaintArtifactCompositor>(WTF::BindRepeating(
- &FakeScrollClient::DidScroll, WTF::Unretained(&scroll_client_)));
- paint_artifact_compositor_->EnableExtraDataForTesting();
+ paint_artifact_compositor_ = std::make_unique<PaintArtifactCompositor>(
+ scroll_callbacks_.GetWeakPtr());
// Uses a LayerTreeHostClient that will make a LayerTreeFrameSink to allow
// the compositor to run and submit frames.
@@ -178,8 +177,6 @@ class PaintArtifactCompositorTest : public testing::Test,
layer->SetScrollable(gfx::Size(rect.Size()));
layer->SetBounds(gfx::Size(rect.Size()));
layer->SetElementId(scroll_node->GetCompositorElementId());
- layer->set_did_scroll_callback(
- paint_artifact_compositor_->scroll_callback_);
artifact.Chunk(scroll_offset, clip, effect)
.ForeignLayer(layer, FloatPoint(rect.Location()));
}
@@ -187,12 +184,10 @@ class PaintArtifactCompositorTest : public testing::Test,
// Returns the |num|th scrollable layer. In CompositeAfterPaint, this will be
// a scroll hit test layer, whereas currently this will be a content layer.
cc::Layer* ScrollableLayerAt(size_t num) {
- for (size_t content_layer_index = 0;
- content_layer_index < ContentLayerCount(); content_layer_index++) {
- auto* content_layer = ContentLayerAt(content_layer_index);
- if (content_layer->scrollable()) {
+ for (auto& layer : RootLayer()->children()) {
+ if (layer->scrollable()) {
if (num == 0)
- return content_layer;
+ return layer.get();
num--;
}
}
@@ -204,27 +199,20 @@ class PaintArtifactCompositorTest : public testing::Test,
// content layers are scrollable and non-scrollable, so this will return the
// |num|th content layer that is not scrollable.
cc::Layer* NonScrollableLayerAt(size_t num) {
- for (size_t content_layer_index = 0;
- content_layer_index < ContentLayerCount(); content_layer_index++) {
- auto* content_layer = ContentLayerAt(content_layer_index);
- if (!content_layer->scrollable()) {
+ for (auto& layer : RootLayer()->children()) {
+ if (!layer->scrollable()) {
if (num == 0)
- return content_layer;
+ return layer.get();
num--;
}
}
return nullptr;
}
- size_t ContentLayerCount() {
- return paint_artifact_compositor_->GetExtraDataForTesting()
- ->content_layers.size();
- }
+ size_t LayerCount() { return RootLayer()->children().size(); }
- cc::Layer* ContentLayerAt(unsigned index) {
- return paint_artifact_compositor_->GetExtraDataForTesting()
- ->content_layers[index]
- .get();
+ cc::Layer* LayerAt(unsigned index) {
+ return RootLayer()->children()[index].get();
}
CompositorElementId ScrollElementId(unsigned id) {
@@ -233,21 +221,20 @@ class PaintArtifactCompositorTest : public testing::Test,
}
size_t SynthesizedClipLayerCount() {
- return paint_artifact_compositor_->GetExtraDataForTesting()
- ->synthesized_clip_layers.size();
+ return paint_artifact_compositor_->SynthesizedClipLayersForTesting().size();
}
cc::Layer* SynthesizedClipLayerAt(unsigned index) {
- return paint_artifact_compositor_->GetExtraDataForTesting()
- ->synthesized_clip_layers[index]
- .get();
+ return paint_artifact_compositor_->SynthesizedClipLayersForTesting()[index];
}
// Return the index of |layer| in the root layer list, or -1 if not found.
int LayerIndex(const cc::Layer* layer) {
- for (size_t i = 0; i < RootLayer()->children().size(); ++i) {
- if (RootLayer()->children()[i] == layer)
+ int i = 0;
+ for (auto& child : RootLayer()->children()) {
+ if (child.get() == layer)
return i;
+ i++;
}
return -1;
}
@@ -276,10 +263,10 @@ class PaintArtifactCompositorTest : public testing::Test,
return PaintArtifactCompositor::MightOverlap(a, b);
}
- FakeScrollClient& ScrollClient() { return scroll_client_; }
+ MockScrollCallbacks& ScrollCallbacks() { return scroll_callbacks_; }
private:
- FakeScrollClient scroll_client_;
+ MockScrollCallbacks scroll_callbacks_;
std::unique_ptr<PaintArtifactCompositor> paint_artifact_compositor_;
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle task_runner_handle_;
@@ -302,8 +289,8 @@ TEST_P(PaintArtifactCompositorTest, OneChunkWithAnOffset) {
artifact.Chunk().RectDrawing(FloatRect(50, -50, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* child = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* child = LayerAt(0);
EXPECT_THAT(
child->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kWhite)));
@@ -326,9 +313,9 @@ TEST_P(PaintArtifactCompositorTest, OneTransform) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
{
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_TRUE(GetTransformNode(layer).transform_changed);
Vector<RectWithColor> rects_with_color;
@@ -344,7 +331,7 @@ TEST_P(PaintArtifactCompositorTest, OneTransform) {
EXPECT_EQ(gfx::RectF(100, 0, 100, 100), mapped_rect);
}
{
- const cc::Layer* layer = ContentLayerAt(1);
+ const cc::Layer* layer = LayerAt(1);
EXPECT_FALSE(GetTransformNode(layer).transform_changed);
EXPECT_THAT(
layer->GetPicture(),
@@ -368,9 +355,9 @@ TEST_P(PaintArtifactCompositorTest, OneTransformWithAlias) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
{
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_TRUE(GetTransformNode(layer).transform_changed);
Vector<RectWithColor> rects_with_color;
@@ -386,7 +373,7 @@ TEST_P(PaintArtifactCompositorTest, OneTransformWithAlias) {
EXPECT_EQ(gfx::RectF(100, 0, 100, 100), mapped_rect);
}
{
- const cc::Layer* layer = ContentLayerAt(1);
+ const cc::Layer* layer = LayerAt(1);
EXPECT_FALSE(GetTransformNode(layer).transform_changed);
EXPECT_THAT(
layer->GetPicture(),
@@ -411,9 +398,9 @@ TEST_P(PaintArtifactCompositorTest, TransformCombining) {
.RectDrawing(FloatRect(0, 0, 300, 200), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
{
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_TRUE(GetTransformNode(layer).transform_changed);
EXPECT_THAT(
layer->GetPicture(),
@@ -423,7 +410,7 @@ TEST_P(PaintArtifactCompositorTest, TransformCombining) {
EXPECT_EQ(gfx::RectF(-10, -10, 600, 400), mapped_rect);
}
{
- const cc::Layer* layer = ContentLayerAt(1);
+ const cc::Layer* layer = LayerAt(1);
EXPECT_TRUE(GetTransformNode(layer).transform_changed);
EXPECT_THAT(
layer->GetPicture(),
@@ -432,8 +419,8 @@ TEST_P(PaintArtifactCompositorTest, TransformCombining) {
layer->ScreenSpaceTransform().TransformRect(&mapped_rect);
EXPECT_EQ(gfx::RectF(0, 0, 600, 400), mapped_rect);
}
- EXPECT_NE(ContentLayerAt(0)->transform_tree_index(),
- ContentLayerAt(1)->transform_tree_index());
+ EXPECT_NE(LayerAt(0)->transform_tree_index(),
+ LayerAt(1)->transform_tree_index());
}
TEST_P(PaintArtifactCompositorTest, BackfaceVisibility) {
@@ -461,14 +448,14 @@ TEST_P(PaintArtifactCompositorTest, BackfaceVisibility) {
.RectDrawing(FloatRect(0, 0, 300, 200), Color::kDarkGray);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
EXPECT_THAT(
- ContentLayerAt(0)->GetPicture(),
+ LayerAt(0)->GetPicture(),
Pointee(DrawsRectangles(Vector<RectWithColor>{
RectWithColor(FloatRect(0, 0, 300, 200), Color::kWhite),
RectWithColor(FloatRect(100, 100, 100, 100), Color::kBlack)})));
EXPECT_THAT(
- ContentLayerAt(1)->GetPicture(),
+ LayerAt(1)->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kDarkGray)));
}
@@ -495,8 +482,8 @@ TEST_P(PaintArtifactCompositorTest, FlattensInheritedTransform) {
.RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(
layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kWhite)));
@@ -550,8 +537,8 @@ TEST_P(PaintArtifactCompositorTest, FlattensInheritedTransformWithAlias) {
.RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(
layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kWhite)));
@@ -610,10 +597,10 @@ TEST_P(PaintArtifactCompositorTest, SortingContextID) {
.RectDrawing(FloatRect(0, 0, 300, 200), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(4u, ContentLayerCount());
+ ASSERT_EQ(4u, LayerCount());
// The white layer is not 3D sorted.
- const cc::Layer* white_layer = ContentLayerAt(0);
+ const cc::Layer* white_layer = LayerAt(0);
EXPECT_THAT(
white_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kWhite)));
@@ -622,7 +609,7 @@ TEST_P(PaintArtifactCompositorTest, SortingContextID) {
EXPECT_EQ(0, white_sorting_context_id);
// The light gray layer is 3D sorted.
- const cc::Layer* light_gray_layer = ContentLayerAt(1);
+ const cc::Layer* light_gray_layer = LayerAt(1);
EXPECT_THAT(
light_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kLightGray)));
@@ -632,7 +619,7 @@ TEST_P(PaintArtifactCompositorTest, SortingContextID) {
// The dark gray layer is 3D sorted with the light gray layer, but has a
// separate transform node.
- const cc::Layer* dark_gray_layer = ContentLayerAt(2);
+ const cc::Layer* dark_gray_layer = LayerAt(2);
EXPECT_THAT(
dark_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kDarkGray)));
@@ -644,7 +631,7 @@ TEST_P(PaintArtifactCompositorTest, SortingContextID) {
// The black layer is 3D sorted, but in a separate context from the previous
// layers.
- const cc::Layer* black_layer = ContentLayerAt(3);
+ const cc::Layer* black_layer = LayerAt(3);
EXPECT_THAT(
black_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kBlack)));
@@ -662,8 +649,8 @@ TEST_P(PaintArtifactCompositorTest, OneClip) {
.RectDrawing(FloatRect(220, 80, 300, 200), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
// The layer is clipped.
EXPECT_EQ(gfx::Size(180, 180), layer->bounds());
EXPECT_EQ(gfx::Vector2dF(220, 100), layer->offset_to_transform_parent());
@@ -687,8 +674,8 @@ TEST_P(PaintArtifactCompositorTest, OneClipWithAlias) {
.RectDrawing(FloatRect(220, 80, 300, 200), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
// The layer is clipped.
EXPECT_EQ(gfx::Size(180, 180), layer->bounds());
EXPECT_EQ(gfx::Vector2dF(220, 100), layer->offset_to_transform_parent());
@@ -727,27 +714,27 @@ TEST_P(PaintArtifactCompositorTest, NestedClips) {
.RectDrawing(FloatRect(300, 350, 100, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(4u, ContentLayerCount());
+ ASSERT_EQ(4u, LayerCount());
- const cc::Layer* white_layer = ContentLayerAt(0);
+ const cc::Layer* white_layer = LayerAt(0);
EXPECT_THAT(
white_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kWhite)));
EXPECT_EQ(Translation(300, 350), white_layer->ScreenSpaceTransform());
- const cc::Layer* light_gray_layer = ContentLayerAt(1);
+ const cc::Layer* light_gray_layer = LayerAt(1);
EXPECT_THAT(
light_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kLightGray)));
EXPECT_EQ(Translation(300, 350), light_gray_layer->ScreenSpaceTransform());
- const cc::Layer* dark_gray_layer = ContentLayerAt(2);
+ const cc::Layer* dark_gray_layer = LayerAt(2);
EXPECT_THAT(
dark_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kDarkGray)));
EXPECT_EQ(Translation(300, 350), dark_gray_layer->ScreenSpaceTransform());
- const cc::Layer* black_layer = ContentLayerAt(3);
+ const cc::Layer* black_layer = LayerAt(3);
EXPECT_THAT(
black_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kBlack)));
@@ -793,27 +780,27 @@ TEST_P(PaintArtifactCompositorTest, NestedClipsWithAlias) {
.RectDrawing(FloatRect(300, 350, 100, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(4u, ContentLayerCount());
+ ASSERT_EQ(4u, LayerCount());
- const cc::Layer* white_layer = ContentLayerAt(0);
+ const cc::Layer* white_layer = LayerAt(0);
EXPECT_THAT(
white_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kWhite)));
EXPECT_EQ(Translation(300, 350), white_layer->ScreenSpaceTransform());
- const cc::Layer* light_gray_layer = ContentLayerAt(1);
+ const cc::Layer* light_gray_layer = LayerAt(1);
EXPECT_THAT(
light_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kLightGray)));
EXPECT_EQ(Translation(300, 350), light_gray_layer->ScreenSpaceTransform());
- const cc::Layer* dark_gray_layer = ContentLayerAt(2);
+ const cc::Layer* dark_gray_layer = LayerAt(2);
EXPECT_THAT(
dark_gray_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kDarkGray)));
EXPECT_EQ(Translation(300, 350), dark_gray_layer->ScreenSpaceTransform());
- const cc::Layer* black_layer = ContentLayerAt(3);
+ const cc::Layer* black_layer = LayerAt(3);
EXPECT_THAT(
black_layer->GetPicture(),
Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kBlack)));
@@ -847,8 +834,8 @@ TEST_P(PaintArtifactCompositorTest, DeeplyNestedClips) {
Update(artifact.Build());
// Check the drawing layer. It's clipped.
- ASSERT_EQ(1u, ContentLayerCount());
- const cc::Layer* drawing_layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* drawing_layer = LayerAt(0);
EXPECT_EQ(gfx::Size(100, 100), drawing_layer->bounds());
EXPECT_EQ(gfx::Vector2dF(50, 0), drawing_layer->offset_to_transform_parent());
EXPECT_THAT(
@@ -867,56 +854,6 @@ TEST_P(PaintArtifactCompositorTest, DeeplyNestedClips) {
}
}
-TEST_P(PaintArtifactCompositorTest, SiblingClipsWithAlias) {
- auto real_common_clip =
- CreateClip(c0(), t0(), FloatRoundedRect(0, 0, 800, 600));
- auto common_clip = ClipPaintPropertyNode::CreateAlias(*real_common_clip);
- auto real_clip1 =
- CreateClip(*common_clip, t0(), FloatRoundedRect(0, 0, 400, 600));
- auto clip1 = ClipPaintPropertyNode::CreateAlias(*real_clip1);
- auto real_clip2 =
- CreateClip(*common_clip, t0(), FloatRoundedRect(400, 0, 400, 600));
- auto clip2 = ClipPaintPropertyNode::CreateAlias(*real_clip2);
-
- TestPaintArtifact artifact;
- artifact.Chunk(t0(), *clip1, e0())
- .RectDrawing(FloatRect(0, 0, 640, 480), Color::kWhite);
- artifact.Chunk(t0(), *clip2, e0())
- .RectDrawing(FloatRect(0, 0, 640, 480), Color::kBlack);
- Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
-
- const cc::Layer* white_layer = ContentLayerAt(0);
- EXPECT_THAT(
- white_layer->GetPicture(),
- Pointee(DrawsRectangle(FloatRect(0, 0, 640, 480), Color::kWhite)));
- EXPECT_EQ(gfx::Transform(), white_layer->ScreenSpaceTransform());
- const cc::ClipNode* white_clip =
- GetPropertyTrees().clip_tree.Node(white_layer->clip_tree_index());
- EXPECT_EQ(cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP, white_clip->clip_type);
- ASSERT_EQ(gfx::RectF(0, 0, 400, 600), white_clip->clip);
-
- const cc::Layer* black_layer = ContentLayerAt(1);
- // The layer is clipped.
- EXPECT_EQ(gfx::Size(240, 480), black_layer->bounds());
- EXPECT_EQ(gfx::Vector2dF(400, 0), black_layer->offset_to_transform_parent());
- EXPECT_THAT(
- black_layer->GetPicture(),
- Pointee(DrawsRectangle(FloatRect(0, 0, 240, 480), Color::kBlack)));
- EXPECT_EQ(Translation(400, 0), black_layer->ScreenSpaceTransform());
- const cc::ClipNode* black_clip =
- GetPropertyTrees().clip_tree.Node(black_layer->clip_tree_index());
- EXPECT_EQ(cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP, black_clip->clip_type);
- ASSERT_EQ(gfx::RectF(400, 0, 400, 600), black_clip->clip);
-
- EXPECT_EQ(white_clip->parent_id, black_clip->parent_id);
- const cc::ClipNode* common_clip_node =
- GetPropertyTrees().clip_tree.Node(white_clip->parent_id);
- EXPECT_EQ(cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP,
- common_clip_node->clip_type);
- ASSERT_EQ(gfx::RectF(0, 0, 800, 600), common_clip_node->clip);
-}
-
TEST_P(PaintArtifactCompositorTest, ForeignLayerPassesThrough) {
scoped_refptr<cc::Layer> layer = cc::Layer::Create();
layer->SetIsDrawable(true);
@@ -931,8 +868,8 @@ TEST_P(PaintArtifactCompositorTest, ForeignLayerPassesThrough) {
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(3u, ContentLayerCount());
- EXPECT_EQ(layer, ContentLayerAt(1));
+ ASSERT_EQ(3u, LayerCount());
+ EXPECT_EQ(layer, LayerAt(1));
EXPECT_EQ(gfx::Size(400, 300), layer->bounds());
EXPECT_EQ(Translation(50, 60), layer->ScreenSpaceTransform());
}
@@ -962,7 +899,7 @@ TEST_P(PaintArtifactCompositorTest, EffectTreeConversionWithAlias) {
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
const cc::EffectTree& effect_tree = GetPropertyTrees().effect_tree;
// Node #0 reserved for null; #1 for root render surface; #2 for e0(),
@@ -987,9 +924,9 @@ TEST_P(PaintArtifactCompositorTest, EffectTreeConversionWithAlias) {
EXPECT_EQ(converted_root_effect.id, converted_effect3.parent_id);
EXPECT_FLOAT_EQ(0.2, converted_effect3.opacity);
- EXPECT_EQ(converted_effect2.id, ContentLayerAt(0)->effect_tree_index());
- EXPECT_EQ(converted_effect1.id, ContentLayerAt(1)->effect_tree_index());
- EXPECT_EQ(converted_effect3.id, ContentLayerAt(2)->effect_tree_index());
+ EXPECT_EQ(converted_effect2.id, LayerAt(0)->effect_tree_index());
+ EXPECT_EQ(converted_effect1.id, LayerAt(1)->effect_tree_index());
+ EXPECT_EQ(converted_effect3.id, LayerAt(2)->effect_tree_index());
}
// Returns a ScrollPaintPropertyNode::State with some arbitrary values.
@@ -1088,10 +1025,16 @@ TEST_P(PaintArtifactCompositorTest, OneScrollNode) {
EXPECT_EQ(gfx::Vector2dF(3, 5), scroll_layer->offset_to_transform_parent());
EXPECT_EQ(scroll_layer->scroll_tree_index(), scroll_node.id);
- EXPECT_EQ(0u, ScrollClient().did_scroll_count);
- scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(1, 2));
- EXPECT_EQ(1u, ScrollClient().did_scroll_count);
- EXPECT_EQ(gfx::ScrollOffset(1, 2), ScrollClient().last_scroll_offset);
+ base::Optional<cc::TargetSnapAreaElementIds> targets;
+ EXPECT_CALL(ScrollCallbacks(), DidScroll(scroll_node.element_id,
+ gfx::ScrollOffset(1, 2), targets));
+ GetPropertyTrees().scroll_tree.NotifyDidScroll(
+ scroll_node.element_id, gfx::ScrollOffset(1, 2), targets);
+
+ EXPECT_CALL(ScrollCallbacks(),
+ DidChangeScrollbarsHidden(scroll_node.element_id, true));
+ GetPropertyTrees().scroll_tree.NotifyDidChangeScrollbarsHidden(
+ scroll_node.element_id, true);
}
TEST_P(PaintArtifactCompositorTest, TransformUnderScrollNode) {
@@ -1115,8 +1058,8 @@ TEST_P(PaintArtifactCompositorTest, TransformUnderScrollNode) {
const cc::ScrollNode& scroll_node = *scroll_tree.Node(2);
// Both layers should refer to the same scroll tree node.
- const auto* layer0 = ContentLayerAt(0);
- const auto* layer1 = ContentLayerAt(1);
+ const auto* layer0 = LayerAt(0);
+ const auto* layer1 = LayerAt(1);
EXPECT_EQ(scroll_node.id, layer0->scroll_tree_index());
EXPECT_EQ(scroll_node.id, layer1->scroll_tree_index());
@@ -1345,7 +1288,7 @@ TEST_P(PaintArtifactCompositorTest, MergeSimpleChunks) {
ASSERT_EQ(2u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1353,7 +1296,7 @@ TEST_P(PaintArtifactCompositorTest, MergeSimpleChunks) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1372,7 +1315,7 @@ TEST_P(PaintArtifactCompositorTest, MergeClip) {
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1383,7 +1326,7 @@ TEST_P(PaintArtifactCompositorTest, MergeClip) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 300, 400), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1404,7 +1347,7 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransform) {
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1415,7 +1358,7 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransform) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1439,7 +1382,7 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransformDirectAncestor) {
auto artifact = test_artifact.Build();
ASSERT_EQ(2u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1448,7 +1391,7 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransformDirectAncestor) {
rects_with_color.push_back(
RectWithColor(FloatRect(50, 50, 100, 100), Color::kBlack));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1467,7 +1410,7 @@ TEST_P(PaintArtifactCompositorTest, MergeTransformOrigin) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1478,7 +1421,7 @@ TEST_P(PaintArtifactCompositorTest, MergeTransformOrigin) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 42, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1497,7 +1440,7 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacity) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1509,7 +1452,7 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacity) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1529,7 +1472,7 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacityWithAlias) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1541,7 +1484,7 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacityWithAlias) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1570,7 +1513,7 @@ TEST_P(PaintArtifactCompositorTest, MergeNestedWithAlias) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1582,7 +1525,7 @@ TEST_P(PaintArtifactCompositorTest, MergeNestedWithAlias) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1609,7 +1552,7 @@ TEST_P(PaintArtifactCompositorTest, ClipPushedUp) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1621,7 +1564,7 @@ TEST_P(PaintArtifactCompositorTest, ClipPushedUp) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1655,7 +1598,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectPushedUp) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1666,7 +1609,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectPushedUp) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1699,7 +1642,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectAndClipPushedUp) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1712,7 +1655,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectAndClipPushedUp) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1734,7 +1677,7 @@ TEST_P(PaintArtifactCompositorTest, ClipAndEffectNoTransform) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1745,7 +1688,7 @@ TEST_P(PaintArtifactCompositorTest, ClipAndEffectNoTransform) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1766,7 +1709,7 @@ TEST_P(PaintArtifactCompositorTest, TwoClips) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1777,7 +1720,7 @@ TEST_P(PaintArtifactCompositorTest, TwoClips) {
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1800,7 +1743,7 @@ TEST_P(PaintArtifactCompositorTest, TwoTransformsClipBetween) {
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
Update(artifact);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
{
Vector<RectWithColor> rects_with_color;
rects_with_color.push_back(
@@ -1809,7 +1752,7 @@ TEST_P(PaintArtifactCompositorTest, TwoTransformsClipBetween) {
RectWithColor(FloatRect(40, 50, 10, 10), Color(Color::kBlack)));
rects_with_color.push_back(
RectWithColor(FloatRect(0, 0, 200, 300), Color::kGray));
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(layer->GetPicture(),
Pointee(DrawsRectangles(rects_with_color)));
}
@@ -1832,7 +1775,7 @@ TEST_P(PaintArtifactCompositorTest, OverlapTransform) {
// The third paint chunk overlaps the second but can't merge due to
// incompatible transform. The second paint chunk can't merge into the first
// due to a direct compositing reason.
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, MightOverlap) {
@@ -2024,9 +1967,9 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleLuminanceMask) {
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_THAT(*layer->GetPicture(),
DrawsRectangles(Vector<RectWithColor>{
RectWithColor(FloatRect(0, 0, 200, 200), Color::kGray),
@@ -2060,9 +2003,9 @@ TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskTwoChildren) {
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* masking_layer = ContentLayerAt(2);
+ const cc::Layer* masking_layer = LayerAt(2);
const cc::EffectNode* masking_group =
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
@@ -2089,9 +2032,9 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) {
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
const cc::EffectNode* group =
GetPropertyTrees().effect_tree.Node(layer->effect_tree_index());
EXPECT_FALSE(group->HasRenderSurface());
@@ -2115,9 +2058,9 @@ TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) {
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
- const cc::Layer* masking_layer = ContentLayerAt(1);
+ const cc::Layer* masking_layer = LayerAt(1);
const cc::EffectNode* masking_group =
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
@@ -2149,9 +2092,9 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* masking_layer = ContentLayerAt(2);
+ const cc::Layer* masking_layer = LayerAt(2);
const cc::EffectNode* masking_group =
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
@@ -2185,9 +2128,9 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), *masking)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* masking_layer = ContentLayerAt(2);
+ const cc::Layer* masking_layer = LayerAt(2);
const cc::EffectNode* masking_group =
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
@@ -2250,9 +2193,9 @@ TEST_P(PaintArtifactCompositorTest, DecompositeClip) {
artifact.Chunk(t0(), *clip, e0())
.RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 50.f), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(125, 125), layer->bounds());
}
@@ -2270,9 +2213,9 @@ TEST_P(PaintArtifactCompositorTest, DecompositeEffect) {
.RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(25.f, 25.f), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(150, 150), layer->bounds());
EXPECT_EQ(1, layer->effect_tree_index());
@@ -2288,14 +2231,14 @@ TEST_P(PaintArtifactCompositorTest, DirectlyCompositedEffect) {
.RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* layer1 = ContentLayerAt(0);
+ const cc::Layer* layer1 = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 25.f), layer1->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer1->bounds());
EXPECT_EQ(1, layer1->effect_tree_index());
- const cc::Layer* layer2 = ContentLayerAt(1);
+ const cc::Layer* layer2 = LayerAt(1);
EXPECT_EQ(gfx::Vector2dF(25.f, 75.f), layer2->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer2->bounds());
const cc::EffectNode* effect_node =
@@ -2303,7 +2246,7 @@ TEST_P(PaintArtifactCompositorTest, DirectlyCompositedEffect) {
EXPECT_EQ(1, effect_node->parent_id);
EXPECT_EQ(0.5f, effect_node->opacity);
- const cc::Layer* layer3 = ContentLayerAt(2);
+ const cc::Layer* layer3 = LayerAt(2);
EXPECT_EQ(gfx::Vector2dF(75.f, 75.f), layer3->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer3->bounds());
EXPECT_EQ(1, layer3->effect_tree_index());
@@ -2323,14 +2266,14 @@ TEST_P(PaintArtifactCompositorTest, DecompositeDeepEffect) {
.RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* layer1 = ContentLayerAt(0);
+ const cc::Layer* layer1 = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 25.f), layer1->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer1->bounds());
EXPECT_EQ(1, layer1->effect_tree_index());
- const cc::Layer* layer2 = ContentLayerAt(1);
+ const cc::Layer* layer2 = LayerAt(1);
EXPECT_EQ(gfx::Vector2dF(25.f, 75.f), layer2->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer2->bounds());
const cc::EffectNode* effect_node2 =
@@ -2341,7 +2284,7 @@ TEST_P(PaintArtifactCompositorTest, DecompositeDeepEffect) {
EXPECT_EQ(1, effect_node1->parent_id);
EXPECT_EQ(0.1f, effect_node1->opacity);
- const cc::Layer* layer3 = ContentLayerAt(2);
+ const cc::Layer* layer3 = LayerAt(2);
EXPECT_EQ(gfx::Vector2dF(75.f, 75.f), layer3->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer3->bounds());
EXPECT_EQ(1, layer3->effect_tree_index());
@@ -2361,14 +2304,14 @@ TEST_P(PaintArtifactCompositorTest, IndirectlyCompositedEffect) {
artifact.Chunk(*transform, c0(), *effect)
.RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
- const cc::Layer* layer1 = ContentLayerAt(0);
+ const cc::Layer* layer1 = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 25.f), layer1->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer1->bounds());
EXPECT_EQ(1, layer1->effect_tree_index());
- const cc::Layer* layer2 = ContentLayerAt(1);
+ const cc::Layer* layer2 = LayerAt(1);
EXPECT_EQ(gfx::Vector2dF(25.f, 75.f), layer2->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer2->bounds());
const cc::EffectNode* effect_node =
@@ -2376,7 +2319,7 @@ TEST_P(PaintArtifactCompositorTest, IndirectlyCompositedEffect) {
EXPECT_EQ(1, effect_node->parent_id);
EXPECT_EQ(0.5f, effect_node->opacity);
- const cc::Layer* layer3 = ContentLayerAt(2);
+ const cc::Layer* layer3 = LayerAt(2);
EXPECT_EQ(gfx::Vector2dF(75.f, 75.f), layer3->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(100, 100), layer3->bounds());
EXPECT_EQ(effect_node->id, layer3->effect_tree_index());
@@ -2406,14 +2349,14 @@ TEST_P(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) {
.RectDrawing(FloatRect(100, 0, 50, 50), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(4u, ContentLayerCount());
+ ASSERT_EQ(4u, LayerCount());
- const cc::Layer* layer1 = ContentLayerAt(0);
+ const cc::Layer* layer1 = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(0.f, 0.f), layer1->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(50, 50), layer1->bounds());
EXPECT_EQ(1, layer1->effect_tree_index());
- const cc::Layer* layer2 = ContentLayerAt(1);
+ const cc::Layer* layer2 = LayerAt(1);
EXPECT_EQ(gfx::Vector2dF(100.f, 0.f), layer2->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(50, 50), layer2->bounds());
const cc::EffectNode* effect_node =
@@ -2421,12 +2364,12 @@ TEST_P(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) {
EXPECT_EQ(1, effect_node->parent_id);
EXPECT_EQ(0.1f, effect_node->opacity);
- const cc::Layer* layer3 = ContentLayerAt(2);
+ const cc::Layer* layer3 = LayerAt(2);
EXPECT_EQ(gfx::Vector2dF(200.f, 0.f), layer3->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(50, 50), layer3->bounds());
EXPECT_EQ(effect_node->id, layer3->effect_tree_index());
- const cc::Layer* layer4 = ContentLayerAt(3);
+ const cc::Layer* layer4 = LayerAt(3);
EXPECT_EQ(gfx::Vector2dF(100.f, 0.f), layer4->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(150, 150), layer4->bounds());
EXPECT_EQ(1, layer4->effect_tree_index());
@@ -2435,97 +2378,97 @@ TEST_P(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) {
TEST_P(PaintArtifactCompositorTest, SkipChunkWithOpacityZero) {
UpdateWithArtifactWithOpacity(0, false, false);
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(0u, ContentLayerCount());
+ EXPECT_EQ(0u, LayerCount());
else
- EXPECT_EQ(1u, ContentLayerCount());
+ EXPECT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
SkipChunkWithOpacityZeroWithPrecedingChunk) {
UpdateWithArtifactWithOpacity(0, true, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, SkipChunkWithOpacityZeroSubsequentChunk) {
UpdateWithArtifactWithOpacity(0, false, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
SkipChunkWithOpacityZeroWithPrecedingAndSubsequentChunk) {
UpdateWithArtifactWithOpacity(0, true, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, SkipChunkWithTinyOpacity) {
UpdateWithArtifactWithOpacity(0.0003f, false, false);
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(0u, ContentLayerCount());
+ EXPECT_EQ(0u, LayerCount());
else
- EXPECT_EQ(1u, ContentLayerCount());
+ EXPECT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
SkipChunkWithTinyOpacityWithPrecedingChunk) {
UpdateWithArtifactWithOpacity(0.0003f, true, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, SkipChunkWithTinyOpacitySubsequentChunk) {
UpdateWithArtifactWithOpacity(0.0003f, false, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
SkipChunkWithTinyOpacityWithPrecedingAndSubsequentChunk) {
UpdateWithArtifactWithOpacity(0.0003f, true, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, DontSkipChunkWithMinimumOpacity) {
UpdateWithArtifactWithOpacity(0.0004f, false, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithMinimumOpacityWithPrecedingChunk) {
UpdateWithArtifactWithOpacity(0.0004f, true, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithMinimumOpacitySubsequentChunk) {
UpdateWithArtifactWithOpacity(0.0004f, false, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithMinimumOpacityWithPrecedingAndSubsequentChunk) {
UpdateWithArtifactWithOpacity(0.0004f, true, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, DontSkipChunkWithAboveMinimumOpacity) {
UpdateWithArtifactWithOpacity(0.3f, false, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithAboveMinimumOpacityWithPrecedingChunk) {
UpdateWithArtifactWithOpacity(0.3f, true, false);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithAboveMinimumOpacitySubsequentChunk) {
UpdateWithArtifactWithOpacity(0.3f, false, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
DontSkipChunkWithAboveMinimumOpacityWithPrecedingAndSubsequentChunk) {
UpdateWithArtifactWithOpacity(0.3f, true, true);
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
@@ -2535,7 +2478,7 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), *effect)
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
@@ -2549,9 +2492,9 @@ TEST_P(PaintArtifactCompositorTest,
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(0u, ContentLayerCount());
+ EXPECT_EQ(0u, LayerCount());
else
- EXPECT_EQ(1u, ContentLayerCount());
+ EXPECT_EQ(1u, LayerCount());
}
TEST_P(
@@ -2564,7 +2507,7 @@ TEST_P(
artifact.Chunk(t0(), c0(), *visible_effect)
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest,
@@ -2577,9 +2520,9 @@ TEST_P(PaintArtifactCompositorTest,
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(0u, ContentLayerCount());
+ EXPECT_EQ(0u, LayerCount());
else
- EXPECT_EQ(1u, ContentLayerCount());
+ EXPECT_EQ(1u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) {
@@ -2592,7 +2535,7 @@ TEST_P(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) {
.RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
ASSERT_TRUE(GetLayerTreeHost().IsElementInPropertyTrees(
element_id, cc::ElementListType::ACTIVE));
}
@@ -2602,7 +2545,7 @@ TEST_P(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) {
ASSERT_TRUE(GetLayerTreeHost().IsElementInPropertyTrees(
element_id, cc::ElementListType::ACTIVE));
Update(artifact.Build());
- ASSERT_EQ(0u, ContentLayerCount());
+ ASSERT_EQ(0u, LayerCount());
ASSERT_FALSE(GetLayerTreeHost().IsElementInPropertyTrees(
element_id, cc::ElementListType::ACTIVE));
}
@@ -2627,18 +2570,16 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipSimple) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(1u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
// There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
+ const cc::Layer* content0 = LayerAt(0);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2661,17 +2602,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipSimple) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2720,17 +2659,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRotatedNotSupported) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2775,18 +2712,16 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClip90DegRotationSupported) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(1u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
// There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
+ const cc::Layer* content0 = LayerAt(0);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2809,17 +2744,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClip90DegRotationSupported) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2862,17 +2795,15 @@ TEST_P(PaintArtifactCompositorTest,
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2913,12 +2844,12 @@ TEST_P(PaintArtifactCompositorTest,
Update(artifact.Build());
#if defined(OS_MACOSX)
- ASSERT_EQ(2u, RootLayer()->children().size());
+ ASSERT_EQ(2u, LayerCount());
#else
if (RuntimeEnabledFeatures::FastBorderRadiusEnabled())
- ASSERT_EQ(1u, RootLayer()->children().size());
+ ASSERT_EQ(1u, LayerCount());
else
- ASSERT_EQ(2u, RootLayer()->children().size());
+ ASSERT_EQ(2u, LayerCount());
#endif
}
@@ -2961,18 +2892,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipNested) {
// mask_isolation_0 will not because it is a leaf synthetic rounded clip
// in the render surface created by the filter.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
// There is still a "synthesized layer" but it's null.
ASSERT_EQ(3u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
EXPECT_FALSE(SynthesizedClipLayerAt(1));
EXPECT_FALSE(SynthesizedClipLayerAt(2));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- EXPECT_EQ(ContentLayerAt(0), content0);
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- EXPECT_EQ(ContentLayerAt(1), content1);
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int c1_id = 2;
@@ -3045,18 +2973,16 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipIsNotDrawable) {
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer, no clip mask (because layer doesn't draw content).
- ASSERT_EQ(1u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
// There is a synthesized clip", but it has no layer backing.
ASSERT_EQ(nullptr, SynthesizedClipLayerAt(0));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
+ const cc::Layer* content0 = LayerAt(0);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3082,7 +3008,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
.RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
Update(artifact.Build());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
+ const cc::Layer* content0 = LayerAt(0);
uint64_t old_stable_id = GetPropertyTrees()
.effect_tree.Node(content0->effect_tree_index())
@@ -3092,7 +3018,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
repeated_artifact.Chunk(t0(), *c1, e0())
.RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
Update(repeated_artifact.Build());
- const cc::Layer* content1 = RootLayer()->children()[0].get();
+ const cc::Layer* content1 = LayerAt(0);
// Check that stable ids are reused across updates.
EXPECT_EQ(GetPropertyTrees()
@@ -3104,7 +3030,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
changed_artifact.Chunk(t0(), *c2, e0())
.RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
Update(changed_artifact.Build());
- const cc::Layer* content2 = RootLayer()->children()[0].get();
+ const cc::Layer* content2 = LayerAt(0);
// The new artifact changed the clip node to c2, so the synthetic clip should
// not be reused.
@@ -3133,17 +3059,15 @@ TEST_P(PaintArtifactCompositorTest,
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer, one clip mask.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3194,20 +3118,18 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
// [ mask_isolation_0 ]
// [ e0 ]
// Two content layers, one clip mask.
- ASSERT_EQ(2u, RootLayer()->children().size());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
// There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
constexpr int t0_id = 1;
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3219,7 +3141,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_EQ(ContentLayerAt(1), content1);
int t1_id = content1->transform_tree_index();
const cc::TransformNode& cc_t1 =
*GetPropertyTrees().transform_tree.Node(t1_id);
@@ -3240,19 +3161,17 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
// [ mask_isolation_0 ]
// [ e0 ]
// Two content layers, one clip mask.
- ASSERT_EQ(3u, RootLayer()->children().size());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[2].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* clip_mask0 = LayerAt(2);
constexpr int t0_id = 1;
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3264,7 +3183,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_EQ(ContentLayerAt(1), content1);
int t1_id = content1->transform_tree_index();
const cc::TransformNode& cc_t1 =
*GetPropertyTrees().transform_tree.Node(t1_id);
@@ -3311,22 +3229,20 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
// [ mask_isolation_0 ] l2 [ mask_isolation_1 ]
// [ e0 ]
// Three content layers.
- ASSERT_EQ(3u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
// There are still "synthesized layers" but they're null.
ASSERT_EQ(2u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
EXPECT_FALSE(SynthesizedClipLayerAt(1));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* content2 = RootLayer()->children()[2].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
constexpr int t0_id = 1;
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3342,7 +3258,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
mask_isolation_0.rounded_corner_bounds);
EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- EXPECT_EQ(ContentLayerAt(1), content1);
int t1_id = content1->transform_tree_index();
const cc::TransformNode& cc_t1 =
*GetPropertyTrees().transform_tree.Node(t1_id);
@@ -3350,7 +3265,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
EXPECT_EQ(c0_id, content1->clip_tree_index());
EXPECT_EQ(e0_id, content1->effect_tree_index());
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(t0_id, content2->transform_tree_index());
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_1_id = content2->effect_tree_index();
@@ -3372,21 +3286,19 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
// [ mask_isolation_0 ] l2 [ mask_isolation_1 ]
// [ e0 ]
// Three content layers, two clip mask.
- ASSERT_EQ(5u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(5u, LayerCount());
ASSERT_EQ(2u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
- const cc::Layer* content1 = RootLayer()->children()[2].get();
- const cc::Layer* content2 = RootLayer()->children()[3].get();
- const cc::Layer* clip_mask1 = RootLayer()->children()[4].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
+ const cc::Layer* content1 = LayerAt(2);
+ const cc::Layer* content2 = LayerAt(3);
+ const cc::Layer* clip_mask1 = LayerAt(4);
constexpr int t0_id = 1;
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3409,7 +3321,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
- EXPECT_EQ(ContentLayerAt(1), content1);
int t1_id = content1->transform_tree_index();
const cc::TransformNode& cc_t1 =
*GetPropertyTrees().transform_tree.Node(t1_id);
@@ -3417,7 +3328,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
EXPECT_EQ(c0_id, content1->clip_tree_index());
EXPECT_EQ(e0_id, content1->effect_tree_index());
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(t0_id, content2->transform_tree_index());
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_1_id = content2->effect_tree_index();
@@ -3465,20 +3375,18 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
// [ mask_isolation_0 ]
// [ e0 ]
// Three content layers.
- ASSERT_EQ(3u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
// There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* content2 = RootLayer()->children()[2].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3490,13 +3398,11 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
ASSERT_EQ(mask_isolation_0_id, cc_e1.parent_id);
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
EXPECT_EQ(mask_isolation_0_id, content2->effect_tree_index());
@@ -3514,19 +3420,17 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
// [ mask_isolation_0 ]
// [ e0 ]
// Three content layers, one clip mask.
- ASSERT_EQ(4u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(4u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* content2 = RootLayer()->children()[2].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[3].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
+ const cc::Layer* clip_mask0 = LayerAt(3);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3538,13 +3442,11 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
EXPECT_TRUE(mask_isolation_0.HasRenderSurface());
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
ASSERT_EQ(mask_isolation_0_id, cc_e1.parent_id);
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
EXPECT_EQ(mask_isolation_0_id, content2->effect_tree_index());
@@ -3589,22 +3491,20 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
// [ mask_isolation_0 ][ e1 ][ mask_isolation_2 ]
// [ e0 ]
// Three content layers.
- ASSERT_EQ(3u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
// There are still "synthesized layers" but they're null.
ASSERT_EQ(3u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
EXPECT_FALSE(SynthesizedClipLayerAt(1));
EXPECT_FALSE(SynthesizedClipLayerAt(2));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* content2 = RootLayer()->children()[2].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3619,7 +3519,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
mask_isolation_0.rounded_corner_bounds);
EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int mask_isolation_1_id = content1->effect_tree_index();
const cc::EffectNode& mask_isolation_1 =
@@ -3634,7 +3533,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
mask_isolation_1.rounded_corner_bounds);
EXPECT_FALSE(mask_isolation_1.HasRenderSurface());
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
const cc::EffectNode& mask_isolation_2 =
@@ -3657,21 +3555,19 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
// [ mask_isolation_0 ][ e1 ][ mask_isolation_2 ]
// [ e0 ]
// Three content layers, three clip mask.
- ASSERT_EQ(6u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(6u, LayerCount());
ASSERT_EQ(3u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
- const cc::Layer* content1 = RootLayer()->children()[2].get();
- const cc::Layer* clip_mask1 = RootLayer()->children()[3].get();
- const cc::Layer* content2 = RootLayer()->children()[4].get();
- const cc::Layer* clip_mask2 = RootLayer()->children()[5].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
+ const cc::Layer* content1 = LayerAt(2);
+ const cc::Layer* clip_mask1 = LayerAt(3);
+ const cc::Layer* content2 = LayerAt(4);
+ const cc::Layer* clip_mask2 = LayerAt(5);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3691,7 +3587,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int mask_isolation_1_id = content1->effect_tree_index();
const cc::EffectNode& mask_isolation_1 =
@@ -3711,7 +3606,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
ASSERT_EQ(mask_isolation_1_id, mask_effect_1.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_1.blend_mode);
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
const cc::EffectNode& mask_isolation_2 =
@@ -3763,22 +3657,20 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
// [ mask_isolation_0 ][ mask_isolation_1 ][ mask_isolation_2 ]
// [ e0 ]
// Three content layers.
- ASSERT_EQ(3u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
// There are still "synthesized layers" but they're null.
ASSERT_EQ(3u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
EXPECT_FALSE(SynthesizedClipLayerAt(1));
EXPECT_FALSE(SynthesizedClipLayerAt(2));
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* content1 = RootLayer()->children()[1].get();
- const cc::Layer* content2 = RootLayer()->children()[2].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3792,7 +3684,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
mask_isolation_0.rounded_corner_bounds);
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
@@ -3807,7 +3698,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
mask_isolation_1.rounded_corner_bounds);
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
const cc::EffectNode& mask_isolation_2 =
@@ -3829,21 +3719,19 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
// [ mask_isolation_0 ][ mask_isolation_1 ][ mask_isolation_2 ]
// [ e0 ]
// Three content layers, three clip mask.
- ASSERT_EQ(6u, RootLayer()->children().size());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(6u, LayerCount());
ASSERT_EQ(3u, SynthesizedClipLayerCount());
- const cc::Layer* content0 = RootLayer()->children()[0].get();
- const cc::Layer* clip_mask0 = RootLayer()->children()[1].get();
- const cc::Layer* content1 = RootLayer()->children()[2].get();
- const cc::Layer* clip_mask1 = RootLayer()->children()[3].get();
- const cc::Layer* content2 = RootLayer()->children()[4].get();
- const cc::Layer* clip_mask2 = RootLayer()->children()[5].get();
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* clip_mask0 = LayerAt(1);
+ const cc::Layer* content1 = LayerAt(2);
+ const cc::Layer* clip_mask1 = LayerAt(3);
+ const cc::Layer* content2 = LayerAt(4);
+ const cc::Layer* clip_mask2 = LayerAt(5);
constexpr int c0_id = 1;
constexpr int e0_id = 1;
- EXPECT_EQ(ContentLayerAt(0), content0);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3863,7 +3751,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
- EXPECT_EQ(ContentLayerAt(1), content1);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
@@ -3884,7 +3771,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
ASSERT_EQ(mask_isolation_1_id, mask_effect_1.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_1.blend_mode);
- EXPECT_EQ(ContentLayerAt(2), content2);
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
const cc::EffectNode& mask_isolation_2 =
@@ -3911,19 +3797,19 @@ TEST_P(PaintArtifactCompositorTest, WillBeRemovedFromFrame) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
WillBeRemovedFromFrame();
// We would need a fake or mock LayerTreeHost to validate that we
// unregister all element ids, so just check layer count for now.
- EXPECT_EQ(0u, ContentLayerCount());
+ EXPECT_EQ(0u, LayerCount());
}
TEST_P(PaintArtifactCompositorTest, ContentsNonOpaque) {
TestPaintArtifact artifact;
artifact.Chunk().RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_FALSE(ContentLayerAt(0)->contents_opaque());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_FALSE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, ContentsOpaque) {
@@ -3932,8 +3818,8 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaque) {
.RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_TRUE(ContentLayerAt(0)->contents_opaque());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_TRUE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) {
@@ -3945,9 +3831,9 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) {
.RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_EQ(gfx::Size(300, 300), ContentLayerAt(0)->bounds());
- EXPECT_FALSE(ContentLayerAt(0)->contents_opaque());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_EQ(gfx::Size(300, 300), LayerAt(0)->bounds());
+ EXPECT_FALSE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) {
@@ -3959,9 +3845,9 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) {
.RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_EQ(gfx::Size(300, 300), ContentLayerAt(0)->bounds());
- EXPECT_TRUE(ContentLayerAt(0)->contents_opaque());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_EQ(gfx::Size(300, 300), LayerAt(0)->bounds());
+ EXPECT_TRUE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque2) {
@@ -3973,11 +3859,11 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque2) {
.RectDrawing(FloatRect(100, 100, 300, 300), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_EQ(gfx::Size(300, 300), ContentLayerAt(0)->bounds());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_EQ(gfx::Size(300, 300), LayerAt(0)->bounds());
// TODO(crbug.com/701991): Upgrade GeometryMapper to make this test pass with
// the following EXPECT_FALSE changed to EXPECT_TRUE.
- EXPECT_FALSE(ContentLayerAt(0)->contents_opaque());
+ EXPECT_FALSE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) {
@@ -3991,9 +3877,9 @@ TEST_P(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) {
artifact.Chunk(t0(), *clip1, *effect1)
.RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 50.f), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(125, 125), layer->bounds());
EXPECT_EQ(1, layer->effect_tree_index());
@@ -4013,9 +3899,9 @@ TEST_P(PaintArtifactCompositorTest, CompositedEffectWithNoOutputClip) {
artifact.Chunk(t0(), *clip1, *effect1)
.RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- const cc::Layer* layer = ContentLayerAt(0);
+ const cc::Layer* layer = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50.f, 50.f), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(125, 125), layer->bounds());
EXPECT_EQ(1, layer->clip_tree_index());
@@ -4036,9 +3922,9 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
artifact1.Client(0).Validate();
artifact1.Client(1).Validate();
Update(artifact1.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
- auto* layer = ContentLayerAt(0);
+ auto* layer = LayerAt(0);
EXPECT_EQ(gfx::Vector2dF(50, 50), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(200, 200), layer->bounds());
EXPECT_THAT(
@@ -4056,8 +3942,8 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
layer->PushPropertiesTo(
layer->CreateLayerImpl(host_impl.active_tree()).get());
Update(artifact2);
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// Invalidate the first chunk because its transform in layer changed.
EXPECT_EQ(gfx::Rect(0, 0, 300, 180), layer->update_rect());
@@ -4079,8 +3965,8 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
layer->PushPropertiesTo(
layer->CreateLayerImpl(host_impl.active_tree()).get());
Update(artifact3);
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// We should not invalidate the layer because the origin didn't change
// because of the clip.
@@ -4257,11 +4143,11 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfaces) {
artifact.Chunk(t0(), c0(), *c).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *ca).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(6u, ContentLayerCount());
+ ASSERT_EQ(6u, LayerCount());
int effect_ids[6];
- for (size_t i = 0; i < ContentLayerCount(); i++)
- effect_ids[i] = ContentLayerAt(i)->effect_tree_index();
+ for (size_t i = 0; i < LayerCount(); i++)
+ effect_ids[i] = LayerAt(i)->effect_tree_index();
// Effects of layer 0, 1, 5 each has one compositing layer, so don't have
// render surface.
@@ -4305,9 +4191,9 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithFilterChildren) {
.Chunk(t0(), c0(), *filter2)
.RectDrawing(r, Color::kWhite)
.Build());
- ASSERT_EQ(2u, ContentLayerCount());
- auto filter_id1 = ContentLayerAt(0)->effect_tree_index();
- auto filter_id2 = ContentLayerAt(1)->effect_tree_index();
+ ASSERT_EQ(2u, LayerCount());
+ auto filter_id1 = LayerAt(0)->effect_tree_index();
+ auto filter_id2 = LayerAt(1)->effect_tree_index();
EXPECT_OPACITY(filter_id1, 1.f, kHasRenderSurface);
EXPECT_OPACITY(filter_id2, 1.f, kHasRenderSurface);
EXPECT_OPACITY(GetPropertyTrees().effect_tree.Node(filter_id1)->parent_id,
@@ -4344,11 +4230,11 @@ TEST_P(PaintArtifactCompositorTest, OpacityAnimationRenderSurfaces) {
artifact.Chunk(t0(), c0(), *c).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *ca).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(6u, ContentLayerCount());
+ ASSERT_EQ(6u, LayerCount());
int effect_ids[6];
- for (size_t i = 0; i < ContentLayerCount(); i++)
- effect_ids[i] = ContentLayerAt(i)->effect_tree_index();
+ for (size_t i = 0; i < LayerCount(); i++)
+ effect_ids[i] = LayerAt(i)->effect_tree_index();
// Effects of layer 0, 1, 5 each has one compositing layer, so don't have
// render surface.
@@ -4396,12 +4282,10 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithBackdropChildren) {
artifact.Chunk(t0(), c0(), *a).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *bd).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 0.5,
- kHasRenderSurface);
- EXPECT_OPACITY(ContentLayerAt(1)->effect_tree_index(), 1.0,
- kHasRenderSurface);
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 0.5, kHasRenderSurface);
+ EXPECT_OPACITY(LayerAt(1)->effect_tree_index(), 1.0, kHasRenderSurface);
}
TEST_P(PaintArtifactCompositorTest,
@@ -4417,10 +4301,10 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), e0()).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), *c1, *e1).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
- const auto* effect = GetPropertyTrees().effect_tree.Node(
- ContentLayerAt(1)->effect_tree_index());
+ const auto* effect =
+ GetPropertyTrees().effect_tree.Node(LayerAt(1)->effect_tree_index());
EXPECT_TRUE(effect->HasRenderSurface());
}
@@ -4438,10 +4322,10 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), e0()).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), *c1, *e1).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
- const auto* effect = GetPropertyTrees().effect_tree.Node(
- ContentLayerAt(1)->effect_tree_index());
+ const auto* effect =
+ GetPropertyTrees().effect_tree.Node(LayerAt(1)->effect_tree_index());
EXPECT_TRUE(effect->HasRenderSurface());
}
@@ -4458,12 +4342,12 @@ TEST_P(PaintArtifactCompositorTest, OpacityIndirectlyAffectingTwoLayers) {
artifact.Chunk(t0(), c0(), *grandchild_composited_effect)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
const auto& effect_tree = GetPropertyTrees().effect_tree;
- int layer0_effect_id = ContentLayerAt(0)->effect_tree_index();
+ int layer0_effect_id = LayerAt(0)->effect_tree_index();
EXPECT_OPACITY(layer0_effect_id, 1.f, kNoRenderSurface);
- int layer1_effect_id = ContentLayerAt(1)->effect_tree_index();
+ int layer1_effect_id = LayerAt(1)->effect_tree_index();
EXPECT_OPACITY(layer1_effect_id, 1.f, kNoRenderSurface);
// |opacity| affects both layer0 and layer1 which don't have render surfaces,
// so it should have a render surface.
@@ -4484,16 +4368,16 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(t0(), c0(), *grandchild_composited_effect)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kGray);
Update(artifact.Build());
- ASSERT_EQ(2u, ContentLayerCount());
+ ASSERT_EQ(2u, LayerCount());
const auto& effect_tree = GetPropertyTrees().effect_tree;
// layer0's opacity animation needs a render surfafce because it affects
// both layer0 and layer1.
- int layer0_effect_id = ContentLayerAt(0)->effect_tree_index();
+ int layer0_effect_id = LayerAt(0)->effect_tree_index();
EXPECT_OPACITY(layer0_effect_id, 1.f, kHasRenderSurface);
// layer1's opacity animation doesn't need a render surface because it
// affects layer1 only.
- int layer1_effect_id = ContentLayerAt(1)->effect_tree_index();
+ int layer1_effect_id = LayerAt(1)->effect_tree_index();
EXPECT_OPACITY(layer1_effect_id, 1.f, kNoRenderSurface);
// Though |opacity| affects both layer0 and layer1, layer0's effect has
// render surface, so |opacity| doesn't need a render surface.
@@ -4517,8 +4401,8 @@ TEST_P(PaintArtifactCompositorTest,
.Chunk(t0(), c0(), *e1)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 1.f, kNoRenderSurface);
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kNoRenderSurface);
}
TEST_P(PaintArtifactCompositorTest, FilterCreatesRenderSurface) {
@@ -4530,9 +4414,8 @@ TEST_P(PaintArtifactCompositorTest, FilterCreatesRenderSurface) {
.Chunk(t0(), c0(), *e1)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 1.f,
- kHasRenderSurface);
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
}
TEST_P(PaintArtifactCompositorTest, FilterAnimationCreatesRenderSurface) {
@@ -4541,9 +4424,8 @@ TEST_P(PaintArtifactCompositorTest, FilterAnimationCreatesRenderSurface) {
.Chunk(t0(), c0(), *e1)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 1.f,
- kHasRenderSurface);
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
}
TEST_P(PaintArtifactCompositorTest, BackdropFilterCreatesRenderSurface) {
@@ -4555,9 +4437,8 @@ TEST_P(PaintArtifactCompositorTest, BackdropFilterCreatesRenderSurface) {
.Chunk(t0(), c0(), *e1)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 1.f,
- kHasRenderSurface);
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
}
TEST_P(PaintArtifactCompositorTest,
@@ -4567,9 +4448,8 @@ TEST_P(PaintArtifactCompositorTest,
.Chunk(t0(), c0(), *e1)
.RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- EXPECT_OPACITY(ContentLayerAt(0)->effect_tree_index(), 1.f,
- kHasRenderSurface);
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
}
TEST_P(PaintArtifactCompositorTest, Non2dAxisAlignedClip) {
@@ -4582,12 +4462,12 @@ TEST_P(PaintArtifactCompositorTest, Non2dAxisAlignedClip) {
artifact.Chunk(t0(), *clip, *opacity)
.RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
// We should create a synthetic effect node for the non-2d-axis-aligned clip.
- int clip_id = ContentLayerAt(0)->clip_tree_index();
+ int clip_id = LayerAt(0)->clip_tree_index();
const auto* cc_clip = GetPropertyTrees().clip_tree.Node(clip_id);
- int effect_id = ContentLayerAt(0)->effect_tree_index();
+ int effect_id = LayerAt(0)->effect_tree_index();
const auto* cc_effect = GetPropertyTrees().effect_tree.Node(effect_id);
EXPECT_OPACITY(effect_id, 1.f, kHasRenderSurface);
EXPECT_OPACITY(cc_effect->parent_id, 0.5f, kNoRenderSurface);
@@ -4607,12 +4487,12 @@ TEST_P(PaintArtifactCompositorTest, Non2dAxisAlignedRoundedRectClip) {
artifact.Chunk(t0(), *clip, *opacity)
.RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(1u, ContentLayerCount());
+ ASSERT_EQ(1u, LayerCount());
// We should create a synthetic effect node for the non-2d-axis-aligned clip.
- int clip_id = ContentLayerAt(0)->clip_tree_index();
+ int clip_id = LayerAt(0)->clip_tree_index();
const auto* cc_clip = GetPropertyTrees().clip_tree.Node(clip_id);
- int effect_id = ContentLayerAt(0)->effect_tree_index();
+ int effect_id = LayerAt(0)->effect_tree_index();
const auto* cc_effect = GetPropertyTrees().effect_tree.Node(effect_id);
EXPECT_OPACITY(effect_id, 1.f, kHasRenderSurface);
EXPECT_OPACITY(cc_effect->parent_id, 0.5f, kNoRenderSurface);
@@ -4646,14 +4526,14 @@ TEST_P(PaintArtifactCompositorTest,
artifact.Chunk(*rotate2, *clip, *opacity)
.RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
- ASSERT_EQ(3u, ContentLayerCount());
+ ASSERT_EQ(3u, LayerCount());
// We should create a synthetic effect node for the non-2d-axis-aligned clip,
// though the accumulated transform to the known render surface was identity
// when the cc clip node was created.
- int clip_id = ContentLayerAt(2)->clip_tree_index();
+ int clip_id = LayerAt(2)->clip_tree_index();
const auto* cc_clip = GetPropertyTrees().clip_tree.Node(clip_id);
- int effect_id = ContentLayerAt(2)->effect_tree_index();
+ int effect_id = LayerAt(2)->effect_tree_index();
const auto* cc_effect = GetPropertyTrees().effect_tree.Node(effect_id);
EXPECT_OPACITY(effect_id, 1.f, kHasRenderSurface);
EXPECT_OPACITY(cc_effect->parent_id, 0.5f, kHasRenderSurface);
@@ -4671,8 +4551,8 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
.Properties(*t2, c0(), e0())
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ cc::Layer* layer = LayerAt(0);
// Change t1 but not t2.
layer->ClearSubtreePropertyChangedForTesting();
@@ -4687,8 +4567,8 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// TODO(wangxianzhu): Probably avoid setting this flag on transform change.
EXPECT_TRUE(layer->subtree_property_changed());
// This is set by cc when propagating ancestor change flag to descendants.
@@ -4712,8 +4592,8 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// TODO(wangxianzhu): Probably avoid setting this flag on transform change.
EXPECT_TRUE(layer->subtree_property_changed());
EXPECT_TRUE(GetTransformNode(layer).transform_changed);
@@ -4734,8 +4614,8 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// The new transform is decomposited, so there is no transform_changed, but
// we set subtree_property_changed because offset_from_transform_parent
// (calculated from the decomposited transforms) changed.
@@ -4753,8 +4633,8 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
.Properties(t0(), c0(), *e2)
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- cc::Layer* layer = ContentLayerAt(0);
+ ASSERT_EQ(1u, LayerCount());
+ cc::Layer* layer = LayerAt(0);
// Change e1 but not e2.
layer->ClearSubtreePropertyChangedForTesting();
@@ -4773,8 +4653,8 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// TODO(wangxianzhu): Probably avoid setting this flag on Effect change.
EXPECT_TRUE(layer->subtree_property_changed());
// This is set by cc when propagating ancestor change flag to descendants.
@@ -4801,8 +4681,8 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
.RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
.Build());
- ASSERT_EQ(1u, ContentLayerCount());
- ASSERT_EQ(layer, ContentLayerAt(0));
+ ASSERT_EQ(1u, LayerCount());
+ ASSERT_EQ(layer, LayerAt(0));
// TODO(wangxianzhu): Probably avoid setting this flag on Effect change.
EXPECT_TRUE(layer->subtree_property_changed());
EXPECT_TRUE(GetEffectNode(layer).effect_changed);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
index ce4a6bf8c06..1bc279443be 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
@@ -171,7 +172,8 @@ class ConversionContext {
// Ends the effect on the top of the state stack if the stack is not empty,
// and update the bounds of the SaveLayer[Alpha]Op of the effect.
void EndEffect();
- void UpdateEffectBounds(const FloatRect&, const TransformPaintPropertyNode&);
+ void UpdateEffectBounds(const base::Optional<FloatRect>&,
+ const TransformPaintPropertyNode&);
// Starts a clip state by adjusting the transform state, applying
// |combined_clip_rect| which is combined from one or more consecutive clips,
@@ -242,7 +244,7 @@ class ConversionContext {
// Records the bounds of the effect which initiated the entry. Note that
// the effect is not |this->effect| (which is the previous effect), but the
// |current_effect_| when this entry is the top of the stack.
- FloatRect bounds;
+ base::Optional<FloatRect> bounds;
};
Vector<EffectBoundsInfo> effect_bounds_stack_;
@@ -588,22 +590,25 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
const ClipPaintPropertyNode* input_clip = current_clip_;
PushState(StateEntry::kEffect, saved_count);
effect_bounds_stack_.emplace_back(
- EffectBoundsInfo{save_layer_id, current_transform_});
+ EffectBoundsInfo{save_layer_id, current_transform_, base::nullopt});
current_clip_ = input_clip;
current_effect_ = &effect;
}
void ConversionContext::UpdateEffectBounds(
- const FloatRect& bounds,
+ const base::Optional<FloatRect>& bounds,
const TransformPaintPropertyNode& transform) {
- if (effect_bounds_stack_.IsEmpty() || bounds.IsEmpty())
+ if (effect_bounds_stack_.IsEmpty() || !bounds)
return;
auto& effect_bounds_info = effect_bounds_stack_.back();
- FloatRect mapped_bounds = bounds;
+ FloatRect mapped_bounds = *bounds;
GeometryMapper::SourceToDestinationRect(
transform, *effect_bounds_info.transform, mapped_bounds);
- effect_bounds_info.bounds.Unite(mapped_bounds);
+ if (effect_bounds_info.bounds)
+ effect_bounds_info.bounds->Unite(mapped_bounds);
+ else
+ effect_bounds_info.bounds = mapped_bounds;
}
void ConversionContext::EndEffect() {
@@ -617,20 +622,20 @@ void ConversionContext::EndEffect() {
DCHECK(effect_bounds_stack_.size());
const auto& bounds_info = effect_bounds_stack_.back();
- FloatRect bounds = bounds_info.bounds;
- if (!bounds.IsEmpty()) {
+ base::Optional<FloatRect> bounds = bounds_info.bounds;
+ if (bounds) {
if (current_effect_->Filter().IsEmpty()) {
- cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id, bounds);
+ cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id, *bounds);
} else {
// The bounds for the SaveLayer[Alpha]Op should be the source bounds
// before the filter is applied, in the space of the TranslateOp which was
// emitted before the SaveLayer[Alpha]Op.
- auto save_layer_bounds = bounds;
+ auto save_layer_bounds = *bounds;
save_layer_bounds.MoveBy(-current_effect_->FiltersOrigin());
cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id,
save_layer_bounds);
// We need to propagate the filtered bounds to the parent.
- bounds = current_effect_->MapRect(bounds);
+ bounds = current_effect_->MapRect(*bounds);
}
}
@@ -719,11 +724,14 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
bool switched_to_chunk_state = false;
for (const auto& item : display_items.ItemsInPaintChunk(chunk)) {
- if (!item.IsDrawing())
+ sk_sp<const PaintRecord> record;
+ if (item.IsScrollbar())
+ record = static_cast<const ScrollbarDisplayItem&>(item).Paint();
+ else if (item.IsDrawing())
+ record = static_cast<const DrawingDisplayItem&>(item).GetPaintRecord();
+ else
continue;
- auto record =
- static_cast<const DrawingDisplayItem&>(item).GetPaintRecord();
// If we have an empty paint record, then we would prefer not to draw it.
// However, if we also have a non-root effect, it means that the filter
// applied might draw something even if the record is empty. We need to
@@ -746,7 +754,17 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
cc_list_.EndPaintOfUnpaired(
chunk_to_layer_mapper_.MapVisualRect(item.VisualRect()));
}
- UpdateEffectBounds(FloatRect(chunk.bounds), chunk_state.Transform());
+
+ // Chunk bounds are only important when we are actually drawing. There may
+ // also be cases when we only generate a paint record and do not draw,
+ // for example, to implement an SVG clip. In such cases, we can safely
+ // ignore effect bounds.
+ base::Optional<FloatRect> chunk_bounds;
+ if (cc_list_.GetUsageHint() ==
+ cc::DisplayItemList::kTopLevelDisplayItemList) {
+ chunk_bounds = FloatRect(chunk.bounds);
+ }
+ UpdateEffectBounds(chunk_bounds, chunk_state.Transform());
}
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
index e7aaa29f92c..7953f485235 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
@@ -101,7 +101,7 @@ class PaintRecordMatcher
Vector<cc::PaintOpType> expected_ops_;
};
-#define EXPECT_EFFECT_BOUNDS(x, y, width, height, op_buffer, index) \
+#define EXPECT_EFFECT_BOUNDS(rect, op_buffer, index) \
do { \
FloatRect bounds; \
if (const auto* save_layer_alpha = \
@@ -113,7 +113,7 @@ class PaintRecordMatcher
} else { \
FAIL() << "No SaveLayer[Alpha]Op at " << index; \
} \
- EXPECT_EQ(FloatRect(x, y, width, height), bounds); \
+ EXPECT_EQ(rect, bounds); \
} while (false)
#define EXPECT_TRANSFORM_MATRIX(transform, op_buffer, index) \
@@ -183,6 +183,10 @@ struct TestChunks {
}
};
+const cc::DisplayItemList::UsageHint kUsageHints[] = {
+ cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer,
+ cc::DisplayItemList::kTopLevelDisplayItemList};
+
TEST_P(PaintChunksToCcLayerTest, EffectGroupingSimple) {
// This test verifies effects are applied as a group.
auto e1 = CreateOpacityEffect(e0(), 0.5f);
@@ -190,18 +194,23 @@ TEST_P(PaintChunksToCcLayerTest, EffectGroupingSimple) {
chunks.AddChunk(t0(), c0(), *e1, IntRect(0, 0, 50, 50));
chunks.AddChunk(t0(), c0(), *e1, IntRect(20, 20, 70, 70));
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(0, 0, 90, 90, *output, 0);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 90, 90)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
}
TEST_P(PaintChunksToCcLayerTest, EffectGroupingNested) {
@@ -213,24 +222,33 @@ TEST_P(PaintChunksToCcLayerTest, EffectGroupingNested) {
chunks.AddChunk(t0(), c0(), *e2);
chunks.AddChunk(t0(), c0(), *e3, IntRect(111, 222, 333, 444));
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::SaveLayerAlpha, // <e3>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </e3>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(0, 0, 444, 666, *output, 0);
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 1);
- EXPECT_EFFECT_BOUNDS(111, 222, 333, 444, *output, 4);
+ const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 444, 666)};
+ const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+ const FloatRect kExpectedBounds3[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(111, 222, 333, 444)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::SaveLayerAlpha, // <e3>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </e3>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 0);
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 1);
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds3[hint], *output, 4);
+ }
}
TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
@@ -246,40 +264,47 @@ TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
chunks.AddChunk(*t2, c0(), *e1, IntRect(0, 0, 50, 50));
chunks.AddChunk(*t1, c0(), *e2, IntRect(20, 20, 70, 70));
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make(
- {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*t2>
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e2_offset>
- cc::PaintOpType::SaveLayer, // <e2>
- cc::PaintOpType::Translate, // <e2_offset^-1/>
- cc::PaintOpType::Save, cc::PaintOpType::Translate, // <t2^-1>
- cc::PaintOpType::DrawRecord, // <p2/>
- cc::PaintOpType::Restore, // </t2^-1>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore, // </e2_offset>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore})); // </t1*t2>
- EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->SlowMatrix(), *output, 1);
- // chunk1.bounds + e2(t2^-1(chunk2.bounds))
- EXPECT_EFFECT_BOUNDS(0, 0, 155, 155, *output, 2);
- // e2_offset
- EXPECT_TRANSLATE(60, 60, *output, 5);
- // t2^-1(chunk2.bounds) - e2_offset
- EXPECT_EFFECT_BOUNDS(10, 10, 70, 70, *output, 6);
- // -e2_offset
- EXPECT_TRANSLATE(-e2->FiltersOrigin().X(), -e2->FiltersOrigin().Y(), *output,
- 7);
- // t2^1
- EXPECT_TRANSLATE(-t2->Translation2D().Width(), -t2->Translation2D().Height(),
- *output, 9);
+ const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 155, 155)};
+ const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(10, 10, 70, 70)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*t2>
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e2_offset>
+ cc::PaintOpType::SaveLayer, // <e2>
+ cc::PaintOpType::Translate, // <e2_offset^-1/>
+ cc::PaintOpType::Save, cc::PaintOpType::Translate, // <t2^-1>
+ cc::PaintOpType::DrawRecord, // <p2/>
+ cc::PaintOpType::Restore, // </t2^-1>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::Restore, // </e2_offset>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Restore})); // </t1*t2>
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->SlowMatrix(), *output, 1);
+ // chunk1.bounds + e2(t2^-1(chunk2.bounds))
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 2);
+ // e2_offset
+ EXPECT_TRANSLATE(60, 60, *output, 5);
+ // t2^-1(chunk2.bounds) - e2_offset
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 6);
+ // -e2_offset
+ EXPECT_TRANSLATE(-e2->FiltersOrigin().X(), -e2->FiltersOrigin().Y(),
+ *output, 7);
+ // t2^1
+ EXPECT_TRANSLATE(-t2->Translation2D().Width(),
+ -t2->Translation2D().Height(), *output, 9);
+ }
}
TEST_P(PaintChunksToCcLayerTest, InterleavedClipEffect) {
@@ -301,38 +326,45 @@ TEST_P(PaintChunksToCcLayerTest, InterleavedClipEffect) {
chunks.AddChunk(t0(), *c3, *e1, IntRect(20, 20, 70, 70));
chunks.AddChunk(t0(), *c4, e0());
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(*output, PaintRecordMatcher::Make(
- {cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1+c2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </c3>
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3+c4>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p2/>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore, // </c3+c4>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3>
- cc::PaintOpType::DrawRecord, // <p3/>
- cc::PaintOpType::Restore, // </c3>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3+c4>
- cc::PaintOpType::DrawRecord, // <p4/>
- cc::PaintOpType::Restore, // </c3+c4>
- cc::PaintOpType::Restore})); // </c1+c2>
- EXPECT_EFFECT_BOUNDS(0, 0, 90, 90, *output, 7);
- EXPECT_EFFECT_BOUNDS(0, 0, 50, 50, *output, 10);
+ const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 90, 90)};
+ const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 50, 50)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output, PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1+c2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </c3>
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3+c4>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p2/>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::Restore, // </c3+c4>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3>
+ cc::PaintOpType::DrawRecord, // <p3/>
+ cc::PaintOpType::Restore, // </c3>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3+c4>
+ cc::PaintOpType::DrawRecord, // <p4/>
+ cc::PaintOpType::Restore, // </c3+c4>
+ cc::PaintOpType::Restore})); // </c1+c2>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 7);
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 10);
+ }
}
TEST_P(PaintChunksToCcLayerTest, ClipSpaceInversion) {
@@ -375,24 +407,29 @@ TEST_P(PaintChunksToCcLayerTest, OpacityEffectSpaceInversion) {
chunks.AddChunk(t0(), c0(), *e1);
chunks.AddChunk(*t1, c0(), *e1);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(*output,
- PaintRecordMatcher::Make(
- {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </t1^-1>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore})); // </t1>
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 2);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output,
+ PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </t1^-1>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Restore})); // </t1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 2);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4);
+ }
}
TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
@@ -410,29 +447,33 @@ TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
TestChunks chunks;
chunks.AddChunk(t0(), c0(), *e1);
- auto output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make(
- {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
- cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e1_offset>
- cc::PaintOpType::SaveLayer, // <e1>
- cc::PaintOpType::Translate, // <e1_offset^-1/>
- cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </t1^-1>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore, // </e1_offset>
- cc::PaintOpType::Restore})); // </t1>
- EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
- EXPECT_TRANSLATE(66, 88, *output, 3);
- EXPECT_EFFECT_BOUNDS(-66, -88, 50, 50, *output, 4);
- EXPECT_TRANSLATE(-66, -88, *output, 5);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 7);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(-66, -88, 50, 50)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ auto output = PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items, kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
+ cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e1_offset>
+ cc::PaintOpType::SaveLayer, // <e1>
+ cc::PaintOpType::Translate, // <e1_offset^-1/>
+ cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </t1^-1>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Restore, // </e1_offset>
+ cc::PaintOpType::Restore})); // </t1>
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
+ EXPECT_TRANSLATE(66, 88, *output, 3);
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 4);
+ EXPECT_TRANSLATE(-66, -88, *output, 5);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 7);
+ }
}
TEST_P(PaintChunksToCcLayerTest, NonRootLayerSimple) {
@@ -482,20 +523,25 @@ TEST_P(PaintChunksToCcLayerTest, EffectWithNoOutputClip) {
TestChunks chunks;
chunks.AddChunk(t0(), *c2, *e1);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), *c1, e0()), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c2>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), *c1, e0()), gfx::Vector2dF(),
+ chunks.items, kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c2>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
}
TEST_P(PaintChunksToCcLayerTest,
@@ -507,23 +553,30 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c1>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 1);
+ const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+ const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c1>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 0);
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 1);
+ }
}
TEST_P(PaintChunksToCcLayerTest,
@@ -535,20 +588,25 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), c0(), *e1), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c1>
- cc::PaintOpType::Restore})); // </e2>
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), c0(), *e1), gfx::Vector2dF(),
+ chunks.items, kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c1>
+ cc::PaintOpType::Restore})); // </e2>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
}
TEST_P(PaintChunksToCcLayerTest,
@@ -560,17 +618,22 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), *c1, *e1), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore})); // </e2>
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), *c1, *e1), gfx::Vector2dF(),
+ chunks.items, kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore})); // </e2>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
}
TEST_P(PaintChunksToCcLayerTest, VisualRect) {
@@ -688,17 +751,22 @@ TEST_P(PaintChunksToCcLayerTest, EmptyEffectsAreStored) {
chunks.AddChunk(nullptr, t0(), c0(), e0());
chunks.AddChunk(nullptr, t0(), c0(), *e1);
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
- chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
- ->ReleaseAsRecord();
-
- EXPECT_THAT(*output, PaintRecordMatcher::Make({
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Restore, // </e1>
- }));
- EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 100, 100)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items,
+ kUsageHints[hint])
+ ->ReleaseAsRecord();
+
+ EXPECT_THAT(*output, PaintRecordMatcher::Make({
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Restore, // </e1>
+ }));
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
}
TEST_P(PaintChunksToCcLayerTest, CombineClips) {
@@ -1313,5 +1381,28 @@ TEST_P(PaintChunksToCcLayerTest, AllowChunkEscapeLayerNoopEffects) {
}));
}
+// https://crbug.com/918240
+TEST_P(PaintChunksToCcLayerTest, EmptyChunkRectDoesntTurnToUnsetOne) {
+ CompositorFilterOperations filter;
+ filter.AppendBlurFilter(5);
+ auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(0, 0));
+ TestChunks chunks;
+ chunks.AddChunk(nullptr, t0(), c0(), *e1, {0, 0, 0, 0});
+
+ const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
+ FloatRect(0, 0, 0, 0)};
+
+ for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
+ auto output = PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(), chunks.items, kUsageHints[hint])
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayer, // <e1>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ }
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
index 4770acc056c..86bd4d15537 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -40,7 +40,7 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"Is DOM overlay for WebXR immersive-ar mode"},
{CompositingReason::kScrollDependentPosition, "scrollDependentPosition",
"Is fixed or sticky position"},
- {CompositingReason::kOverflowScrollingTouch, "overflowScrollingTouch",
+ {CompositingReason::kOverflowScrolling, "overflowScrolling",
"Is a scrollable overflow element"},
{CompositingReason::kOverflowScrollingParent, "overflowScrollingParent",
"Scroll parent is not an ancestor"},
@@ -58,6 +58,8 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"Has a backdrop filter"},
{CompositingReason::kRootScroller, "rootScroller",
"Is the document.rootScroller"},
+ {CompositingReason::kCrossOriginIframe, "crossOriginIframe",
+ "Is a cross-origin iframe"},
{CompositingReason::kAssumedOverlap, "assumedOverlap",
"Might overlap other composited content"},
{CompositingReason::kOverlap, "overlap",
@@ -98,8 +100,6 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"preserve3DWith3DDescendants",
"Has a preserves-3d property that needs to be known by compositor because "
"of 3d descendants"},
- {CompositingReason::kReflectionOfCompositedParent,
- "reflectionOfCompositedParent", "Is a reflection of a composited layer"},
{CompositingReason::kIsolateCompositedDescendants,
"isolateCompositedDescendants",
"Should isolate descendants to apply a blend effect"},
@@ -107,11 +107,6 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"positionFixedWithCompositedDescendants"
"Is a position:fixed element with composited descendants"},
{CompositingReason::kRoot, "root", "Is the root layer"},
- {CompositingReason::kLayerForAncestorClip, "layerForAncestorClip",
- "Secondary layer, applies a clip due to a sibling in the compositing "
- "tree"},
- {CompositingReason::kLayerForDescendantClip, "layerForDescendantClip",
- "Secondary layer, to clip descendants of the owning layer"},
{CompositingReason::kLayerForHorizontalScrollbar,
"layerForHorizontalScrollbar",
"Secondary layer, the horizontal scrollbar layer"},
@@ -137,28 +132,18 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::kLayerForForeground, "layerForForeground",
"Secondary layer, to contain any normal flow and positive z-index "
"contents on top of a negative z-index layer"},
- {CompositingReason::kLayerForBackground, "layerForBackground",
- "Secondary layer, to contain acceleratable background content"},
{CompositingReason::kLayerForMask, "layerForMask",
"Secondary layer, to contain the mask contents"},
- {CompositingReason::kLayerForClippingMask, "layerForClippingMask",
- "Secondary layer, for clipping mask"},
- {CompositingReason::kLayerForAncestorClippingMask,
- "layerForAncestorClippingMask",
- "Secondary layer, applies a clipping mask due to a sibling in the "
- "composited layer tree"},
- {CompositingReason::kLayerForScrollingBlockSelection,
- "layerForScrollingBlockSelection",
- "Secondary layer, to house block selection gaps for composited scrolling "
- "with no scrolling contents"},
{CompositingReason::kLayerForDecoration, "layerForDecoration",
"Layer painted on top of other layers as decoration"},
-
+ {CompositingReason::kLayerForOther, "layerForOther",
+ "Layer for link highlight, frame overlay, etc."},
};
} // anonymous namespace
-Vector<const char*> CompositingReason::ShortNames(CompositingReasons reasons) {
+std::vector<const char*> CompositingReason::ShortNames(
+ CompositingReasons reasons) {
#define V(name) \
static_assert( \
CompositingReason::k##name == \
@@ -168,7 +153,7 @@ Vector<const char*> CompositingReason::ShortNames(CompositingReasons reasons) {
FOR_EACH_COMPOSITING_REASON(V)
#undef V
- Vector<const char*> result;
+ std::vector<const char*> result;
if (reasons == kNone)
return result;
for (auto& map : kCompositingReasonsStringMap) {
@@ -178,9 +163,9 @@ Vector<const char*> CompositingReason::ShortNames(CompositingReasons reasons) {
return result;
}
-Vector<const char*> CompositingReason::Descriptions(
+std::vector<const char*> CompositingReason::Descriptions(
CompositingReasons reasons) {
- Vector<const char*> result;
+ std::vector<const char*> result;
if (reasons == kNone)
return result;
for (auto& map : kCompositingReasonsStringMap) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
index 8d6d9c4cb2d..5df7a4e83d1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -6,10 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_REASONS_H_
#include <stdint.h>
+#include <vector>
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -29,7 +29,7 @@ using CompositingReasons = uint64_t;
V(ActiveBackdropFilterAnimation) \
V(ImmersiveArOverlay) \
V(ScrollDependentPosition) \
- V(OverflowScrollingTouch) \
+ V(OverflowScrolling) \
V(OverflowScrollingParent) \
V(OutOfFlowClipping) \
V(VideoOverlay) \
@@ -40,6 +40,7 @@ using CompositingReasons = uint64_t;
V(WillChangeOther) \
V(BackdropFilter) \
V(RootScroller) \
+ V(CrossOriginIframe) \
\
/* Overlap reasons that require knowing what's behind you in paint-order \
before knowing the answer. */ \
@@ -50,7 +51,6 @@ using CompositingReasons = uint64_t;
\
/* Subtree reasons that require knowing what the status of your subtree is \
before knowing the answer. */ \
- V(TransformWithCompositedDescendants) \
V(OpacityWithCompositedDescendants) \
V(MaskWithCompositedDescendants) \
V(ReflectionWithCompositedDescendants) \
@@ -59,7 +59,6 @@ using CompositingReasons = uint64_t;
V(ClipsCompositingDescendants) \
V(PerspectiveWith3DDescendants) \
V(Preserve3DWith3DDescendants) \
- V(ReflectionOfCompositedParent) \
V(IsolateCompositedDescendants) \
V(PositionFixedWithCompositedDescendants) \
\
@@ -67,9 +66,8 @@ using CompositingReasons = uint64_t;
also needs to be a layer if anything else in the subtree is composited. */ \
V(Root) \
\
- /* CompositedLayerMapping internal hierarchy reasons. */ \
- V(LayerForAncestorClip) \
- V(LayerForDescendantClip) \
+ /* CompositedLayerMapping internal hierarchy reasons. Some of them are also \
+ used in CompositeAfterPaint. */ \
V(LayerForHorizontalScrollbar) \
V(LayerForVerticalScrollbar) \
V(LayerForOverflowControlsHost) \
@@ -79,13 +77,11 @@ using CompositingReasons = uint64_t;
V(LayerForSquashingContents) \
V(LayerForSquashingContainer) \
V(LayerForForeground) \
- V(LayerForBackground) \
V(LayerForMask) \
- V(LayerForClippingMask) \
- V(LayerForAncestorClippingMask) \
- V(LayerForScrollingBlockSelection) \
/* Composited layer painted on top of all other layers as decoration. */ \
- V(LayerForDecoration)
+ V(LayerForDecoration) \
+ /* Used in CompositeAfterPaint for link highlight, frame overlay, etc. */ \
+ V(LayerForOther)
class PLATFORM_EXPORT CompositingReason {
DISALLOW_NEW();
@@ -104,8 +100,8 @@ class PLATFORM_EXPORT CompositingReason {
#undef V
public:
- static Vector<const char*> ShortNames(CompositingReasons);
- static Vector<const char*> Descriptions(CompositingReasons);
+ static std::vector<const char*> ShortNames(CompositingReasons);
+ static std::vector<const char*> Descriptions(CompositingReasons);
static String ToString(CompositingReasons);
enum : CompositingReasons {
@@ -129,13 +125,13 @@ class PLATFORM_EXPORT CompositingReason {
kComboAllDirectNonStyleDeterminedReasons =
kVideo | kCanvas | kPlugin | kIFrame | kOverflowScrollingParent |
kOutOfFlowClipping | kVideoOverlay | kImmersiveArOverlay | kRoot |
- kRootScroller | kScrollDependentPosition,
+ kRootScroller | kScrollDependentPosition | kCrossOriginIframe,
kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons |
kComboAllDirectNonStyleDeterminedReasons,
kComboAllCompositedScrollingDeterminedReasons =
- kScrollDependentPosition | kOverflowScrollingTouch,
+ kScrollDependentPosition | kOverflowScrolling,
kComboCompositedDescendants =
kIsolateCompositedDescendants | kOpacityWithCompositedDescendants |
@@ -157,6 +153,8 @@ class PLATFORM_EXPORT CompositingReason {
k3DTransform | kWillChangeTransform | kWillChangeOther |
kPerspectiveWith3DDescendants | kPreserve3DWith3DDescendants |
kActiveTransformAnimation,
+ kDirectReasonsForScrollTranslationProperty =
+ kRootScroller | kOverflowScrolling,
kDirectReasonsForEffectProperty = kActiveOpacityAnimation |
kWillChangeOpacity | kBackdropFilter |
kActiveBackdropFilterAnimation,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index 0a10700da9f..0c2a478ca67 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -172,22 +172,27 @@ bool DarkModeFilter::IsDarkModeActive() const {
// perform some other logic in between confirming dark mode is active and
// checking the color classifiers.
bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) {
- if (role == ElementRole::kBackground) {
- // Calling get() is necessary below because operator<< in std::unique_ptr is
- // a C++20 feature.
- // TODO(https://crbug.com/980914): Drop .get() once we move to C++20.
- DCHECK_NE(background_classifier_.get(), nullptr);
- return background_classifier_->ShouldInvertColor(color) ==
- DarkModeClassification::kApplyFilter;
+ switch (role) {
+ case ElementRole::kText:
+ DCHECK(text_classifier_);
+ return text_classifier_->ShouldInvertColor(color) ==
+ DarkModeClassification::kApplyFilter;
+ case ElementRole::kBackground:
+ DCHECK(background_classifier_);
+ return background_classifier_->ShouldInvertColor(color) ==
+ DarkModeClassification::kApplyFilter;
+ case ElementRole::kSVG:
+ // 1) Inline SVG images are considered as individual shapes and do not
+ // have an Image object associated with them. So they do not go through
+ // the regular image classification pipeline. Do not apply any filter to
+ // the SVG shapes until there is a way to get the classification for the
+ // entire image to which these shapes belong.
+
+ // 2) Non-inline SVG images are already classified at this point and have
+ // a filter applied if necessary.
+ return false;
}
-
- DCHECK_EQ(role, ElementRole::kText);
- // Calling get() is necessary below because operator<< in std::unique_ptr is
- // a C++20 feature.
- // TODO(https://crbug.com/980914): Drop .get() once we move to C++20.
- DCHECK_NE(text_classifier_.get(), nullptr);
- return text_classifier_->ShouldInvertColor(color) ==
- DarkModeClassification::kApplyFilter;
+ NOTREACHED();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
index 6c96642010e..b46d2e35b75 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -37,7 +37,7 @@ class PLATFORM_EXPORT DarkModeFilter {
// TODO(gilmanmh): Add a role for shadows. In general, we don't want to
// invert shadows, but we may need to do some other kind of processing for
// them.
- enum class ElementRole { kText, kBackground };
+ enum class ElementRole { kText, kBackground, kSVG };
Color InvertColorIfNeeded(const Color& color, ElementRole element_role);
base::Optional<cc::PaintFlags> ApplyToFlagsIfNeeded(
const cc::PaintFlags& flags,
@@ -49,6 +49,8 @@ class PLATFORM_EXPORT DarkModeFilter {
Image* image,
cc::PaintFlags* flags);
+ SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); }
+
private:
DarkModeSettings settings_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
index 34e414d6175..132473342e8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -14,7 +14,6 @@
namespace blink {
namespace {
-// TODO(gilmanmh): Add expectations for image inversion to each test.
TEST(DarkModeFilterTest, DoNotApplyFilterWhenDarkModeIsOff) {
DarkModeFilter filter;
@@ -32,6 +31,8 @@ TEST(DarkModeFilterTest, DoNotApplyFilterWhenDarkModeIsOff) {
EXPECT_EQ(base::nullopt,
filter.ApplyToFlagsIfNeeded(
cc::PaintFlags(), DarkModeFilter::ElementRole::kBackground));
+
+ EXPECT_EQ(nullptr, filter.GetImageFilterForTesting());
}
TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
@@ -48,12 +49,21 @@ TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
filter.InvertColorIfNeeded(
Color::kBlack, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(Color::kWhite,
+ filter.InvertColorIfNeeded(Color::kWhite,
+ DarkModeFilter::ElementRole::kSVG));
+ EXPECT_EQ(Color::kBlack,
+ filter.InvertColorIfNeeded(Color::kBlack,
+ DarkModeFilter::ElementRole::kSVG));
+
cc::PaintFlags flags;
flags.setColor(SK_ColorWHITE);
auto flags_or_nullopt = filter.ApplyToFlagsIfNeeded(
flags, DarkModeFilter::ElementRole::kBackground);
ASSERT_NE(flags_or_nullopt, base::nullopt);
EXPECT_EQ(SK_ColorBLACK, flags_or_nullopt.value().getColor());
+
+ EXPECT_NE(nullptr, filter.GetImageFilterForTesting());
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
index babdfb632bf..50dad6f6644 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
@@ -48,7 +48,7 @@ struct DarkModeSettings {
bool grayscale = false;
float image_grayscale_percent = 0.0; // Valid range from 0.0 to 1.0
float contrast = 0.0; // Valid range from -1.0 to 1.0
- DarkModeImagePolicy image_policy = DarkModeImagePolicy::kFilterAll;
+ DarkModeImagePolicy image_policy = DarkModeImagePolicy::kFilterNone;
DarkModeClassifierType classifier_type = DarkModeClassifierType::kGeneric;
// Text colors with brightness below this threshold will be inverted, and
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
index 6141df1b539..da6f2259314 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
@@ -396,11 +396,24 @@ void DeferredImageDecoder::PrepareLazyDecodedFrames() {
if (!metadata_decoder_ || !metadata_decoder_->IsSizeAvailable())
return;
+ if (!image_metadata_)
+ image_metadata_ = metadata_decoder_->MakeMetadataForDecodeAcceleration();
+
+ // If the image contains a coded size with zero in either or both size
+ // dimensions, the image is invalid.
+ if (image_metadata_->coded_size.has_value() &&
+ image_metadata_->coded_size.value().IsEmpty())
+ return;
+
ActivateLazyDecoding();
const size_t previous_size = frame_data_.size();
frame_data_.resize(metadata_decoder_->FrameCount());
+ // The decoder may be invalidated during a FrameCount(). Simply bail if so.
+ if (metadata_decoder_->Failed())
+ return;
+
// We have encountered a broken image file. Simply bail.
if (frame_data_.size() < previous_size)
return;
@@ -423,9 +436,6 @@ void DeferredImageDecoder::PrepareLazyDecodedFrames() {
metadata_decoder_->CanDecodeToYUV() && all_data_received_ &&
!frame_generator_->IsMultiFrame();
- if (!image_metadata_)
- image_metadata_ = metadata_decoder_->MakeMetadataForDecodeAcceleration();
-
// If we've received all of the data, then we can reset the metadata decoder,
// since everything we care about should now be stored in |frame_data_|.
if (all_data_received_) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
index da3ee02e80b..d515c956a31 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
@@ -270,7 +270,7 @@ TEST_F(DeferredImageDecoderTest, MAYBE_decodeOnOtherThread) {
// Create a thread to rasterize PaintRecord.
std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("RasterThread"));
PostCrossThreadTask(
*thread->GetTaskRunner(), FROM_HERE,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS b/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
index b7824e63632..aa252c3bb21 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
@@ -15,4 +15,5 @@ include_rules = [
"+gpu/config/gpu_driver_bug_workaround_type.h",
"+gpu/config/gpu_feature_info.h",
"+ui/gfx/gpu_fence.h",
+ "+ui/gl/gpu_preference.h",
]
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
index af143834c51..8e88b40607a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_
-#include <dawn/dawn.h>
#include <dawn/dawn_proc_table.h>
+#include <dawn/webgpu.h>
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/platform_export.h"
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index 65b672a3573..261c1b0512d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -60,11 +60,11 @@
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
+#include "ui/gl/gpu_preference.h"
#include "v8/include/v8.h"
namespace blink {
@@ -91,7 +91,8 @@ scoped_refptr<DrawingBuffer> DrawingBuffer::Create(
PreserveDrawingBuffer preserve,
WebGLVersion webgl_version,
ChromiumImageUsage chromium_image_usage,
- const CanvasColorParams& color_params) {
+ const CanvasColorParams& color_params,
+ gl::GpuPreference gpu_preference) {
if (g_should_fail_drawing_buffer_creation_for_testing) {
g_should_fail_drawing_buffer_creation_for_testing = false;
return nullptr;
@@ -142,7 +143,7 @@ scoped_refptr<DrawingBuffer> DrawingBuffer::Create(
std::move(extensions_util), client, discard_framebuffer_supported,
want_alpha_channel, premultiplied_alpha, preserve, webgl_version,
want_depth_buffer, want_stencil_buffer, chromium_image_usage,
- color_params));
+ color_params, gpu_preference));
if (!drawing_buffer->Initialize(size, multisample_supported)) {
drawing_buffer->BeginDestruction();
return scoped_refptr<DrawingBuffer>();
@@ -168,7 +169,8 @@ DrawingBuffer::DrawingBuffer(
bool want_depth,
bool want_stencil,
ChromiumImageUsage chromium_image_usage,
- const CanvasColorParams& color_params)
+ const CanvasColorParams& color_params,
+ gl::GpuPreference gpu_preference)
: client_(client),
preserve_drawing_buffer_(preserve),
webgl_version_(webgl_version),
@@ -186,13 +188,18 @@ DrawingBuffer::DrawingBuffer(
storage_color_space_(color_params.GetStorageGfxColorSpace()),
sampler_color_space_(color_params.GetSamplerGfxColorSpace()),
use_half_float_storage_(color_params.PixelFormat() ==
- kF16CanvasPixelFormat),
+ CanvasPixelFormat::kF16),
chromium_image_usage_(chromium_image_usage),
opengl_flip_y_extension_(
- ContextProvider()->GetCapabilities().mesa_framebuffer_flip_y) {
+ ContextProvider()->GetCapabilities().mesa_framebuffer_flip_y),
+ initial_gpu_(gpu_preference),
+ current_active_gpu_(gpu_preference) {
// Used by browser tests to detect the use of a DrawingBuffer.
TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
TRACE_EVENT_SCOPE_GLOBAL);
+ // PowerPreferenceToGpuPreference should have resolved the meaning
+ // of the "default" GPU already.
+ DCHECK(gpu_preference != gl::GpuPreference::kDefault);
}
DrawingBuffer::~DrawingBuffer() {
@@ -247,7 +254,7 @@ DrawingBuffer::ContextProviderWeakPtr() {
return context_provider_->GetWeakPtr();
}
-void DrawingBuffer::SetIsHidden(bool hidden) {
+void DrawingBuffer::SetIsInHiddenPage(bool hidden) {
if (is_hidden_ == hidden)
return;
is_hidden_ = hidden;
@@ -346,15 +353,15 @@ bool DrawingBuffer::PrepareTransferableResourceInternal(
ResolveIfNeeded();
if (!using_gpu_compositing_ && !force_gpu_result) {
- FinishPrepareTransferableResourceSoftware(bitmap_registrar, out_resource,
- out_release_callback);
- } else {
- FinishPrepareTransferableResourceGpu(out_resource, out_release_callback);
+ return FinishPrepareTransferableResourceSoftware(
+ bitmap_registrar, out_resource, out_release_callback);
}
- return true;
+
+ return FinishPrepareTransferableResourceGpu(out_resource,
+ out_release_callback);
}
-void DrawingBuffer::FinishPrepareTransferableResourceSoftware(
+bool DrawingBuffer::FinishPrepareTransferableResourceSoftware(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
@@ -392,9 +399,10 @@ void DrawingBuffer::FinishPrepareTransferableResourceSoftware(
*out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
ResetBuffersToAutoClear();
+ return true;
}
-void DrawingBuffer::FinishPrepareTransferableResourceGpu(
+bool DrawingBuffer::FinishPrepareTransferableResourceGpu(
viz::TransferableResource* out_resource,
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
DCHECK(state_restorer_);
@@ -420,6 +428,10 @@ void DrawingBuffer::FinishPrepareTransferableResourceGpu(
// into the mailbox, and allocate (or recycle) a new backbuffer.
color_buffer_for_mailbox = back_color_buffer_;
back_color_buffer_ = CreateOrRecycleColorBuffer();
+ if (!back_color_buffer_) {
+ // Context is likely lost.
+ return false;
+ }
AttachColorBufferToReadFramebuffer();
// Explicitly specify that m_fbo (which is now bound to the just-allocated
@@ -438,6 +450,10 @@ void DrawingBuffer::FinishPrepareTransferableResourceGpu(
// TODO(sunnyps): We can skip this test if explicit resolve is used since
// we'll render to the multisample fbo which will be preserved.
color_buffer_for_mailbox = CreateOrRecycleColorBuffer();
+ if (!color_buffer_for_mailbox) {
+ // Context is likely lost.
+ return false;
+ }
gl_->CopySubTextureCHROMIUM(
back_color_buffer_->texture_id, 0, texture_target_,
color_buffer_for_mailbox->texture_id, 0, 0, 0, 0, 0, size_.Width(),
@@ -499,6 +515,7 @@ void DrawingBuffer::FinishPrepareTransferableResourceGpu(
contents_changed_ = false;
ResetBuffersToAutoClear();
+ return true;
}
void DrawingBuffer::MailboxReleasedGpu(scoped_refptr<ColorBuffer> color_buffer,
@@ -562,7 +579,8 @@ scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage(
SkBitmap black_bitmap;
black_bitmap.allocN32Pixels(size_.Width(), size_.Height());
black_bitmap.eraseARGB(0, 0, 0, 0);
- return StaticBitmapImage::Create(SkImage::MakeFromBitmap(black_bitmap));
+ return UnacceleratedStaticBitmapImage::Create(
+ SkImage::MakeFromBitmap(black_bitmap));
}
DCHECK_EQ(size_.Width(), transferable_resource.size.width());
@@ -646,12 +664,17 @@ DrawingBuffer::ScopedRGBEmulationForBlitFramebuffer::
scoped_refptr<CanvasResource> DrawingBuffer::AsCanvasResource(
base::WeakPtr<CanvasResourceProvider> resource_provider) {
+ // Swap chain must be presented before resource is exported.
+ ResolveAndPresentSwapChainIfNeeded();
+
scoped_refptr<ColorBuffer> canvas_resource_buffer =
UsingSwapChain() ? front_color_buffer_ : back_color_buffer_;
+
return ExternalCanvasResource::Create(
canvas_resource_buffer->mailbox, canvas_resource_buffer->size,
texture_target_, CanvasColorParams(), context_provider_->GetWeakPtr(),
- resource_provider, kLow_SkFilterQuality);
+ resource_provider, kLow_SkFilterQuality,
+ /*is_origin_top_left=*/opengl_flip_y_extension_);
}
DrawingBuffer::ColorBuffer::ColorBuffer(
@@ -719,18 +742,11 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
bool supports_implicit_resolve =
!UsingSwapChain() && extensions_util_->SupportsExtension(
"GL_EXT_multisampled_render_to_texture");
- bool supports_screen_space_aa =
- !UsingSwapChain() && extensions_util_->SupportsExtension(
- "GL_CHROMIUM_screen_space_antialiasing");
if (webgl_preferences.anti_aliasing_mode == kAntialiasingModeUnspecified) {
if (use_multisampling) {
anti_aliasing_mode_ = kAntialiasingModeMSAAExplicitResolve;
if (supports_implicit_resolve) {
anti_aliasing_mode_ = kAntialiasingModeMSAAImplicitResolve;
- } else if (supports_screen_space_aa &&
- ContextProvider()->GetGpuFeatureInfo().IsWorkaroundEnabled(
- gpu::USE_FRAMEBUFFER_CMAA)) {
- anti_aliasing_mode_ = kAntialiasingModeScreenSpaceAntialiasing;
}
} else {
anti_aliasing_mode_ = kAntialiasingModeNone;
@@ -738,26 +754,13 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
} else {
bool prefer_implicit_resolve = (webgl_preferences.anti_aliasing_mode ==
kAntialiasingModeMSAAImplicitResolve);
- bool prefer_screen_space_aa = (webgl_preferences.anti_aliasing_mode ==
- kAntialiasingModeScreenSpaceAntialiasing);
- if ((prefer_implicit_resolve && !supports_implicit_resolve) ||
- (prefer_screen_space_aa && !supports_screen_space_aa)) {
+ if (prefer_implicit_resolve && !supports_implicit_resolve) {
DLOG(ERROR) << "Invalid anti-aliasing mode specified.";
return false;
}
anti_aliasing_mode_ = webgl_preferences.anti_aliasing_mode;
}
- // TODO(dshwang): Enable storage textures on all platforms. crbug.com/557848
- // The Linux ATI bot fails
- // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage
- // textures only if ScreenSpaceAntialiasing is enabled, because
- // ScreenSpaceAntialiasing is much faster with storage textures.
- storage_texture_supported_ =
- (webgl_version_ > kWebGL1 ||
- extensions_util_->SupportsExtension("GL_EXT_texture_storage")) &&
- anti_aliasing_mode_ == kAntialiasingModeScreenSpaceAntialiasing;
-
sample_count_ = std::min(
static_cast<int>(webgl_preferences.msaa_sample_count), max_sample_count);
eqaa_storage_sample_count_ = webgl_preferences.eqaa_storage_sample_count;
@@ -1110,22 +1113,49 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) {
void DrawingBuffer::ClearFramebuffers(GLbitfield clear_mask) {
ScopedStateRestorer scoped_state_restorer(this);
- ClearFramebuffersInternal(clear_mask);
+ ClearFramebuffersInternal(clear_mask, ClearAllFBOs);
}
-void DrawingBuffer::ClearFramebuffersInternal(GLbitfield clear_mask) {
+void DrawingBuffer::ClearFramebuffersInternal(GLbitfield clear_mask,
+ ClearOption clear_option) {
DCHECK(state_restorer_);
state_restorer_->SetFramebufferBindingDirty();
- // We will clear the multisample FBO, but we also need to clear the
- // non-multisampled buffer.
- if (multisample_fbo_) {
+ // Clear the multisample FBO, but also clear the non-multisampled buffer if
+ // requested.
+ if (multisample_fbo_ && clear_option == ClearAllFBOs) {
gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
gl_->Clear(GL_COLOR_BUFFER_BIT);
}
- gl_->BindFramebuffer(GL_FRAMEBUFFER,
- multisample_fbo_ ? multisample_fbo_ : fbo_);
- gl_->Clear(clear_mask);
+ if (multisample_fbo_ || clear_option == ClearAllFBOs) {
+ gl_->BindFramebuffer(GL_FRAMEBUFFER,
+ multisample_fbo_ ? multisample_fbo_ : fbo_);
+ gl_->Clear(clear_mask);
+ }
+}
+
+void DrawingBuffer::ClearNewlyAllocatedFramebuffers(ClearOption clear_option) {
+ DCHECK(state_restorer_);
+
+ state_restorer_->SetClearStateDirty();
+ gl_->Disable(GL_SCISSOR_TEST);
+ gl_->ClearColor(0, 0, 0,
+ DefaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
+ gl_->ColorMask(true, true, true, true);
+
+ GLbitfield clear_mask = GL_COLOR_BUFFER_BIT;
+ if (!!depth_stencil_buffer_) {
+ gl_->ClearDepthf(1.0f);
+ clear_mask |= GL_DEPTH_BUFFER_BIT;
+ gl_->DepthMask(true);
+ }
+ if (!!depth_stencil_buffer_) {
+ gl_->ClearStencil(0);
+ clear_mask |= GL_STENCIL_BUFFER_BIT;
+ gl_->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
+ }
+
+ ClearFramebuffersInternal(clear_mask, clear_option);
}
IntSize DrawingBuffer::AdjustSize(const IntSize& desired_size,
@@ -1175,25 +1205,7 @@ bool DrawingBuffer::ResizeFramebufferInternal(const IntSize& new_size) {
return false;
}
- state_restorer_->SetClearStateDirty();
- gl_->Disable(GL_SCISSOR_TEST);
- gl_->ClearColor(0, 0, 0,
- DefaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
- gl_->ColorMask(true, true, true, true);
-
- GLbitfield clear_mask = GL_COLOR_BUFFER_BIT;
- if (!!depth_stencil_buffer_) {
- gl_->ClearDepthf(1.0f);
- clear_mask |= GL_DEPTH_BUFFER_BIT;
- gl_->DepthMask(true);
- }
- if (!!depth_stencil_buffer_) {
- gl_->ClearStencil(0);
- clear_mask |= GL_STENCIL_BUFFER_BIT;
- gl_->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
- }
-
- ClearFramebuffersInternal(clear_mask);
+ ClearNewlyAllocatedFramebuffers(ClearAllFBOs);
return true;
}
@@ -1235,8 +1247,6 @@ void DrawingBuffer::ResolveMultisampleFramebufferInternal() {
}
gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
- if (anti_aliasing_mode_ == kAntialiasingModeScreenSpaceAntialiasing)
- gl_->ApplyScreenSpaceAntialiasingCHROMIUM();
}
void DrawingBuffer::ResolveIfNeeded() {
@@ -1246,13 +1256,57 @@ void DrawingBuffer::ResolveIfNeeded() {
contents_change_resolved_ = true;
auto* gl = ContextProvider()->ContextGL();
- if (gl->DidGpuSwitch() == GL_TRUE) {
- // TODO(crbug.com/681341): handle preserveDrawingBuffer:true, and
- // user-allocated multisampled renderbuffers, by dispatching a context lost
- // event.
- if (WantExplicitResolve()) {
- ReallocateMultisampleRenderbuffer(size_);
+ gl::GpuPreference active_gpu = gl::GpuPreference::kDefault;
+ if (gl->DidGpuSwitch(&active_gpu) == GL_TRUE) {
+ // This code path is mainly taken on macOS (the only platform which, as of
+ // this writing, dispatches the GPU-switched notifications), and the
+ // comments below focus only on macOS.
+ //
+ // The code below attempts to deduce whether, if a GPU switch occurred,
+ // it's really necessary to lose the context because certain GPU resources
+ // are no longer accessible. Resources only become inaccessible if
+ // CGLSetVirtualScreen is explicitly called against a GL context to change
+ // its renderer ID. GPU switching notifications are highly asynchronous.
+ //
+ // The tests below, of the initial and currently active GPU, replicate
+ // some logic in GLContextCGL::ForceGpuSwitchIfNeeded. Basically, if a
+ // context requests the high-performance GPU, then CGLSetVirtualScreen
+ // will never be called to migrate that context to the low-power
+ // GPU. However, contexts that were allocated on the integrated GPU will
+ // be migrated to the discrete GPU, and back, when the discrete GPU is
+ // activated and deactivated. Also, if the high-performance GPU was
+ // requested, then that request took effect during context bringup, even
+ // though the GPU switching notification is generally dispatched a couple
+ // of seconds after that, so it's not necessary to either lose the context
+ // or reallocate the multisampled renderbuffers when that initial
+ // notification is received.
+ if (initial_gpu_ == gl::GpuPreference::kLowPower &&
+ current_active_gpu_ != active_gpu) {
+ if ((WantExplicitResolve() && preserve_drawing_buffer_ == kPreserve) ||
+ client_
+ ->DrawingBufferClientUserAllocatedMultisampledRenderbuffers()) {
+ // In these situations there are multisampled renderbuffers whose
+ // content the application expects to be preserved, but which can not
+ // be. Forcing a lost context is the only option to keep applications
+ // rendering correctly.
+ client_->DrawingBufferClientForceLostContextWithAutoRecovery();
+ } else if (WantExplicitResolve()) {
+ ReallocateMultisampleRenderbuffer(size_);
+
+ // This does a bit more work than desired - clearing any depth and
+ // stencil renderbuffers is unnecessary, since they weren't reallocated
+ // - but reusing this code reduces complexity. Note that we do not clear
+ // the non-multisampled framebuffer, as doing so can cause users'
+ // content to disappear unexpectedly.
+ //
+ // TODO(crbug.com/1046146): perform this clear at the beginning rather
+ // than at the end of a frame in order to eliminate rendering glitches.
+ // This should also simplify the code, allowing removal of the
+ // ClearOption.
+ ClearNewlyAllocatedFramebuffers(ClearOnlyMultisampledFBO);
+ }
}
+ current_active_gpu_ = active_gpu;
}
}
@@ -1433,16 +1487,18 @@ void DrawingBuffer::FlipVertically(uint8_t* framebuffer,
}
}
-void DrawingBuffer::PresentSwapChain() {
- DCHECK(UsingSwapChain());
- DCHECK_EQ(texture_target_, static_cast<unsigned>(GL_TEXTURE_2D));
-
+void DrawingBuffer::ResolveAndPresentSwapChainIfNeeded() {
if (!contents_changed_)
return;
ScopedStateRestorer scoped_state_restorer(this);
ResolveIfNeeded();
+ if (!UsingSwapChain())
+ return;
+
+ DCHECK_EQ(texture_target_, static_cast<unsigned>(GL_TEXTURE_2D));
+
if (premultiplied_alpha_false_texture_) {
// The rendering results are in |premultiplied_alpha_false_texture_| rather
// than the |back_color_buffer_|'s texture. Copy them in, multiplying the
@@ -1480,6 +1536,11 @@ void DrawingBuffer::PresentSwapChain() {
scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
const IntSize& size) {
+ if (size.IsEmpty()) {
+ // Context is likely lost.
+ return nullptr;
+ }
+
DCHECK(state_restorer_);
state_restorer_->SetFramebufferBindingDirty();
state_restorer_->SetTextureBindingDirty();
@@ -1567,9 +1628,8 @@ scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
gl_->BeginSharedImageAccessDirectCHROMIUM(
texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
- // Clear the alpha channel if we allocated a GpuMemoryBuffer and RGB emulation
- // is required.
- if (gpu_memory_buffer && !want_alpha_channel_ && have_alpha_channel_) {
+ // Clear the alpha channel if RGB emulation is required.
+ if (!want_alpha_channel_ && have_alpha_channel_) {
GLuint fbo = 0;
state_restorer_->SetClearStateDirty();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
index 2aa58412c39..c4f0e99a8a9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
@@ -52,6 +52,7 @@
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/color_space.h"
+#include "ui/gl/gpu_preference.h"
namespace cc {
class Layer;
@@ -98,6 +99,9 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
virtual void DrawingBufferClientRestoreFramebufferBinding() = 0;
virtual void DrawingBufferClientRestorePixelUnpackBufferBinding() = 0;
virtual void DrawingBufferClientRestorePixelPackBufferBinding() = 0;
+ virtual bool
+ DrawingBufferClientUserAllocatedMultisampledRenderbuffers() = 0;
+ virtual void DrawingBufferClientForceLostContextWithAutoRecovery() = 0;
};
enum PreserveDrawingBuffer {
@@ -129,7 +133,8 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
PreserveDrawingBuffer,
WebGLVersion,
ChromiumImageUsage,
- const CanvasColorParams&);
+ const CanvasColorParams&,
+ gl::GpuPreference);
static void ForceNextDrawingBufferCreationToFail();
~DrawingBuffer() override;
@@ -186,7 +191,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
void SetBuffersToAutoClear(GLbitfield bitmask);
GLbitfield GetBuffersToAutoClear() const;
- void SetIsHidden(bool);
+ void SetIsInHiddenPage(bool);
void SetFilterQuality(SkFilterQuality);
SkFilterQuality FilterQuality() const { return filter_quality_; }
@@ -249,7 +254,6 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
void RestoreAllState();
bool UsingSwapChain() const { return using_swap_chain_; }
- void PresentSwapChain();
// This class helps implement correct semantics for BlitFramebuffer
// when the DrawingBuffer is using a CHROMIUM image for its backing
@@ -284,7 +288,8 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool wants_depth,
bool wants_stencil,
ChromiumImageUsage,
- const CanvasColorParams&);
+ const CanvasColorParams&,
+ gl::GpuPreference gpu_preference);
bool Initialize(const IntSize&, bool use_multisampling);
@@ -380,8 +385,14 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
DISALLOW_COPY_AND_ASSIGN(ColorBuffer);
};
+ enum ClearOption { ClearOnlyMultisampledFBO, ClearAllFBOs };
+
+ // Clears out newly-allocated framebuffers (really, renderbuffers / textures).
+ void ClearNewlyAllocatedFramebuffers(ClearOption clear_option);
+
// The same as clearFramebuffers(), but leaves GL state dirty.
- void ClearFramebuffersInternal(GLbitfield clear_mask);
+ void ClearFramebuffersInternal(GLbitfield clear_mask,
+ ClearOption clear_option);
// The same as reset(), but leaves GL state dirty.
bool ResizeFramebufferInternal(const IntSize&);
@@ -399,10 +410,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool force_gpu_result);
// Helper functions to be called only by PrepareTransferableResourceInternal.
- void FinishPrepareTransferableResourceGpu(
+ bool FinishPrepareTransferableResourceGpu(
viz::TransferableResource* out_resource,
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
- void FinishPrepareTransferableResourceSoftware(
+ bool FinishPrepareTransferableResourceSoftware(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
@@ -478,6 +489,9 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
// and GPU switch
bool ReallocateMultisampleRenderbuffer(const IntSize&);
+ // Presents swap chain if swap chain is being used and contents have changed.
+ void ResolveAndPresentSwapChainIfNeeded();
+
// Weak, reset by beginDestruction.
Client* client_ = nullptr;
@@ -503,7 +517,6 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
const bool using_gpu_compositing_;
const bool using_swap_chain_;
bool has_implicit_stencil_buffer_ = false;
- bool storage_texture_supported_ = false;
// The texture target (2D or RECTANGLE) for our allocations.
GLenum texture_target_ = 0;
@@ -604,6 +617,9 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool opengl_flip_y_extension_;
+ gl::GpuPreference initial_gpu_;
+ gl::GpuPreference current_active_gpu_;
+
DISALLOW_COPY_AND_ASSIGN(DrawingBuffer);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
index f3919c90756..19d15ce32c4 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h"
#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "ui/gl/gpu_preference.h"
#include "v8/include/v8.h"
using testing::Test;
@@ -726,7 +727,7 @@ TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported) {
IntSize(10, 10), premultiplied_alpha, want_alpha_channel,
want_depth_buffer, want_stencil_buffer, want_antialiasing, preserve,
DrawingBuffer::kWebGL1, DrawingBuffer::kAllowChromiumImage,
- CanvasColorParams());
+ CanvasColorParams(), gl::GpuPreference::kHighPerformance);
// When we request a depth or a stencil buffer, we will get both.
EXPECT_EQ(cases[i].request_depth || cases[i].request_stencil,
@@ -778,7 +779,7 @@ TEST_F(DrawingBufferTest, VerifySetIsHiddenProperlyAffectsMailboxes) {
gpu::SyncToken wait_sync_token;
gl_->GenSyncTokenCHROMIUM(wait_sync_token.GetData());
- drawing_buffer_->SetIsHidden(true);
+ drawing_buffer_->SetIsInHiddenPage(true);
// m_drawingBuffer deletes resource immediately when hidden.
EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUMMock(SyncTokenEq(wait_sync_token)))
.Times(0);
@@ -796,7 +797,7 @@ TEST_F(DrawingBufferTest,
nullptr, gpu_compositing, false /* using_swap_chain */, nullptr,
too_big_size, false, false, false, false, false, DrawingBuffer::kDiscard,
DrawingBuffer::kWebGL1, DrawingBuffer::kAllowChromiumImage,
- CanvasColorParams());
+ CanvasColorParams(), gl::GpuPreference::kHighPerformance);
EXPECT_EQ(too_big_drawing_buffer, nullptr);
drawing_buffer_->BeginDestruction();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
index 1b426760742..61445894ffc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "ui/gl/gpu_preference.h"
namespace blink {
@@ -42,7 +43,9 @@ class WebGraphicsContext3DProviderForTests
std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu)
: webgpu_(std::move(webgpu)) {}
+ gpu::InterfaceBase* InterfaceBase() override { return gl_.get(); }
gpu::gles2::GLES2Interface* ContextGL() override { return gl_.get(); }
+ gpu::raster::RasterInterface* RasterInterface() override { return nullptr; }
GrContext* GetGrContext() override { return nullptr; }
gpu::webgpu::WebGPUInterface* WebGPUInterface() override {
return webgpu_.get();
@@ -328,6 +331,13 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
void DrawingBufferClientRestorePixelPackBufferBinding() override {
state_.pixel_pack_buffer_binding = saved_state_.pixel_pack_buffer_binding;
}
+ bool DrawingBufferClientUserAllocatedMultisampledRenderbuffers() override {
+ // Not unit tested yet. Tested with end-to-end tests.
+ return false;
+ }
+ void DrawingBufferClientForceLostContextWithAutoRecovery() override {
+ // Not unit tested yet. Tested with end-to-end tests.
+ }
// Testing methods.
gpu::SyncToken MostRecentlyWaitedSyncToken() const {
@@ -460,7 +470,8 @@ class DrawingBufferForTests : public DrawingBuffer {
false /* wantDepth */,
false /* wantStencil */,
DrawingBuffer::kAllowChromiumImage /* ChromiumImageUsage */,
- CanvasColorParams()),
+ CanvasColorParams(),
+ gl::GpuPreference::kHighPerformance),
live_(nullptr) {}
~DrawingBufferForTests() override {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
index ecad1895ee6..966ee2547d7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -224,8 +224,8 @@ void ImageLayerBridge::ResourceReleasedGpu(
if (image && image->IsValid()) {
DCHECK(image->IsTextureBacked());
if (token.HasData() && image->ContextProvider() &&
- image->ContextProvider()->ContextGL()) {
- image->ContextProvider()->ContextGL()->WaitSyncTokenCHROMIUM(
+ image->ContextProvider()->InterfaceBase()) {
+ image->ContextProvider()->InterfaceBase()->WaitSyncTokenCHROMIUM(
token.GetConstData());
}
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.cc
index 595db75011b..a74e9860588 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.cc
@@ -8,6 +8,7 @@
#include "base/memory/ptr_util.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/common/capabilities.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
@@ -22,14 +23,14 @@ SharedContextRateLimiter::SharedContextRateLimiter(unsigned max_pending_ticks)
if (!context_provider_)
return;
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
- if (gl && gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
- std::unique_ptr<Extensions3DUtil> extensions_util =
- Extensions3DUtil::Create(gl);
+ gpu::raster::RasterInterface* raster_interface =
+ context_provider_->RasterInterface();
+ if (raster_interface &&
+ raster_interface->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
+ const auto& gpu_capabilities = context_provider_->GetCapabilities();
// TODO(junov): when the GLES 3.0 command buffer is ready, we could use
// fenceSync instead.
- can_use_sync_queries_ =
- extensions_util->SupportsExtension("GL_CHROMIUM_sync_query");
+ can_use_sync_queries_ = gpu_capabilities.sync_query;
}
}
@@ -37,24 +38,28 @@ void SharedContextRateLimiter::Tick() {
if (!context_provider_)
return;
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
- if (!gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
+ gpu::raster::RasterInterface* raster_interface =
+ context_provider_->RasterInterface();
+ if (!raster_interface ||
+ raster_interface->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
return;
queries_.push_back(0);
if (can_use_sync_queries_) {
- gl->GenQueriesEXT(1, &queries_.back());
- gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, queries_.back());
- gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
+ raster_interface->GenQueriesEXT(1, &queries_.back());
+ raster_interface->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
+ queries_.back());
+ raster_interface->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
}
if (queries_.size() > max_pending_ticks_) {
if (can_use_sync_queries_) {
GLuint result;
- gl->GetQueryObjectuivEXT(queries_.front(), GL_QUERY_RESULT_EXT, &result);
- gl->DeleteQueriesEXT(1, &queries_.front());
+ raster_interface->GetQueryObjectuivEXT(queries_.front(),
+ GL_QUERY_RESULT_EXT, &result);
+ raster_interface->DeleteQueriesEXT(1, &queries_.front());
queries_.pop_front();
} else {
- gl->Finish();
+ raster_interface->Finish();
Reset();
}
}
@@ -64,11 +69,12 @@ void SharedContextRateLimiter::Reset() {
if (!context_provider_)
return;
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
- if (can_use_sync_queries_ && gl &&
- gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
+ gpu::raster::RasterInterface* raster_interface =
+ context_provider_->RasterInterface();
+ if (can_use_sync_queries_ && raster_interface &&
+ raster_interface->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
while (!queries_.empty()) {
- gl->DeleteQueriesEXT(1, &queries_.front());
+ raster_interface->DeleteQueriesEXT(1, &queries_.front());
queries_.pop_front();
}
} else {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h
index 3c4bbb11dea..4e62f11bc94 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/macros.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
index f3bfe43141c..c71ed146c82 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
@@ -6,6 +6,7 @@
#include "base/single_thread_task_runner.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "third_party/blink/public/platform/platform.h"
@@ -89,7 +90,7 @@ void SharedGpuContext::CreateContextProviderIfNeeded(
// thread it was made on, or else lock it.
if (context_provider_wrapper_ &&
context_provider_wrapper_->ContextProvider()
- ->ContextGL()
+ ->RasterInterface()
->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
// If the context isn't lost then |is_gpu_compositing_disabled_| state
// hasn't changed yet. RenderThreadImpl::CompositingModeFallbackToSoftware()
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
index 700e5ec82ea..08aea5a6e62 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -2823,7 +2823,8 @@ void WebGLImageConversion::ImageExtractor::ExtractImage(
image_->Data(), data_complete, ImageDecoder::kAlphaNotPremultiplied,
ImageDecoder::kDefaultBitDepth,
ignore_color_space ? ColorBehavior::Ignore()
- : ColorBehavior::TransformToSRGB()));
+ : ColorBehavior::TransformToSRGB(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny));
if (!decoder || !decoder->FrameCount())
return;
ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
index 928096a88d0..d2fd96c760f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -14,11 +14,11 @@
namespace blink {
namespace {
-viz::ResourceFormat DawnFormatToViz(DawnTextureFormat format) {
- if (format == DAWN_TEXTURE_FORMAT_BGRA8_UNORM) {
+viz::ResourceFormat WGPUFormatToViz(WGPUTextureFormat format) {
+ if (format == WGPUTextureFormat_BGRA8Unorm) {
return viz::BGRA_8888;
}
- if (format == DAWN_TEXTURE_FORMAT_RGBA8_UNORM) {
+ if (format == WGPUTextureFormat_RGBA8Unorm) {
return viz::RGBA_8888;
}
NOTREACHED();
@@ -29,12 +29,12 @@ viz::ResourceFormat DawnFormatToViz(DawnTextureFormat format) {
WebGPUSwapBufferProvider::WebGPUSwapBufferProvider(
Client* client,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
- DawnTextureUsage usage,
- DawnTextureFormat format)
+ WGPUTextureUsage usage,
+ WGPUTextureFormat format)
: dawn_control_client_(dawn_control_client),
client_(client),
usage_(usage),
- format_(DawnFormatToViz(format)) {
+ format_(WGPUFormatToViz(format)) {
// Create a layer that will be used by the canvas and will ask for a
// SharedImage each frame.
layer_ = cc::TextureLayer::CreateForMailbox(this);
@@ -85,7 +85,7 @@ void WebGPUSwapBufferProvider::Neuter() {
neutered_ = true;
}
-DawnTexture WebGPUSwapBufferProvider::GetNewTexture(DawnDevice device,
+WGPUTexture WebGPUSwapBufferProvider::GetNewTexture(WGPUDevice device,
const IntSize& size) {
DCHECK(!current_swap_buffer_ && !dawn_control_client_->IsDestroyed());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
index 5d2a86604fa..601e49b0f6c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
@@ -35,13 +35,13 @@ class PLATFORM_EXPORT WebGPUSwapBufferProvider
WebGPUSwapBufferProvider(
Client* client,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
- DawnTextureUsage usage,
- DawnTextureFormat format);
+ WGPUTextureUsage usage,
+ WGPUTextureFormat format);
~WebGPUSwapBufferProvider() override;
cc::Layer* CcLayer();
void Neuter();
- DawnTexture GetNewTexture(DawnDevice device, const IntSize& size);
+ WGPUTexture GetNewTexture(WGPUDevice device, const IntSize& size);
// cc::TextureLayerClient implementation.
bool PrepareTransferableResource(
@@ -84,7 +84,7 @@ class PLATFORM_EXPORT WebGPUSwapBufferProvider
scoped_refptr<cc::TextureLayer> layer_;
bool neutered_ = false;
- DawnTextureUsage usage_;
+ WGPUTextureUsage usage_;
uint32_t wire_texture_id_ = 0;
uint32_t wire_texture_generation_ = 0;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
index 9e99fc67743..6ff93d7e300 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
@@ -19,7 +19,7 @@ namespace {
class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub {
public:
- MOCK_METHOD1(ReserveTexture, gpu::webgpu::ReservedTexture(DawnDevice device));
+ MOCK_METHOD1(ReserveTexture, gpu::webgpu::ReservedTexture(WGPUDevice device));
// It is hard to use GMock with SyncTokens represented as GLByte*, instead we
// remember which were the last sync tokens generated or waited upon.
@@ -58,8 +58,8 @@ class WebGPUSwapBufferProviderForTests : public WebGPUSwapBufferProvider {
bool* alive,
Client* client,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
- DawnTextureUsage usage,
- DawnTextureFormat format)
+ WGPUTextureUsage usage,
+ WGPUTextureFormat format)
: WebGPUSwapBufferProvider(client, dawn_control_client, usage, format),
alive_(alive) {}
~WebGPUSwapBufferProviderForTests() override { *alive_ = false; }
@@ -84,7 +84,7 @@ class WebGPUSwapBufferProviderTest : public testing::Test {
base::MakeRefCounted<DawnControlClientHolder>(std::move(provider));
provider_ = base::MakeRefCounted<WebGPUSwapBufferProviderForTests>(
&provider_alive_, &client_, dawn_control_client_,
- DAWN_TEXTURE_USAGE_OUTPUT_ATTACHMENT, DAWN_TEXTURE_FORMAT_RGBA8_UNORM);
+ WGPUTextureUsage_OutputAttachment, WGPUTextureFormat_RGBA8Unorm);
}
scoped_refptr<DawnControlClientHolder> dawn_control_client_;
@@ -101,17 +101,17 @@ TEST_F(WebGPUSwapBufferProviderTest,
viz::TransferableResource resource1;
gpu::webgpu::ReservedTexture reservation1 = {
- reinterpret_cast<DawnTexture>(&resource1), 1, 1};
+ reinterpret_cast<WGPUTexture>(&resource1), 1, 1};
std::unique_ptr<viz::SingleReleaseCallback> release_callback1;
viz::TransferableResource resource2;
gpu::webgpu::ReservedTexture reservation2 = {
- reinterpret_cast<DawnTexture>(&resource2), 2, 2};
+ reinterpret_cast<WGPUTexture>(&resource2), 2, 2};
std::unique_ptr<viz::SingleReleaseCallback> release_callback2;
viz::TransferableResource resource3;
gpu::webgpu::ReservedTexture reservation3 = {
- reinterpret_cast<DawnTexture>(&resource3), 3, 3};
+ reinterpret_cast<WGPUTexture>(&resource3), 3, 3};
std::unique_ptr<viz::SingleReleaseCallback> release_callback3;
// Produce resources.
@@ -149,7 +149,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyResizingProperlyAffectsResources) {
viz::TransferableResource resource;
gpu::webgpu::ReservedTexture reservation = {
- reinterpret_cast<DawnTexture>(&resource), 1, 1};
+ reinterpret_cast<WGPUTexture>(&resource), 1, 1};
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
// Produce one resource of size kSize.
@@ -182,7 +182,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyInsertAndWaitSyncTokenCorrectly) {
viz::TransferableResource resource;
gpu::webgpu::ReservedTexture reservation = {
- reinterpret_cast<DawnTexture>(&resource), 1, 1};
+ reinterpret_cast<WGPUTexture>(&resource), 1, 1};
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
// Produce the first resource, check that WebGPU will wait for the creation of
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
index e599e2eda72..63b92488b08 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
@@ -102,16 +102,13 @@ void XRFrameTransport::FrameSubmit(
DrawingBuffer::Client* drawing_buffer_client,
scoped_refptr<Image> image_ref,
std::unique_ptr<viz::SingleReleaseCallback> release_callback,
- int16_t vr_frame_id,
- bool needs_copy) {
+ int16_t vr_frame_id) {
DCHECK(transport_options_);
if (transport_options_->transport_method ==
device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_TEXTURE_HANDLE) {
#if defined(OS_WIN)
- // Currently, we assume that this transport needs a copy.
- DCHECK(needs_copy);
TRACE_EVENT0("gpu", "XRFrameTransport::CopyImage");
// Update last_transfer_succeeded_ value. This should usually complete
// without waiting.
@@ -152,10 +149,6 @@ void XRFrameTransport::FrameSubmit(
} else if (transport_options_->transport_method ==
device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_MAILBOX_HOLDER) {
- // Currently, this transport assumes we don't need to make a separate copy
- // of the canvas content.
- DCHECK(!needs_copy);
-
// The AcceleratedStaticBitmapImage must be kept alive until the
// mailbox is used via createAndConsumeTextureCHROMIUM, the mailbox
// itself does not keep it alive. We must keep a reference to the
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
index 4bd102781f0..f0fa0523692 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
@@ -53,8 +53,7 @@ class PLATFORM_EXPORT XRFrameTransport final
DrawingBuffer::Client*,
scoped_refptr<Image> image_ref,
std::unique_ptr<viz::SingleReleaseCallback>,
- int16_t vr_frame_id,
- bool needs_copy);
+ int16_t vr_frame_id);
void FrameSubmitMissing(device::mojom::blink::XRPresentationProvider*,
gpu::gles2::GLES2Interface*,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
index 6450da3e30e..f4660896cee 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -213,12 +214,6 @@ bool XRWebGLDrawingBuffer::Initialize(const IntSize& size,
if (extensions_util->SupportsExtension(
"GL_EXT_multisampled_render_to_texture")) {
anti_aliasing_mode_ = kMSAAImplicitResolve;
- } else if (extensions_util->SupportsExtension(
- "GL_CHROMIUM_screen_space_antialiasing") &&
- drawing_buffer_->ContextProvider()
- ->GetGpuFeatureInfo()
- .IsWorkaroundEnabled(gpu::USE_FRAMEBUFFER_CMAA)) {
- anti_aliasing_mode_ = kScreenSpaceAntialiasing;
}
}
DVLOG(2) << __FUNCTION__
@@ -254,7 +249,8 @@ void XRWebGLDrawingBuffer::SetMirrorClient(scoped_refptr<MirrorClient> client) {
// it has content to show.
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(1, 1);
mirror_client_->OnMirrorImageAvailable(
- StaticBitmapImage::Create(surface->makeImageSnapshot()), nullptr);
+ UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot()),
+ nullptr);
}
}
@@ -575,12 +571,7 @@ void XRWebGLDrawingBuffer::BindAndResolveDestinationFramebuffer() {
client->DrawingBufferClientRestoreScissorTest();
} else {
gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
- if (anti_aliasing_mode_ == kScreenSpaceAntialiasing) {
- DVLOG(3) << __FUNCTION__ << ": screen space antialiasing";
- gl->ApplyScreenSpaceAntialiasingCHROMIUM();
- } else {
- DVLOG(3) << __FUNCTION__ << ": nothing to do";
- }
+ DVLOG(3) << __FUNCTION__ << ": nothing to do";
}
// On exit, leaves the destination framebuffer active. Caller is responsible
@@ -664,7 +655,7 @@ XRWebGLDrawingBuffer::TransferToStaticBitmapImage(
// context gets lost.
sk_sp<SkSurface> surface =
SkSurface::MakeRasterN32Premul(size_.Width(), size_.Height());
- return StaticBitmapImage::Create(surface->makeImageSnapshot());
+ return UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot());
}
// This holds a ref on the XRWebGLDrawingBuffer that will keep it alive
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
index 6727432172c..44649d80dd6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
@@ -139,8 +139,8 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
const GLuint framebuffer_ = 0;
GLuint resolved_framebuffer_ = 0;
GLuint multisample_renderbuffer_ = 0;
- scoped_refptr<ColorBuffer> back_color_buffer_ = 0;
- scoped_refptr<ColorBuffer> front_color_buffer_ = 0;
+ scoped_refptr<ColorBuffer> back_color_buffer_;
+ scoped_refptr<ColorBuffer> front_color_buffer_;
GLuint depth_stencil_buffer_ = 0;
IntSize size_;
@@ -167,7 +167,6 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
kNone,
kMSAAImplicitResolve,
kMSAAExplicitResolve,
- kScreenSpaceAntialiasing,
};
AntialiasingMode anti_aliasing_mode_ = kNone;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
index ee1ce96db8d..3bf0b074a5b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -306,6 +306,8 @@ void GraphicsContext::BeginRecording(const FloatRect& bounds) {
canvas_ = paint_recorder_.beginRecording(bounds);
if (metafile_)
canvas_->SetPrintingMetafile(metafile_);
+ if (tracker_)
+ canvas_->SetPaintPreviewTracker(tracker_);
}
namespace {
@@ -1038,24 +1040,24 @@ void GraphicsContext::DrawImageTiled(Image* image,
paint_controller_.SetImagePainted();
}
-void GraphicsContext::DrawOval(const SkRect& oval, const PaintFlags& flags) {
+void GraphicsContext::DrawOval(const SkRect& oval,
+ const PaintFlags& flags,
+ const DarkModeFilter::ElementRole role) {
if (ContextDisabled())
return;
DCHECK(canvas_);
- canvas_->drawOval(
- oval,
- DarkModeFlags(this, flags, DarkModeFilter::ElementRole::kBackground));
+ canvas_->drawOval(oval, DarkModeFlags(this, flags, role));
}
-void GraphicsContext::DrawPath(const SkPath& path, const PaintFlags& flags) {
+void GraphicsContext::DrawPath(const SkPath& path,
+ const PaintFlags& flags,
+ const DarkModeFilter::ElementRole role) {
if (ContextDisabled())
return;
DCHECK(canvas_);
- canvas_->drawPath(
- path,
- DarkModeFlags(this, flags, DarkModeFilter::ElementRole::kBackground));
+ canvas_->drawPath(path, DarkModeFlags(this, flags, role));
}
void GraphicsContext::DrawRect(const SkRect& rect,
@@ -1374,7 +1376,7 @@ void GraphicsContext::SetURLForRect(const KURL& link,
// Intercept URL rects when painting previews.
if (IsPaintingPreview() && tracker_) {
- tracker_->AnnotateLink(link.GetString().Utf8(), dest_rect);
+ tracker_->AnnotateLink(GURL(link), dest_rect);
return;
}
@@ -1391,7 +1393,7 @@ void GraphicsContext::SetURLFragmentForRect(const String& dest_name,
// Intercept URL rects when painting previews.
if (IsPaintingPreview() && tracker_) {
- tracker_->AnnotateLink(dest_name.Utf8(), rect);
+ tracker_->AnnotateLink(GURL(dest_name.Utf8()), rect);
return;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
index 5a42e8103ab..b33ed07b357 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -262,8 +262,14 @@ class PLATFORM_EXPORT GraphicsContext {
// These methods write to the canvas.
// Also drawLine(const IntPoint& point1, const IntPoint& point2) and
// fillRoundedRect().
- void DrawOval(const SkRect&, const PaintFlags&);
- void DrawPath(const SkPath&, const PaintFlags&);
+ void DrawOval(const SkRect&,
+ const PaintFlags&,
+ const DarkModeFilter::ElementRole role =
+ DarkModeFilter::ElementRole::kBackground);
+ void DrawPath(const SkPath&,
+ const PaintFlags&,
+ const DarkModeFilter::ElementRole role =
+ DarkModeFilter::ElementRole::kBackground);
void DrawRect(const SkRect&,
const PaintFlags&,
const DarkModeFilter::ElementRole role =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
index 211e3db2d05..7f39c9e8911 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -42,6 +42,7 @@
#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
+#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/geometry/region.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
@@ -88,14 +89,12 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
layer_ = cc::PictureLayer::Create(this);
CcLayer()->SetIsDrawable(draws_content_ && contents_visible_);
CcLayer()->SetHitTestable(hit_testable_);
- CcLayer()->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
UpdateTrackingRasterInvalidations();
}
GraphicsLayer::~GraphicsLayer() {
CcLayer()->ClearClient();
- CcLayer()->SetLayerClient(nullptr);
SetContentsLayer(nullptr);
#if DCHECK_IS_ON()
@@ -117,21 +116,67 @@ IntRect GraphicsLayer::VisualRect() const {
return IntRect(layer_state_->offset, IntSize(Size()));
}
-void GraphicsLayer::SetHasWillChangeTransformHint(
- bool has_will_change_transform) {
- CcLayer()->SetHasWillChangeTransformHint(has_will_change_transform);
-}
+void GraphicsLayer::AppendAdditionalInfoAsJSON(LayerTreeFlags flags,
+ const cc::Layer& layer,
+ JSONObject& json) const {
+ // Only the primary layer associated with GraphicsLayer adds additional
+ // information. Other layer state, such as raster invalidations, don't
+ // disambiguate between specific layers.
+ if (&layer != layer_.get())
+ return;
-void GraphicsLayer::SetCompositingReasons(CompositingReasons reasons) {
- CcLayer()->set_compositing_reasons(reasons);
-}
+ if ((flags & kLayerTreeIncludesPaintInvalidations) &&
+ Client().IsTrackingRasterInvalidations() &&
+ GetRasterInvalidationTracking()) {
+ GetRasterInvalidationTracking()->AsJSON(&json);
+ }
+
+ GraphicsLayerPaintingPhase painting_phase = PaintingPhase();
+ if ((flags & kLayerTreeIncludesPaintingPhases) && painting_phase) {
+ auto painting_phases_json = std::make_unique<JSONArray>();
+ if (painting_phase & kGraphicsLayerPaintBackground)
+ painting_phases_json->PushString("GraphicsLayerPaintBackground");
+ if (painting_phase & kGraphicsLayerPaintForeground)
+ painting_phases_json->PushString("GraphicsLayerPaintForeground");
+ if (painting_phase & kGraphicsLayerPaintMask)
+ painting_phases_json->PushString("GraphicsLayerPaintMask");
+ if (painting_phase & kGraphicsLayerPaintOverflowContents)
+ painting_phases_json->PushString("GraphicsLayerPaintOverflowContents");
+ if (painting_phase & kGraphicsLayerPaintCompositedScroll)
+ painting_phases_json->PushString("GraphicsLayerPaintCompositedScroll");
+ if (painting_phase & kGraphicsLayerPaintDecoration)
+ painting_phases_json->PushString("GraphicsLayerPaintDecoration");
+ json.SetArray("paintingPhases", std::move(painting_phases_json));
+ }
+
+ if (flags &
+ (kLayerTreeIncludesDebugInfo | kLayerTreeIncludesCompositingReasons)) {
+ bool debug = flags & kLayerTreeIncludesDebugInfo;
+ {
+ auto squashing_disallowed_reasons_json = std::make_unique<JSONArray>();
+ SquashingDisallowedReasons squashing_disallowed_reasons =
+ GetSquashingDisallowedReasons();
+ auto names = debug ? SquashingDisallowedReason::Descriptions(
+ squashing_disallowed_reasons)
+ : SquashingDisallowedReason::ShortNames(
+ squashing_disallowed_reasons);
+ for (const char* name : names)
+ squashing_disallowed_reasons_json->PushString(name);
+ json.SetArray("squashingDisallowedReasons",
+ std::move(squashing_disallowed_reasons_json));
+ }
+ }
-CompositingReasons GraphicsLayer::GetCompositingReasons() const {
- return CcLayer()->compositing_reasons();
+#if DCHECK_IS_ON()
+ if (HasLayerState() && DrawsContent() &&
+ (flags & kLayerTreeIncludesPaintRecords))
+ json.SetValue("paintRecord", RecordAsJSON(*CapturePaintRecord()));
+#endif
}
-void GraphicsLayer::SetOwnerNodeId(int node_id) {
- CcLayer()->set_owner_node_id(node_id);
+void GraphicsLayer::SetHasWillChangeTransformHint(
+ bool has_will_change_transform) {
+ CcLayer()->SetHasWillChangeTransformHint(has_will_change_transform);
}
void GraphicsLayer::SetParent(GraphicsLayer* layer) {
@@ -418,7 +463,6 @@ void GraphicsLayer::UnregisterContentsLayer(cc::Layer* layer) {
DCHECK(g_registered_layer_set);
CHECK(g_registered_layer_set->Contains(layer->id()));
g_registered_layer_set->erase(layer->id());
- layer->SetLayerClient(nullptr);
}
void GraphicsLayer::SetContentsTo(cc::Layer* layer,
@@ -469,17 +513,11 @@ void GraphicsLayer::ClearContentsLayerIfUnregistered() {
}
void GraphicsLayer::SetContentsLayer(cc::Layer* contents_layer) {
- // If we have a previous contents layer which is still registered, then unset
- // this client pointer. If unregistered, it has already nulled out the client
- // pointer and may have been deleted.
- if (contents_layer_ && g_registered_layer_set->Contains(contents_layer_id_))
- contents_layer_->SetLayerClient(nullptr);
contents_layer_ = contents_layer;
if (!contents_layer_) {
contents_layer_id_ = 0;
return;
}
- contents_layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
contents_layer_id_ = contents_layer_->id();
}
@@ -547,14 +585,6 @@ String GraphicsLayer::DebugName(const cc::Layer* layer) const {
return "";
}
-void GraphicsLayer::SetPosition(const gfx::PointF& point) {
- CcLayer()->SetPosition(point);
-}
-
-const gfx::PointF& GraphicsLayer::GetPosition() const {
- return CcLayer()->position();
-}
-
const gfx::Size& GraphicsLayer::Size() const {
return CcLayer()->bounds();
}
@@ -670,13 +700,6 @@ void GraphicsLayer::SetNeedsDisplay() {
PaintInvalidationReason::kFullLayer);
}
-void GraphicsLayer::SetNeedsDisplayRecursively() {
- for (auto* child : children_) {
- child->SetNeedsDisplayRecursively();
- }
- SetNeedsDisplay();
-}
-
void GraphicsLayer::SetNeedsDisplayInRect(const IntRect& rect) {
DCHECK(PaintsContentOrHitTest());
CcLayer()->SetNeedsDisplayRect(rect);
@@ -726,7 +749,6 @@ void GraphicsLayer::SetContentsToImage(
.TakePaintImage();
if (!image_layer_) {
image_layer_ = cc::PictureImageLayer::Create();
- image_layer_->set_owner_node_id(CcLayer()->owner_node_id());
RegisterContentsLayer(image_layer_.get());
}
image_layer_->SetImage(std::move(paint_image), matrix,
@@ -759,43 +781,6 @@ void GraphicsLayer::SetPaintingPhase(GraphicsLayerPaintingPhase phase) {
SetNeedsDisplay();
}
-std::unique_ptr<base::trace_event::TracedValue> GraphicsLayer::TakeDebugInfo(
- const cc::Layer* layer) {
- auto traced_value = std::make_unique<base::trace_event::TracedValue>();
-
- traced_value->SetString("layer_name", LayerDebugName(layer));
-
- traced_value->BeginArray("compositing_reasons");
- for (const char* description :
- CompositingReason::Descriptions(GetCompositingReasons()))
- traced_value->AppendString(description);
- traced_value->EndArray();
-
- traced_value->BeginArray("squashing_disallowed_reasons");
- for (const char* description :
- SquashingDisallowedReason::Descriptions(squashing_disallowed_reasons_))
- traced_value->AppendString(description);
- traced_value->EndArray();
-
- if (auto node_id = layer_->owner_node_id())
- traced_value->SetInteger("owner_node", node_id);
-
- if (auto* tracking = GetRasterInvalidationTracking()) {
- tracking->AddToTracedValue(*traced_value);
- tracking->ClearInvalidations();
- }
-
- return traced_value;
-}
-
-std::string GraphicsLayer::LayerDebugName(const cc::Layer* layer) const {
- return DebugName(layer).Utf8();
-}
-
-void GraphicsLayer::DidChangeScrollbarsHiddenIfOverlay(bool hidden) {
- client_.SetOverlayScrollbarsHidden(hidden);
-}
-
PaintController& GraphicsLayer::GetPaintController() const {
CHECK(PaintsContentOrHitTest());
if (!paint_controller_)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
index c4868211288..269eb43a3ef 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -30,16 +30,15 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
#include "cc/input/scroll_snap_data.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
-#include "cc/layers/layer_client.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
@@ -73,8 +72,8 @@ typedef Vector<GraphicsLayer*, 64> GraphicsLayerVector;
// GraphicsLayer is an abstraction for a rendering surface with backing store,
// which may have associated transformation and animations.
-class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
- public DisplayItemClient,
+class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
+ public LayerAsJSONClient,
private cc::ContentLayerClient {
USING_FAST_MALLOC(GraphicsLayer);
@@ -84,8 +83,12 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
GraphicsLayerClient& Client() const { return client_; }
- void SetCompositingReasons(CompositingReasons reasons);
- CompositingReasons GetCompositingReasons() const;
+ void SetCompositingReasons(CompositingReasons reasons) {
+ compositing_reasons_ = reasons;
+ }
+ CompositingReasons GetCompositingReasons() const {
+ return compositing_reasons_;
+ }
SquashingDisallowedReasons GetSquashingDisallowedReasons() const {
return squashing_disallowed_reasons_;
@@ -94,7 +97,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
squashing_disallowed_reasons_ = reasons;
}
- void SetOwnerNodeId(int id);
+ void SetOwnerNodeId(DOMNodeId id) { owner_node_id_ = id; }
GraphicsLayer* Parent() const { return parent_; }
void SetParent(GraphicsLayer*); // Internal use only.
@@ -118,11 +121,6 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
IntSize OffsetFromLayoutObject() const { return offset_from_layout_object_; }
void SetOffsetFromLayoutObject(const IntSize&);
- // The position of the layer (the location of its top-left corner in its
- // parent).
- const gfx::PointF& GetPosition() const;
- void SetPosition(const gfx::PointF&);
-
// The size of the layer.
const gfx::Size& Size() const;
void SetSize(const gfx::Size&);
@@ -170,7 +168,6 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
void SetPaintingPhase(GraphicsLayerPaintingPhase);
void SetNeedsDisplay();
- void SetNeedsDisplayRecursively();
void SetContentsNeedsDisplay();
// Set that the position/size of the contents (image or video).
@@ -199,11 +196,6 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
// For hosting this GraphicsLayer in a native layer hierarchy.
cc::PictureLayer* CcLayer() const;
- // Return a string with a human readable form of the layer tree. If debug is
- // true, pointers for the layers and timing data will be included in the
- // returned string.
- String GetLayerTreeAsTextForTesting(LayerTreeFlags = kLayerTreeNormal) const;
-
void UpdateTrackingRasterInvalidations();
void ResetTrackedRasterInvalidations();
bool HasTrackedRasterInvalidations() const;
@@ -220,12 +212,6 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
// Returns true if this layer is repainted.
bool Paint(GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled);
- // cc::LayerClient implementation.
- std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
- const cc::Layer*) override;
- std::string LayerDebugName(const cc::Layer*) const override;
- void DidChangeScrollbarsHiddenIfOverlay(bool) override;
-
PaintController& GetPaintController() const;
void SetElementId(const CompositorElementId&);
@@ -233,6 +219,12 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
// DisplayItemClient methods
String DebugName() const final { return client_.DebugName(this); }
IntRect VisualRect() const override;
+ DOMNodeId OwnerNodeId() const final { return owner_node_id_; }
+
+ // LayerAsJSONClient implementation.
+ void AppendAdditionalInfoAsJSON(LayerTreeFlags,
+ const cc::Layer&,
+ JSONObject&) const override;
void SetHasWillChangeTransformHint(bool);
@@ -364,7 +356,8 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
std::unique_ptr<RasterInvalidator> raster_invalidator_;
- base::WeakPtrFactory<GraphicsLayer> weak_ptr_factory_{this};
+ DOMNodeId owner_node_id_ = kInvalidDOMNodeId;
+ CompositingReasons compositing_reasons_ = CompositingReason::kNone;
FRIEND_TEST_ALL_PREFIXES(CompositingLayerPropertyUpdaterTest, MaskLayerState);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
index 65645d0f3c8..091a8e66c36 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
@@ -50,23 +50,6 @@ enum GraphicsLayerPaintingPhaseFlags {
};
typedef unsigned GraphicsLayerPaintingPhase;
-// These values need to be kept consistent with the layer tree flags in
-// core/testing/Internals.idl.
-enum {
- kLayerTreeNormal = 0,
- // Dump extra debugging info like layer addresses.
- kLayerTreeIncludesDebugInfo = 1 << 0,
- kLayerTreeIncludesPaintInvalidations = 1 << 1,
- kLayerTreeIncludesPaintingPhases = 1 << 2,
- kLayerTreeIncludesRootLayer = 1 << 3,
- kLayerTreeIncludesCompositingReasons = 1 << 5,
- kLayerTreeIncludesPaintRecords = 1 << 6,
- // Outputs all layers as a layer tree. The default is output children
- // (excluding the root) as a layer list, in paint (preorder) order.
- kOutputAsLayerTree = 0x4000,
-};
-typedef unsigned LayerTreeFlags;
-
enum class DisplayLockContextLifecycleTarget { kSelf, kChildren };
class PLATFORM_EXPORT GraphicsLayerClient {
@@ -97,8 +80,6 @@ class PLATFORM_EXPORT GraphicsLayerClient {
virtual bool IsTrackingRasterInvalidations() const { return false; }
- virtual void SetOverlayScrollbarsHidden(bool) {}
-
virtual void GraphicsLayersDidChange() {}
virtual String DebugName(const GraphicsLayer*) const = 0;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
index c230eb535d2..e1c3148b159 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
@@ -146,23 +146,6 @@ TEST_P(GraphicsLayerTest, SetDrawsContentFalse) {
EXPECT_EQ(nullptr, GetInternalRasterInvalidator(layers_.graphics_layer()));
}
-TEST_P(GraphicsLayerTest, CcLayerClient) {
- auto graphics_layer =
- std::make_unique<FakeGraphicsLayer>(layers_.graphics_layer_client());
- graphics_layer->SetDrawsContent(true);
- scoped_refptr<cc::PictureLayer> cc_layer = graphics_layer->CcLayer();
- ASSERT_TRUE(cc_layer);
- EXPECT_TRUE(cc_layer->DrawsContent());
- EXPECT_TRUE(cc_layer->client());
- EXPECT_TRUE(cc_layer->GetLayerClientForTesting());
-
- graphics_layer.reset();
- EXPECT_FALSE(cc_layer->DrawsContent());
- EXPECT_FALSE(cc_layer->client());
- EXPECT_FALSE(cc_layer->GetLayerClientForTesting());
- EXPECT_FALSE(cc_layer->GetPicture());
-}
-
TEST_P(GraphicsLayerTest, ContentsLayer) {
auto& graphics_layer = layers_.graphics_layer();
auto contents_layer = cc::Layer::Create();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
index 425cd594c29..237d6c5ac94 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
@@ -197,8 +197,8 @@ enum ColorFilter {
};
enum WindRule {
- RULE_NONZERO = SkPath::kWinding_FillType,
- RULE_EVENODD = SkPath::kEvenOdd_FillType
+ RULE_NONZERO = static_cast<int>(SkPathFillType::kWinding),
+ RULE_EVENODD = static_cast<int>(SkPathFillType::kEvenOdd)
};
PLATFORM_EXPORT String CompositeOperatorName(CompositeOperator, BlendMode);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
index 8e1255ce43b..fe622fba3ae 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
@@ -34,6 +34,7 @@
#include <memory>
+#include "base/compiler_specific.h"
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
@@ -78,10 +79,12 @@ ImageDataBuffer::ImageDataBuffer(scoped_refptr<StaticBitmapImage> image) {
pixmap_.reset();
return;
}
+ MSAN_CHECK_MEM_IS_INITIALIZED(pixmap_.addr(), pixmap_.computeByteSize());
retained_image_ = SkImage::MakeRasterData(info, std::move(data), rowBytes);
} else {
if (!retained_image_->peekPixels(&pixmap_))
return;
+ MSAN_CHECK_MEM_IS_INITIALIZED(pixmap_.addr(), pixmap_.computeByteSize());
}
is_valid_ = true;
size_ = IntSize(image->width(), image->height());
@@ -161,7 +164,9 @@ String ImageDataBuffer::ToDataURL(const ImageEncodingMimeType mime_type,
if (!pixmap.colorSpace()->isSRGB()) {
skia_image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
skia_image = skia_image->makeColorSpace(SkColorSpace::MakeSRGB());
- skia_image->peekPixels(&pixmap);
+ if (!skia_image->peekPixels(&pixmap))
+ return "data:,";
+ MSAN_CHECK_MEM_IS_INITIALIZED(pixmap.addr(), pixmap.computeByteSize());
}
pixmap.setColorSpace(nullptr);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
index 286625bf260..37f8263c8b7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
@@ -37,7 +37,6 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_clamped_array.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkRefCnt.h"
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
index 3b8f379a84d..5a6dab40814 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
@@ -287,6 +287,7 @@ std::unique_ptr<ImageDecoder> ImageDecoderWrapper::CreateDecoderWithData(
// The newly created decoder just grabbed the data. No need to reset it.
return ImageDecoder::Create(data_, all_data_received_, alpha_option_,
decoding_option_, decoder_color_behavior_,
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny,
scaled_size_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
index 0deed330d80..93cf3c72bd8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
@@ -236,12 +236,6 @@ bool ImageFrameGenerator::GetYUVComponentSizes(
ImageDecoder::kDefaultBitDepth, decoder_color_behavior_);
DCHECK(decoder);
- // Setting a dummy ImagePlanes object signals to the decoder that we want to
- // do YUV decoding.
- std::unique_ptr<ImagePlanes> dummy_image_planes =
- std::make_unique<ImagePlanes>();
- decoder->SetImagePlanes(std::move(dummy_image_planes));
-
DCHECK(decoder->CanDecodeToYUV());
*yuv_color_space = decoder->GetYUVColorSpace();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
index 1b88db47358..51156fdccc9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
@@ -267,7 +267,7 @@ TEST_F(ImageFrameGeneratorTest,
SetFrameStatus(ImageFrame::kFrameComplete);
AddNewData();
std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("DecodeThread"));
PostCrossThreadTask(
*thread->GetTaskRunner(), FROM_HERE,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
index 2e8405e2056..b22ea1d9e6d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
@@ -169,15 +169,15 @@ std::unique_ptr<JSONObject> ObjectForSkRRect(const SkRRect& rrect) {
return rrect_item;
}
-String FillTypeName(SkPath::FillType type) {
+String FillTypeName(SkPathFillType type) {
switch (type) {
- case SkPath::kWinding_FillType:
+ case SkPathFillType::kWinding:
return "Winding";
- case SkPath::kEvenOdd_FillType:
+ case SkPathFillType::kEvenOdd:
return "EvenOdd";
- case SkPath::kInverseWinding_FillType:
+ case SkPathFillType::kInverseWinding:
return "InverseWinding";
- case SkPath::kInverseEvenOdd_FillType:
+ case SkPathFillType::kInverseEvenOdd:
return "InverseEvenOdd";
default:
NOTREACHED();
@@ -185,13 +185,13 @@ String FillTypeName(SkPath::FillType type) {
};
}
-String ConvexityName(SkPath::Convexity convexity) {
+String ConvexityName(SkPathConvexityType convexity) {
switch (convexity) {
- case SkPath::kUnknown_Convexity:
+ case SkPathConvexityType::kUnknown:
return "Unknown";
- case SkPath::kConvex_Convexity:
+ case SkPathConvexityType::kConvex:
return "Convex";
- case SkPath::kConcave_Convexity:
+ case SkPathConvexityType::kConcave:
return "Concave";
default:
NOTREACHED();
@@ -224,13 +224,13 @@ VerbParams SegmentParams(SkPath::Verb verb) {
std::unique_ptr<JSONObject> ObjectForSkPath(const SkPath& path) {
auto path_item = std::make_unique<JSONObject>();
path_item->SetString("fillType", FillTypeName(path.getFillType()));
- path_item->SetString("convexity", ConvexityName(path.getConvexity()));
+ path_item->SetString("convexity", ConvexityName(path.getConvexityType()));
path_item->SetBoolean("isRect", path.isRect(nullptr));
SkPath::Iter iter(path, false);
SkPoint points[4];
auto path_points_array = std::make_unique<JSONArray>();
- for (SkPath::Verb verb = iter.next(points, false); verb != SkPath::kDone_Verb;
- verb = iter.next(points, false)) {
+ for (SkPath::Verb verb = iter.next(points); verb != SkPath::kDone_Verb;
+ verb = iter.next(points)) {
VerbParams verb_params = SegmentParams(verb);
auto path_point_item = std::make_unique<JSONObject>();
path_point_item->SetString("verb", verb_params.name);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
index 84dbe25076e..87831e86f1f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
@@ -17,7 +17,6 @@ namespace {
typedef HashMap<int, blink::OffscreenCanvasPlaceholder*> PlaceholderIdMap;
PlaceholderIdMap& placeholderRegistry() {
- DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(PlaceholderIdMap, s_placeholderRegistry, ());
return s_placeholderRegistry;
}
@@ -40,6 +39,14 @@ void SetSuspendAnimation(
}
}
+void UpdateDispatcherFilterQuality(
+ base::WeakPtr<blink::CanvasResourceDispatcher> dispatcher,
+ SkFilterQuality filter) {
+ if (dispatcher) {
+ dispatcher->SetFilterQuality(filter);
+ }
+}
+
} // unnamed namespace
namespace blink {
@@ -48,17 +55,13 @@ OffscreenCanvasPlaceholder::~OffscreenCanvasPlaceholder() {
UnregisterPlaceholderCanvas();
}
-void OffscreenCanvasPlaceholder::SetOffscreenCanvasFrame(
+void OffscreenCanvasPlaceholder::SetOffscreenCanvasResource(
scoped_refptr<CanvasResource> new_frame,
- base::WeakPtr<CanvasResourceDispatcher> dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
viz::ResourceId resource_id) {
DCHECK(IsOffscreenCanvasRegistered());
DCHECK(new_frame);
ReleaseOffscreenCanvasFrame();
placeholder_frame_ = std::move(new_frame);
- frame_dispatcher_ = std::move(dispatcher);
- frame_dispatcher_task_runner_ = std::move(task_runner);
placeholder_frame_resource_id_ = resource_id;
if (animation_state_ == kShouldSuspendAnimation) {
@@ -72,16 +75,56 @@ void OffscreenCanvasPlaceholder::SetOffscreenCanvasFrame(
}
}
+void OffscreenCanvasPlaceholder::SetOffscreenCanvasDispatcher(
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ DCHECK(IsOffscreenCanvasRegistered());
+ frame_dispatcher_ = std::move(dispatcher);
+ frame_dispatcher_task_runner_ = std::move(task_runner);
+ // The UpdateOffscreenCanvasFilterQuality could be called to change the filter
+ // quality before this function. We need to first apply the filter changes to
+ // the corresponding offscreen canvas.
+ if (filter_quality_) {
+ SkFilterQuality quality = filter_quality_.value();
+ filter_quality_ = base::nullopt;
+ UpdateOffscreenCanvasFilterQuality(quality);
+ }
+}
+
void OffscreenCanvasPlaceholder::ReleaseOffscreenCanvasFrame() {
DCHECK(IsOffscreenCanvasRegistered());
- if (placeholder_frame_) {
- DCHECK(frame_dispatcher_task_runner_);
- placeholder_frame_->Transfer();
+ if (!placeholder_frame_)
+ return;
+
+ DCHECK(frame_dispatcher_task_runner_);
+ placeholder_frame_->Transfer();
+ PostCrossThreadTask(
+ *frame_dispatcher_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(releaseFrameToDispatcher, frame_dispatcher_,
+ std::move(placeholder_frame_),
+ placeholder_frame_resource_id_));
+}
+
+void OffscreenCanvasPlaceholder::UpdateOffscreenCanvasFilterQuality(
+ SkFilterQuality filter_quality) {
+ DCHECK(IsOffscreenCanvasRegistered());
+ if (!frame_dispatcher_task_runner_) {
+ filter_quality_ = filter_quality;
+ return;
+ }
+
+ if (filter_quality_ == filter_quality)
+ return;
+
+ filter_quality_ = filter_quality;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ Thread::Current()->GetTaskRunner();
+ if (task_runner == frame_dispatcher_task_runner_) {
+ UpdateDispatcherFilterQuality(frame_dispatcher_, filter_quality);
+ } else {
PostCrossThreadTask(*frame_dispatcher_task_runner_, FROM_HERE,
- CrossThreadBindOnce(releaseFrameToDispatcher,
- std::move(frame_dispatcher_),
- std::move(placeholder_frame_),
- placeholder_frame_resource_id_));
+ CrossThreadBindOnce(UpdateDispatcherFilterQuality,
+ frame_dispatcher_, filter_quality));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
index dc91d6cbd9f..c21fdd436b1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
@@ -12,6 +12,7 @@
#include "components/viz/common/resources/resource_id.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/skia/include/core/SkFilterQuality.h"
namespace blink {
@@ -24,11 +25,12 @@ class PLATFORM_EXPORT OffscreenCanvasPlaceholder {
public:
~OffscreenCanvasPlaceholder();
- virtual void SetOffscreenCanvasFrame(
- scoped_refptr<CanvasResource>,
+ virtual void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>,
+ viz::ResourceId resource_id);
+ void SetOffscreenCanvasDispatcher(
base::WeakPtr<CanvasResourceDispatcher>,
- scoped_refptr<base::SingleThreadTaskRunner>,
- viz::ResourceId resource_id);
+ scoped_refptr<base::SingleThreadTaskRunner>);
+
void ReleaseOffscreenCanvasFrame();
void SetSuspendOffscreenCanvasAnimation(bool);
@@ -46,6 +48,8 @@ class PLATFORM_EXPORT OffscreenCanvasPlaceholder {
return placeholder_id_ != kNoPlaceholderId;
}
+ void UpdateOffscreenCanvasFilterQuality(SkFilterQuality filter_quality);
+
private:
bool PostSetSuspendAnimationToOffscreenCanvasThread(bool suspend);
@@ -67,6 +71,7 @@ class PLATFORM_EXPORT OffscreenCanvasPlaceholder {
kShouldActivateAnimation,
};
AnimationState animation_state_ = kActiveAnimation;
+ base::Optional<SkFilterQuality> filter_quality_ = base::nullopt;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
index 68fd14fc54b..acfc8a40fa0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -63,22 +63,29 @@ static void MapRect(const TransformPaintPropertyNode& transform,
}
CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
- const TransformPaintPropertyNode& transform) {
+ const TransformPaintPropertyNode& transform,
+ bool clip_to_scroll_container) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (const auto* scroll = transform.ScrollNode()) {
- rect_.Intersect(scroll->ContainerRect());
- if (rect_.IsEmpty())
- return kNotExpanded;
+ if (clip_to_scroll_container) {
+ rect_.Intersect(scroll->ContainerRect());
+ if (rect_.IsEmpty())
+ return kNotExpanded;
+ }
+
MapRect(transform, rect_);
- // Expand the cull rect for scrolling contents in case of composited
- // scrolling.
- // TODO(wangxianzhu): options for non-composited-scrolling contents:
- // 1. to use non-composted-scrolling heuristics to avoid expansion;
- // 2. to reduce the 4000px distance, no matter if the contents with be
- // composited scrolling.
- // 3. mixed method of 1 and 2, e.g. the distance could be a function of
- // confidence that the contents will be composited scrolling.
+ // Don't expand for non-composited scrolling.
+ if (!transform.HasDirectCompositingReasons())
+ return kNotExpanded;
+
+ // We create scroll node for the root scroller even it's not scrollable.
+ // Don't expand in the case.
+ if (scroll->ContainerRect().Width() >= scroll->ContentsSize().Width() &&
+ scroll->ContainerRect().Height() >= scroll->ContentsSize().Height())
+ return kNotExpanded;
+
+ // Expand the cull rect for scrolling contents for composited scrolling.
static const int kPixelDistanceToExpand = 4000;
rect_.Inflate(kPixelDistanceToExpand);
// Don't clip the cull rect by contents size to let ChangedEnough() work
@@ -96,7 +103,8 @@ CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
- const base::Optional<CullRect>& old_cull_rect) {
+ const base::Optional<CullRect>& old_cull_rect,
+ bool clip_to_scroll_container) {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
Vector<const TransformPaintPropertyNode*> scroll_translations;
@@ -122,7 +130,7 @@ void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
*last_transform, *scroll_translation->Parent(), rect_);
}
last_scroll_translation_result =
- ApplyTransformInternal(*scroll_translation);
+ ApplyTransformInternal(*scroll_translation, clip_to_scroll_container);
last_transform = scroll_translation;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
index 1a67ba81e10..8b4fade8326 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
@@ -45,7 +45,8 @@ class PLATFORM_EXPORT CullRect {
// the cull rect is in the space of the parent the transform node.
// For CompositeAfterPaint, when the transform is a scroll translation, the
// cull rect is converted in the following steps:
- // 1. it's clipped by the container rect,
+ // 1. it's clipped by the container rect if |clip_to_scroll_container| is
+ // true,
// 2. transformed by inverse of the scroll translation,
// 3. expanded by thousands of pixels for composited scrolling.
void ApplyTransform(const TransformPaintPropertyNode& transform) {
@@ -61,7 +62,8 @@ class PLATFORM_EXPORT CullRect {
// will be set to |old_cull_rect| to avoid repaint on each composited scroll.
void ApplyTransforms(const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
- const base::Optional<CullRect>& old_cull_rect);
+ const base::Optional<CullRect>& old_cull_rect,
+ bool clip_to_scroll_container = true);
const IntRect& Rect() const { return rect_; }
@@ -84,7 +86,8 @@ class PLATFORM_EXPORT CullRect {
kExpandedForPartialScrollingContents,
};
ApplyTransformResult ApplyTransformInternal(
- const TransformPaintPropertyNode&);
+ const TransformPaintPropertyNode&,
+ bool clip_to_scroll_container = true);
bool ChangedEnough(const CullRect& old_cull_rect) const;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
index ecc5ee884ac..5ab03deee6a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -122,7 +122,7 @@ TEST_F(CullRectTest, ApplyScrollTranslationPartialScrollingContents) {
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
auto scroll_translation =
- CreateScrollTranslation(t0(), -3000, -5000, *scroll);
+ CreateCompositedScrollTranslation(t0(), -3000, -5000, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kExpandedForPartialScrollingContents,
@@ -141,6 +141,32 @@ TEST_F(CullRectTest, ApplyScrollTranslationPartialScrollingContents) {
EXPECT_EQ(IntRect(-980, 1010, 8040, 8050), cull_rect.Rect());
}
+TEST_F(CullRectTest,
+ ApplyNonCompositedScrollTranslationPartialScrollingContents) {
+ ScopedCompositeAfterPaintForTest cap(true);
+
+ ScrollPaintPropertyNode::State scroll_state;
+ scroll_state.container_rect = IntRect(20, 10, 40, 50);
+ scroll_state.contents_size = IntSize(8000, 8000);
+ auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
+ std::move(scroll_state));
+ auto scroll_translation =
+ CreateScrollTranslation(t0(), -3000, -5000, *scroll);
+
+ CullRect cull_rect(IntRect(0, 0, 50, 100));
+ EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
+
+ // Clipped: (20, 10, 30, 50)
+ // Inverse transformed: (3020, 5010, 30, 50)
+ EXPECT_EQ(IntRect(3020, 5010, 30, 50), cull_rect.Rect());
+
+ cull_rect = CullRect::Infinite();
+ EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
+ // This result differs from the above result in height (40 vs 30)
+ // because it's not clipped by the infinite input cull rect.
+ EXPECT_EQ(IntRect(3020, 5010, 40, 50), cull_rect.Rect());
+}
+
TEST_F(CullRectTest, ApplyScrollTranslationNoIntersectionWithContainerRect) {
ScopedCompositeAfterPaintForTest cap(true);
@@ -149,6 +175,23 @@ TEST_F(CullRectTest, ApplyScrollTranslationNoIntersectionWithContainerRect) {
scroll_state.contents_size = IntSize(2000, 2000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
+ auto scroll_translation =
+ CreateCompositedScrollTranslation(t0(), -10, -15, *scroll);
+
+ CullRect cull_rect(IntRect(0, 0, 50, 100));
+ EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
+ EXPECT_TRUE(cull_rect.Rect().IsEmpty());
+}
+
+TEST_F(CullRectTest,
+ ApplyNonCompositedScrollTranslationNoIntersectionWithContainerRect) {
+ ScopedCompositeAfterPaintForTest cap(true);
+
+ ScrollPaintPropertyNode::State scroll_state;
+ scroll_state.container_rect = IntRect(200, 100, 40, 50);
+ scroll_state.contents_size = IntSize(2000, 2000);
+ auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
+ std::move(scroll_state));
auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
@@ -164,7 +207,8 @@ TEST_F(CullRectTest, ApplyScrollTranslationWholeScrollingContents) {
scroll_state.contents_size = IntSize(2000, 2000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
- auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll);
+ auto scroll_translation =
+ CreateCompositedScrollTranslation(t0(), -10, -15, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kExpandedForWholeScrollingContents,
@@ -183,6 +227,31 @@ TEST_F(CullRectTest, ApplyScrollTranslationWholeScrollingContents) {
EXPECT_EQ(IntRect(-3970, -3975, 8040, 8050), cull_rect.Rect());
}
+TEST_F(CullRectTest,
+ ApplyNonCompositedScrollTranslationWholeScrollingContents) {
+ ScopedCompositeAfterPaintForTest cap(true);
+
+ ScrollPaintPropertyNode::State scroll_state;
+ scroll_state.container_rect = IntRect(20, 10, 40, 50);
+ scroll_state.contents_size = IntSize(2000, 2000);
+ auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
+ std::move(scroll_state));
+ auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll);
+
+ CullRect cull_rect(IntRect(0, 0, 50, 100));
+ EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
+
+ // Clipped: (20, 10, 30, 50)
+ // Inverse transformed: (30, 25, 30, 50)
+ EXPECT_EQ(IntRect(30, 25, 30, 50), cull_rect.Rect());
+
+ cull_rect = CullRect::Infinite();
+ EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
+ // This result differs from the above result in height (40 vs 30)
+ // because it's not clipped by the infinite input cull rect.
+ EXPECT_EQ(IntRect(30, 25, 40, 50), cull_rect.Rect());
+}
+
TEST_F(CullRectTest, ChangedEnoughEmpty) {
ScopedCompositeAfterPaintForTest cap(true);
EXPECT_FALSE(ChangedEnough(IntRect(), IntRect()));
@@ -268,7 +337,8 @@ TEST_F(CullRectTest, ApplyTransformsSingleScrollWholeScrollingContents) {
scroll_state.contents_size = IntSize(2000, 2000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
- auto scroll_translation = CreateScrollTranslation(*t1, -10, -15, *scroll);
+ auto scroll_translation =
+ CreateCompositedScrollTranslation(*t1, -10, -15, *scroll);
// Same as ApplyScrollTranslationWholeScrollingContents.
CullRect cull_rect1(IntRect(0, 0, 50, 100));
@@ -308,7 +378,8 @@ TEST_F(CullRectTest, ApplyTransformsSingleScrollPartialScrollingContents) {
scroll_state.contents_size = IntSize(8000, 8000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
- auto scroll_translation = CreateScrollTranslation(*t1, -3000, -5000, *scroll);
+ auto scroll_translation =
+ CreateCompositedScrollTranslation(*t1, -3000, -5000, *scroll);
// Same as ApplyScrollTranslationPartialScrollingContents.
CullRect cull_rect1(IntRect(0, 0, 50, 100));
@@ -344,7 +415,8 @@ TEST_F(CullRectTest, ApplyTransformsEscapingScroll) {
scroll_state.contents_size = IntSize(8000, 8000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
- auto scroll_translation = CreateScrollTranslation(*t1, -3000, -5000, *scroll);
+ auto scroll_translation =
+ CreateCompositedScrollTranslation(*t1, -3000, -5000, *scroll);
auto t2 = CreateTransform(*scroll_translation,
TransformationMatrix().Translate(100, 200));
@@ -374,7 +446,8 @@ TEST_F(CullRectTest, ApplyTransformsSmallScrollContentsAfterBigScrollContents) {
scroll_state1.contents_size = IntSize(8000, 8000);
auto scroll1 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state1));
- auto scroll_translation1 = CreateScrollTranslation(*t1, -10, -15, *scroll1);
+ auto scroll_translation1 =
+ CreateCompositedScrollTranslation(*t1, -10, -15, *scroll1);
auto t2 = CreateTransform(*scroll_translation1,
TransformationMatrix().Translate(2000, 3000));
@@ -384,7 +457,8 @@ TEST_F(CullRectTest, ApplyTransformsSmallScrollContentsAfterBigScrollContents) {
scroll_state2.contents_size = IntSize(200, 400);
auto scroll2 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state2));
- auto scroll_translation2 = CreateScrollTranslation(*t2, -10, -15, *scroll2);
+ auto scroll_translation2 =
+ CreateCompositedScrollTranslation(*t2, -10, -15, *scroll2);
CullRect cull_rect1(IntRect(0, 0, 50, 100));
cull_rect1.ApplyTransforms(*t1, *scroll_translation2, base::nullopt);
@@ -407,7 +481,8 @@ TEST_F(CullRectTest, ApplyTransformsBigScrollContentsAfterSmallScrollContents) {
scroll_state1.contents_size = IntSize(200, 400);
auto scroll1 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state1));
- auto scroll_translation1 = CreateScrollTranslation(*t1, -10, -15, *scroll1);
+ auto scroll_translation1 =
+ CreateCompositedScrollTranslation(*t1, -10, -15, *scroll1);
auto t2 = CreateTransform(*scroll_translation1,
TransformationMatrix().Translate(10, 20));
@@ -418,7 +493,7 @@ TEST_F(CullRectTest, ApplyTransformsBigScrollContentsAfterSmallScrollContents) {
auto scroll2 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state2));
auto scroll_translation2 =
- CreateScrollTranslation(*t2, -3000, -5000, *scroll2);
+ CreateCompositedScrollTranslation(*t2, -3000, -5000, *scroll2);
CullRect cull_rect1(IntRect(0, 0, 100, 200));
cull_rect1.ApplyTransforms(*t1, *scroll_translation2, base::nullopt);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
index 6aa649cca79..bb0ae38e08c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
@@ -126,6 +126,8 @@ static String ForeignLayerTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(ForeignLayerWrapper);
DEBUG_STRING_CASE(ForeignLayerContentsWrapper);
DEBUG_STRING_CASE(ForeignLayerLinkHighlight);
+ DEBUG_STRING_CASE(ForeignLayerViewportScroll);
+ DEBUG_STRING_CASE(ForeignLayerViewportScrollbar);
DEFAULT_CASE;
}
}
@@ -153,6 +155,8 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) {
DEBUG_STRING_CASE(LayerChunkFloat);
DEBUG_STRING_CASE(LayerChunkForeground);
DEBUG_STRING_CASE(LayerChunkNormalFlowAndPositiveZOrderChildren);
+ DEBUG_STRING_CASE(ScrollbarHorizontal);
+ DEBUG_STRING_CASE(ScrollbarVertical);
DEBUG_STRING_CASE(UninitializedType);
DEFAULT_CASE;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
index 79dbb3805e5..320f0d0bee5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -82,6 +82,9 @@ class PLATFORM_EXPORT DisplayItem {
kSVGFilter,
kSVGMask,
kScrollCorner,
+ // The following 3 types are used during cc::Scrollbar::PaintPart() only.
+ // During Paint stage of document lifecycle update, we record
+ // ScrollbarDisplayItem instead of DrawingItems of these types.
kScrollbarTrackAndButtons,
kScrollbarThumb,
kScrollbarTickmarks,
@@ -100,7 +103,9 @@ class PLATFORM_EXPORT DisplayItem {
kForeignLayerWrapper,
kForeignLayerContentsWrapper,
kForeignLayerLinkHighlight,
- kForeignLayerLast = kForeignLayerLinkHighlight,
+ kForeignLayerViewportScroll,
+ kForeignLayerViewportScrollbar,
+ kForeignLayerLast = kForeignLayerViewportScrollbar,
kClipPaintPhaseFirst,
kClipPaintPhaseLast = kClipPaintPhaseFirst + kPaintPhaseMax,
@@ -135,6 +140,10 @@ class PLATFORM_EXPORT DisplayItem {
kLayerChunkForeground,
kLayerChunkNormalFlowAndPositiveZOrderChildren,
+ // The following 2 types are For ScrollbarDisplayItem.
+ kScrollbarHorizontal,
+ kScrollbarVertical,
+
kUninitializedType,
kTypeLast = kUninitializedType
};
@@ -248,6 +257,10 @@ class PLATFORM_EXPORT DisplayItem {
bool IsResizerScrollHitTest() const { return type_ == kResizerScrollHitTest; }
bool IsPluginScrollHitTest() const { return type_ == kPluginScrollHitTest; }
+ bool IsScrollbar() const {
+ return type_ == kScrollbarHorizontal || type_ == kScrollbarVertical;
+ }
+
bool IsCacheable() const { return is_cacheable_; }
void SetUncacheable() { is_cacheable_ = false; }
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
index d5ac6cb2d90..d29f0ecee1f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
@@ -123,6 +123,7 @@ class PLATFORM_EXPORT DisplayItemClient {
private:
friend class FakeDisplayItemClient;
+ friend class ObjectPaintInvalidatorTest;
friend class PaintController;
void Validate() const {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
index 9ee2571f0ae..d1f45b6e0d9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/platform/graphics/contiguous_container.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
@@ -19,8 +19,8 @@ struct PaintChunk;
// each derived display item; the ideal value is the least common multiple.
// The validity of kDisplayItemAlignment and kMaximumDisplayItemSize are checked
// in PaintController::CreateAndAppend().
-static const size_t kDisplayItemAlignment = alignof(HitTestDisplayItem);
-static const size_t kMaximumDisplayItemSize = sizeof(HitTestDisplayItem);
+static const size_t kDisplayItemAlignment = alignof(ScrollbarDisplayItem);
+static const size_t kMaximumDisplayItemSize = sizeof(ScrollbarDisplayItem);
// A container for a list of display items.
class PLATFORM_EXPORT DisplayItemList
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 38d605b9249..480ff218deb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -249,6 +249,10 @@ class PLATFORM_EXPORT EffectPaintPropertyNode
// CompositingReason::kActiveBackdropFilterAnimation;
}
+ CompositingReasons DirectCompositingReasonsForDebugging() const {
+ return DirectCompositingReasons();
+ }
+
const CompositorElementId& GetCompositorElementId() const {
DCHECK(!Parent() || !IsParentAlias());
return state_.compositor_element_id;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
index aedb6cac7ec..daa76c1b077 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -7,7 +7,10 @@
#include <utility>
#include "cc/layers/layer.h"
+#include "cc/layers/picture_layer.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -15,23 +18,21 @@ namespace blink {
namespace {
+// It uses DebugName and OwnerNodeId of the input DisplayItemClient, while
+// calculate VisualRect from the layer's offset and bounds.
class ForeignLayerDisplayItemClient final : public DisplayItemClient {
public:
- ForeignLayerDisplayItemClient(scoped_refptr<cc::Layer> layer,
+ ForeignLayerDisplayItemClient(const DisplayItemClient& client,
+ scoped_refptr<cc::Layer> layer,
const FloatPoint& offset)
- : layer_(std::move(layer)), offset_(offset) {
+ : client_(client), layer_(std::move(layer)), offset_(offset) {
+ DCHECK(layer_);
Invalidate(PaintInvalidationReason::kUncacheable);
}
- String DebugName() const final {
-#if DCHECK_IS_ON()
- return String("ForeignLayer for ") + layer_->DebugName().c_str();
-#else
- return "ForeignLayer";
-#endif
- }
+ String DebugName() const final { return client_.DebugName(); }
- DOMNodeId OwnerNodeId() const final { return layer_->owner_node_id(); }
+ DOMNodeId OwnerNodeId() const final { return client_.OwnerNodeId(); }
IntRect VisualRect() const final {
const auto& bounds = layer_->bounds();
@@ -42,25 +43,27 @@ class ForeignLayerDisplayItemClient final : public DisplayItemClient {
cc::Layer* GetLayer() const { return layer_.get(); }
private:
+ const DisplayItemClient& client_;
scoped_refptr<cc::Layer> layer_;
FloatPoint offset_;
};
} // anonymous namespace
-ForeignLayerDisplayItem::ForeignLayerDisplayItem(Type type,
- scoped_refptr<cc::Layer> layer,
- const FloatPoint& offset)
- : DisplayItem(*new ForeignLayerDisplayItemClient(std::move(layer), offset),
- type,
- sizeof(*this)),
- offset_(offset) {
+ForeignLayerDisplayItem::ForeignLayerDisplayItem(
+ const DisplayItemClient& client,
+ Type type,
+ scoped_refptr<cc::Layer> layer,
+ const FloatPoint& offset,
+ const LayerAsJSONClient* json_client)
+ : DisplayItem(
+ *new ForeignLayerDisplayItemClient(client, std::move(layer), offset),
+ type,
+ sizeof(*this)),
+ offset_(offset),
+ json_client_(json_client) {
DCHECK(IsForeignLayerType(type));
- DCHECK(GetLayer());
DCHECK(!IsCacheable());
- // TODO(959734): This CHECK is intended to find stack traces that are causing
- // a segfault.
- CHECK(GetLayer());
}
ForeignLayerDisplayItem::~ForeignLayerDisplayItem() {
@@ -71,6 +74,10 @@ cc::Layer* ForeignLayerDisplayItem::GetLayer() const {
return static_cast<const ForeignLayerDisplayItemClient&>(Client()).GetLayer();
}
+const LayerAsJSONClient* ForeignLayerDisplayItem::GetLayerAsJSONClient() const {
+ return json_client_;
+}
+
bool ForeignLayerDisplayItem::Equals(const DisplayItem& other) const {
return GetType() == other.GetType() &&
GetLayer() ==
@@ -86,11 +93,14 @@ void ForeignLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const {
}
#endif
-void RecordForeignLayer(GraphicsContext& context,
- DisplayItem::Type type,
- scoped_refptr<cc::Layer> layer,
- const FloatPoint& offset,
- const base::Optional<PropertyTreeState>& properties) {
+static void RecordForeignLayerInternal(
+ GraphicsContext& context,
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ scoped_refptr<cc::Layer> layer,
+ const FloatPoint& offset,
+ const LayerAsJSONClient* json_client,
+ const base::Optional<PropertyTreeState>& properties) {
PaintController& paint_controller = context.GetPaintController();
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
@@ -104,11 +114,37 @@ void RecordForeignLayer(GraphicsContext& context,
*properties);
}
paint_controller.CreateAndAppend<ForeignLayerDisplayItem>(
- type, std::move(layer), offset);
+ client, type, std::move(layer), offset, json_client);
if (properties) {
paint_controller.UpdateCurrentPaintChunkProperties(base::nullopt,
*previous_properties);
}
}
+void RecordForeignLayer(GraphicsContext& context,
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ scoped_refptr<cc::Layer> layer,
+ const FloatPoint& offset,
+ const base::Optional<PropertyTreeState>& properties) {
+ RecordForeignLayerInternal(context, client, type, std::move(layer), offset,
+ nullptr, properties);
+}
+
+void RecordGraphicsLayerAsForeignLayer(GraphicsContext& context,
+ DisplayItem::Type type,
+ const GraphicsLayer& graphics_layer) {
+ // In pre-CompositeAfterPaint, the GraphicsLayer hierarchy is still built
+ // during CompositingUpdate, and we have to clear them here to ensure no
+ // extraneous layers are still attached. In future we will disable all
+ // those layer hierarchy code so we won't need this line.
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ graphics_layer.CcLayer()->RemoveAllChildren();
+
+ RecordForeignLayerInternal(
+ context, graphics_layer, type, graphics_layer.CcLayer(),
+ FloatPoint(graphics_layer.GetOffsetFromTransformNode()), &graphics_layer,
+ graphics_layer.GetPropertyTreeState());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
index a877ae9218e..95e3c4162f5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
@@ -13,6 +13,8 @@
namespace blink {
class GraphicsContext;
+class GraphicsLayer;
+class LayerAsJSONClient;
// Represents foreign content (produced outside Blink) which draws to a layer.
// A client supplies a layer which can be unwrapped and inserted into the full
@@ -22,13 +24,17 @@ class GraphicsContext;
// GraphicsLayer tree.
class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem {
public:
- ForeignLayerDisplayItem(Type,
+ ForeignLayerDisplayItem(const DisplayItemClient& client,
+ Type,
scoped_refptr<cc::Layer>,
- const FloatPoint& offset);
+ const FloatPoint& offset,
+ const LayerAsJSONClient*);
~ForeignLayerDisplayItem() override;
cc::Layer* GetLayer() const;
+ const LayerAsJSONClient* GetLayerAsJSONClient() const;
+
// DisplayItem
bool Equals(const DisplayItem&) const override;
#if DCHECK_IS_ON()
@@ -39,17 +45,44 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem {
private:
FloatPoint offset_;
+ const LayerAsJSONClient* json_client_;
+};
+
+// When a foreign layer's debug name is a literal string, define a instance of
+// LiteralDebugNameClient with DEFINE_STATIC_LOCAL() and pass the instance as
+// client to RecordForeignLayer().
+class LiteralDebugNameClient : public DisplayItemClient {
+ public:
+ LiteralDebugNameClient(const char* name) : name_(name) {}
+
+ String DebugName() const override { return name_; }
+ IntRect VisualRect() const override {
+ NOTREACHED();
+ return IntRect();
+ }
+
+ private:
+ const char* name_;
};
// Records a foreign layer into a GraphicsContext.
// Use this where you would use a recorder class.
+// |client| provides DebugName and optionally DOMNodeId, while VisualRect will
+// be calculated automatically based on layer bounds and offset.
PLATFORM_EXPORT void RecordForeignLayer(
- GraphicsContext&,
- DisplayItem::Type,
- scoped_refptr<cc::Layer>,
+ GraphicsContext& context,
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ scoped_refptr<cc::Layer> layer,
const FloatPoint& offset,
const base::Optional<PropertyTreeState>& = base::nullopt);
+// Records a graphics layer into a GraphicsContext.
+PLATFORM_EXPORT void RecordGraphicsLayerAsForeignLayer(
+ GraphicsContext& context,
+ DisplayItem::Type type,
+ const GraphicsLayer& graphics_layer);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_FOREIGN_LAYER_DISPLAY_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
index 8a41fa8bed6..67168a48af8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
@@ -53,9 +53,12 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
DCHECK(current_properties_.IsInitialized());
#endif
- bool item_forces_new_chunk = item.IsForeignLayer() || item.IsScrollHitTest();
- if (item_forces_new_chunk)
+ bool item_forces_new_chunk =
+ item.IsForeignLayer() || item.IsScrollHitTest() || item.IsScrollbar();
+ if (item_forces_new_chunk) {
force_new_chunk_ = true;
+ next_chunk_id_.emplace(item.GetId());
+ }
size_t new_chunk_begin_index;
if (chunks_.IsEmpty()) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
index 2aeedf8f073..38c19a5348b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
@@ -259,6 +259,7 @@ TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) {
TestChunkerDisplayItem after_i2(client_, DisplayItemType(10));
chunker.IncrementDisplayItemIndex(after_i2);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(i3);
EXPECT_THAT(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
index 42631cf4740..ca0705125b3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
@@ -19,10 +19,6 @@ namespace cc {
class PaintCanvas;
}
-namespace paint_preview {
-class PaintPreviewTracker;
-}
-
namespace blink {
class GraphicsContext;
class PaintController;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
index 2426f3fab15..1a65460c14d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
-#include "base/trace_event/traced_value.h"
+#include "cc/layers/layer.h"
#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
@@ -24,9 +24,11 @@ void RasterInvalidationTracking::SimulateRasterUnderInvalidations(bool enable) {
}
bool RasterInvalidationTracking::ShouldAlwaysTrack() {
- if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
- return true;
+ return RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
+ IsTracingRasterInvalidations();
+}
+bool RasterInvalidationTracking::IsTracingRasterInvalidations() {
bool tracing_enabled;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), &tracing_enabled);
@@ -76,12 +78,15 @@ static bool CompareRasterInvalidationInfo(const RasterInvalidationInfo& a,
return a.reason < b.reason;
}
-void RasterInvalidationTracking::AsJSON(JSONObject* json) {
+void RasterInvalidationTracking::AsJSON(JSONObject* json) const {
if (!invalidations_.IsEmpty()) {
- std::sort(invalidations_.begin(), invalidations_.end(),
+ // Sort to make the output more readable and easier to see the differences
+ // by a human.
+ auto sorted_invalidations = invalidations_;
+ std::sort(sorted_invalidations.begin(), sorted_invalidations.end(),
&CompareRasterInvalidationInfo);
auto paint_invalidations_json = std::make_unique<JSONArray>();
- for (auto& info : invalidations_) {
+ for (auto& info : sorted_invalidations) {
auto info_json = std::make_unique<JSONObject>();
info_json->SetString("object", info.client_debug_name);
if (!info.rect.IsEmpty()) {
@@ -117,36 +122,17 @@ void RasterInvalidationTracking::AsJSON(JSONObject* json) {
}
}
-void RasterInvalidationTracking::AddToTracedValue(
- base::trace_event::TracedValue& traced_value) {
- if (!ShouldAlwaysTrack())
- return;
-
- // The names should be kept consistent with (except the intentional naming
- // style difference: 'naming_style' here vs 'namingStyle' in trace viewer)
- // third_party/catapult/tracing/tracing/extras/chrome/cc/layer_impl.html.
- // Note that the difference between naming style is intentional.
- traced_value.BeginArray("annotated_invalidation_rects");
- std::sort(invalidations_.begin(), invalidations_.end(),
- &CompareRasterInvalidationInfo);
+void RasterInvalidationTracking::AddToLayerDebugInfo(
+ cc::LayerDebugInfo& debug_info) const {
+ // This is not sorted because the output is for client programs, and the
+ // invalidations may be accumulated in debug_info.
for (auto& info : invalidations_) {
if (info.rect.IsEmpty())
continue;
- traced_value.BeginDictionary();
- traced_value.BeginArray("geometry_rect");
- traced_value.AppendInteger(info.rect.X());
- traced_value.AppendInteger(info.rect.Y());
- traced_value.AppendInteger(info.rect.Width());
- traced_value.AppendInteger(info.rect.Height());
- traced_value.EndArray();
- traced_value.SetString("reason",
- PaintInvalidationReasonToString(info.reason));
- traced_value.SetString(
- "client",
- WTF::StringUTF8Adaptor(info.client_debug_name).AsStringPiece());
- traced_value.EndDictionary();
+ debug_info.invalidations.push_back(
+ {gfx::Rect(info.rect), PaintInvalidationReasonToString(info.reason),
+ info.client_debug_name.Utf8()});
}
- traced_value.EndArray();
}
static bool PixelComponentsDiffer(int c1, int c2) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
index 52c3f69b8fc..94bf0a526ce 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
@@ -14,11 +14,9 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkColor.h"
-namespace base {
-namespace trace_event {
-class TracedValue;
+namespace cc {
+struct LayerDebugInfo;
}
-} // namespace base
namespace blink {
@@ -76,6 +74,8 @@ class PLATFORM_EXPORT RasterInvalidationTracking {
// "disabled-by-default-blink.invalidation" category.
static bool ShouldAlwaysTrack();
+ static bool IsTracingRasterInvalidations();
+
void AddInvalidation(const DisplayItemClient*,
const String& debug_name,
const IntRect&,
@@ -95,8 +95,9 @@ class PLATFORM_EXPORT RasterInvalidationTracking {
sk_sp<PaintRecord> new_record,
const IntRect& new_interest_rect);
- void AsJSON(JSONObject*);
- void AddToTracedValue(base::trace_event::TracedValue&);
+ void AsJSON(JSONObject*) const;
+
+ void AddToLayerDebugInfo(cc::LayerDebugInfo&) const;
// The record containing under-invalidated pixels in dark red.
sk_sp<const PaintRecord> UnderInvalidationRecord() const {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
index 6dc6b14b523..a7033cf5adb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -149,6 +149,16 @@ PaintInvalidationReason RasterInvalidator::ChunkPropertiesChanged(
return PaintInvalidationReason::kNone;
}
+// Skip the chunk for raster invalidation if it contains only one non-drawing
+// display item. We could also skip chunks containing all non-drawing display
+// items, but single non-drawing item is more common, e.g. scroll hit test.
+bool ShouldSkipForRasterInvalidation(const PaintArtifact& paint_artifact,
+ const PaintChunk& paint_chunk) {
+ return paint_chunk.size() == 1 &&
+ !paint_artifact.GetDisplayItemList()[paint_chunk.begin_index]
+ .DrawsContent();
+}
+
// Generates raster invalidations by checking changes (appearing, disappearing,
// reordering, property changes) of chunks. The logic is similar to
// PaintController::GenerateRasterInvalidations(). The complexity is between
@@ -173,6 +183,9 @@ void RasterInvalidator::GenerateRasterInvalidations(
size_t max_matched_old_index = 0;
for (auto it = new_chunks.begin(); it != new_chunks.end(); ++it) {
const auto& new_chunk = *it;
+ if (ShouldSkipForRasterInvalidation(new_paint_artifact, new_chunk))
+ continue;
+
mapper.SwitchToChunk(new_chunk);
auto& new_chunk_info = new_chunks_info.emplace_back(*this, mapper, it);
@@ -327,6 +340,8 @@ void RasterInvalidator::Generate(
ChunkToLayerMapper mapper(layer_state, layer_bounds.OffsetFromOrigin(),
visual_rect_subpixel_offset);
for (auto it = paint_chunks.begin(); it != paint_chunks.end(); ++it) {
+ if (ShouldSkipForRasterInvalidation(*new_paint_artifact, *it))
+ continue;
mapper.SwitchToChunk(*it);
new_chunks_info.emplace_back(*this, mapper, it);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
new file mode 100644
index 00000000000..72d3fb4c053
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
@@ -0,0 +1,128 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
+
+#include "base/trace_event/traced_value.h"
+#include "cc/input/scrollbar.h"
+#include "cc/layers/painted_overlay_scrollbar_layer.h"
+#include "cc/layers/painted_scrollbar_layer.h"
+#include "cc/layers/solid_color_scrollbar_layer.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
+
+namespace blink {
+
+ScrollbarDisplayItem::ScrollbarDisplayItem(
+ const DisplayItemClient& client,
+ Type type,
+ scoped_refptr<cc::Scrollbar> scrollbar,
+ const IntRect& rect,
+ const TransformPaintPropertyNode* scroll_translation,
+ CompositorElementId element_id)
+ : DisplayItem(client, type, sizeof(*this), /*draws_content*/ true),
+ scrollbar_(std::move(scrollbar)),
+ rect_(rect),
+ scroll_translation_(scroll_translation),
+ element_id_(element_id) {
+ DCHECK(IsScrollbar());
+ DCHECK(!scroll_translation || scroll_translation->ScrollNode());
+}
+
+sk_sp<const PaintRecord> ScrollbarDisplayItem::Paint() const {
+ if (record_) {
+ DCHECK(!scrollbar_->NeedsRepaintPart(cc::TRACK_BUTTONS_TICKMARKS));
+ DCHECK(!scrollbar_->NeedsRepaintPart(cc::THUMB));
+ return record_;
+ }
+
+ PaintRecorder recorder;
+ recorder.beginRecording(rect_);
+ auto* canvas = recorder.getRecordingCanvas();
+ scrollbar_->PaintPart(canvas, cc::TRACK_BUTTONS_TICKMARKS, rect_);
+ gfx::Rect thumb_rect = scrollbar_->ThumbRect();
+ thumb_rect.Offset(rect_.X(), rect_.Y());
+ scrollbar_->PaintPart(canvas, cc::THUMB, thumb_rect);
+
+ record_ = recorder.finishRecordingAsPicture();
+ return record_;
+}
+
+scoped_refptr<cc::Layer> ScrollbarDisplayItem::CreateLayer() const {
+ scoped_refptr<cc::ScrollbarLayerBase> layer;
+ if (scrollbar_->IsSolidColor()) {
+ DCHECK(scrollbar_->IsOverlay());
+ bool is_horizontal = scrollbar_->Orientation() == cc::HORIZONTAL;
+ gfx::Rect thumb_rect = scrollbar_->ThumbRect();
+ int thumb_thickness =
+ is_horizontal ? thumb_rect.height() : thumb_rect.width();
+ gfx::Rect track_rect = scrollbar_->TrackRect();
+ int track_start = is_horizontal ? track_rect.x() : track_rect.y();
+ layer = cc::SolidColorScrollbarLayer::Create(
+ scrollbar_->Orientation(), thumb_thickness, track_start,
+ scrollbar_->IsLeftSideVerticalScrollbar());
+ } else if (scrollbar_->UsesNinePatchThumbResource()) {
+ DCHECK(scrollbar_->IsOverlay());
+ layer = cc::PaintedOverlayScrollbarLayer::Create(scrollbar_);
+ } else {
+ layer = cc::PaintedScrollbarLayer::Create(scrollbar_);
+ }
+
+ layer->SetIsDrawable(true);
+ layer->SetElementId(element_id_);
+ if (scroll_translation_) {
+ layer->SetScrollElementId(
+ scroll_translation_->ScrollNode()->GetCompositorElementId());
+ }
+ return layer;
+}
+
+bool ScrollbarDisplayItem::Equals(const DisplayItem& other) const {
+ if (!DisplayItem::Equals(other))
+ return false;
+
+ // Don't check scrollbar_ because it's always newly created when we repaint
+ // a scrollbar (including forced repaint for PaintUnderInvalidationChecking).
+ // Don't check record_ because it's lazily created, and the DCHECKs in Paint()
+ // can catch most under-invalidation cases.
+ const auto& other_scrollbar_item =
+ static_cast<const ScrollbarDisplayItem&>(other);
+ return rect_ == other_scrollbar_item.rect_ &&
+ scroll_translation_ == other_scrollbar_item.scroll_translation_ &&
+ element_id_ == other_scrollbar_item.element_id_;
+}
+
+#if DCHECK_IS_ON()
+void ScrollbarDisplayItem::PropertiesAsJSON(JSONObject& json) const {
+ DisplayItem::PropertiesAsJSON(json);
+ json.SetString("rect", rect_.ToString());
+ json.SetString("scrollTranslation",
+ String::Format("%p", scroll_translation_));
+}
+#endif
+
+void ScrollbarDisplayItem::Record(
+ GraphicsContext& context,
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ scoped_refptr<cc::Scrollbar> scrollbar,
+ const IntRect& rect,
+ const TransformPaintPropertyNode* scroll_translation,
+ CompositorElementId element_id) {
+ PaintController& paint_controller = context.GetPaintController();
+ if (paint_controller.DisplayItemConstructionIsDisabled())
+ return;
+
+ // Must check PaintController::UseCachedItemIfPossible before this function.
+ DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
+ !paint_controller.UseCachedItemIfPossible(client, type));
+
+ paint_controller.CreateAndAppend<ScrollbarDisplayItem>(
+ client, type, std::move(scrollbar), rect, scroll_translation, element_id);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h
new file mode 100644
index 00000000000..c8e214c8007
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h
@@ -0,0 +1,80 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLLBAR_DISPLAY_ITEM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLLBAR_DISPLAY_ITEM_H_
+
+#include "cc/input/scrollbar.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
+#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
+
+namespace cc {
+class Layer;
+}
+
+namespace blink {
+
+class GraphicsContext;
+class TransformPaintPropertyNode;
+
+// Represents a non-custom scrollbar in CompositeAfterPaint. During paint, we
+// create a ScrollbarDisplayItem for a non-custom scrollbar. During
+// PaintArtifactCompositor::Update(), we decide whether to composite the
+// scrollbar and, if not composited, call Paint() to actually paint the
+// scrollbar into a paint record, otherwise call CreateLayer() to create a
+// cc scrollbar layer.
+class PLATFORM_EXPORT ScrollbarDisplayItem final : public DisplayItem {
+ public:
+ ScrollbarDisplayItem(const DisplayItemClient&,
+ Type,
+ scoped_refptr<cc::Scrollbar>,
+ const IntRect& rect,
+ const TransformPaintPropertyNode* scroll_translation,
+ CompositorElementId element_id);
+
+ cc::Scrollbar* GetScrollbar() const { return scrollbar_.get(); }
+ const IntRect& GetRect() const { return rect_; }
+ const TransformPaintPropertyNode* ScrollTranslation() const {
+ return scroll_translation_;
+ }
+ CompositorElementId ElementId() const { return element_id_; }
+
+ // Paints the scrollbar into the internal paint record, for non-composited
+ // scrollbar.
+ sk_sp<const PaintRecord> Paint() const;
+
+ // Creates cc layer for composited scrollbar.
+ scoped_refptr<cc::Layer> CreateLayer() const;
+
+ // DisplayItem
+ bool Equals(const DisplayItem&) const override;
+#if DCHECK_IS_ON()
+ void PropertiesAsJSON(JSONObject&) const override;
+#endif
+
+ // Records a scrollbar into a GraphicsContext. Must check
+ // PaintController::UseCachedItem() before calling this function.
+ // |rect| is the bounding box of the scrollbar in the current transform space.
+ static void Record(GraphicsContext&,
+ const DisplayItemClient&,
+ DisplayItem::Type,
+ scoped_refptr<cc::Scrollbar>,
+ const IntRect& rect,
+ const TransformPaintPropertyNode* scroll_translation,
+ CompositorElementId element_id);
+
+ private:
+ scoped_refptr<cc::Scrollbar> scrollbar_;
+ IntRect rect_;
+ const TransformPaintPropertyNode* scroll_translation_;
+ CompositorElementId element_id_;
+ // This is lazily created for non-composited scrollbar.
+ mutable sk_sp<const PaintRecord> record_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLLBAR_DISPLAY_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index f48c35cf7e8..802a8acba3e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -368,6 +368,11 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return state_.direct_compositing_reasons &
CompositingReason::kActiveTransformAnimation;
}
+
+ CompositingReasons DirectCompositingReasonsForDebugging() const {
+ return DirectCompositingReasons();
+ }
+
bool TransformAnimationIsAxisAligned() const {
return state_.flags.animation_is_axis_aligned;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.cc
index 508a92c1f19..c645e61fc7a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.cc
@@ -108,7 +108,7 @@ void PaintWorkletPaintDispatcher::DispatchWorklets(
// specified, base::RepeatingClosure will trigger immediately and so the
// callback will still happen.
base::RepeatingClosure repeating_on_done = base::BarrierClosure(
- ongoing_jobs_.size(), ConvertToBaseCallback(std::move(on_done)));
+ ongoing_jobs_.size(), ConvertToBaseRepeatingCallback(std::move(on_done)));
// Now dispatch the calls to the registered painters. For each input, we match
// the id to a registered worklet and dispatch a cross-thread call to it,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher_test.cc
index b764379856e..d682fcd9a62 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher_test.cc
@@ -10,8 +10,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
using ::testing::_;
using ::testing::NiceMock;
@@ -22,8 +22,7 @@ namespace {
// We need a thread (or multiple threads) for the (mock) worklets to run on.
std::unique_ptr<Thread> CreateTestThread(const char* name) {
return Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
- .SetThreadNameForTest(name));
+ ThreadCreationParams(ThreadType::kTestThread).SetThreadNameForTest(name));
}
class PaintWorkletPaintDispatcherAsyncTest : public ::testing::Test {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/path.cc b/chromium/third_party/blink/renderer/platform/graphics/path.cc
index b1a93cf71b1..f45069b7a15 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/path.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/path.cc
@@ -73,7 +73,7 @@ bool Path::Contains(const FloatPoint& point, WindRule rule) const {
return false;
SkScalar x = point.X();
SkScalar y = point.Y();
- SkPath::FillType fill_type = WebCoreWindRuleToSkFillType(rule);
+ SkPathFillType fill_type = WebCoreWindRuleToSkFillType(rule);
if (path_.getFillType() != fill_type) {
SkPath tmp(path_);
tmp.setFillType(fill_type);
@@ -337,7 +337,7 @@ void Path::AddArcTo(const FloatPoint& p,
WebCoreFloatToSkScalar(r.Height()),
WebCoreFloatToSkScalar(x_rotate),
large_arc ? SkPath::kLarge_ArcSize : SkPath::kSmall_ArcSize,
- sweep ? SkPath::kCW_Direction : SkPath::kCCW_Direction,
+ sweep ? SkPathDirection::kCW : SkPathDirection::kCCW,
WebCoreFloatToSkScalar(p.X()), WebCoreFloatToSkScalar(p.Y()));
}
@@ -399,7 +399,7 @@ void Path::AddArc(const FloatPoint& p,
void Path::AddRect(const FloatRect& rect) {
// Start at upper-left, add clock-wise.
- path_.addRect(rect, SkPath::kCW_Direction, 0);
+ path_.addRect(rect, SkPathDirection::kCW, 0);
}
void Path::AddEllipse(const FloatPoint& p,
@@ -430,7 +430,7 @@ void Path::AddEllipse(const FloatPoint& p,
void Path::AddEllipse(const FloatRect& rect) {
// Start at 3 o'clock, add clock-wise.
- path_.addOval(rect, SkPath::kCW_Direction, 1);
+ path_.addOval(rect, SkPathDirection::kCW, 1);
}
void Path::AddRoundedRect(const FloatRoundedRect& r) {
@@ -502,7 +502,7 @@ void Path::AddPathForRoundedRect(const FloatRect& rect,
// Start at upper-left (after corner radii), add clock-wise.
path_.addRRect(FloatRoundedRect(rect, top_left_radius, top_right_radius,
bottom_left_radius, bottom_right_radius),
- SkPath::kCW_Direction, 0);
+ SkPathDirection::kCW, 0);
}
void Path::AddPath(const Path& src, const AffineTransform& transform) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.cc b/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.cc
new file mode 100644
index 00000000000..9712fb34348
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.cc
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h"
+
+namespace blink {
+
+static bool g_mock_scrollbars_enabled = false;
+static bool g_overlay_scrollbars_enabled = false;
+
+void ScrollbarThemeSettings::SetMockScrollbarsEnabled(bool flag) {
+ g_mock_scrollbars_enabled = flag;
+}
+
+bool ScrollbarThemeSettings::MockScrollbarsEnabled() {
+ return g_mock_scrollbars_enabled;
+}
+
+void ScrollbarThemeSettings::SetOverlayScrollbarsEnabled(bool flag) {
+ g_overlay_scrollbars_enabled = flag;
+}
+
+bool ScrollbarThemeSettings::OverlayScrollbarsEnabled() {
+ return g_overlay_scrollbars_enabled;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h b/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h
new file mode 100644
index 00000000000..08e5916b069
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SCROLLBAR_THEME_SETTINGS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SCROLLBAR_THEME_SETTINGS_H_
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+// Scrollbar theme settings are only accessible from particular classes. Other
+// code should use Page::GetScrollbarTheme(), and test code can also use
+// ScopedMockOverlayScrollbars. These settings are not under
+// RuntimeEnabledFeatures because OverlayScrollbars can only be set though
+// WebRuntimeSettings for chrome, and blink tests code must set
+// OverlayScrollbars and MockScrollbars at the same time with
+// ScopedOverlayMockScrollbars (see the class for the reasons), unless the
+// callers (the listed friend classes only) know that the reasons don't apply.
+class PLATFORM_EXPORT ScrollbarThemeSettings {
+ private:
+ ScrollbarThemeSettings() = delete;
+
+ friend class DevToolsEmulator;
+ friend class Element;
+ friend class Internals;
+ friend class ScopedMockOverlayScrollbars;
+ friend class ScrollbarTheme;
+ friend class ScrollbarsTest;
+ friend class WebRuntimeFeatures;
+
+ static void SetMockScrollbarsEnabled(bool);
+ static bool MockScrollbarsEnabled();
+
+ static void SetOverlayScrollbarsEnabled(bool);
+
+ // This is the global overlay scrollbars setting. We also allow per-page
+ // setting of Android overlay scrollbars, which overrides this setting, for
+ // device emulation on desktop, so code should use Page::GetScrollbarTheme()
+ // instead of this function.
+ static bool OverlayScrollbarsEnabled();
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SCROLLBAR_THEME_SETTINGS_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
index f6edaa4ada5..b5f81ee0f40 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
@@ -95,14 +95,14 @@ inline bool WebCoreFloatNearlyEqual(float a, float b) {
WebCoreFloatToSkScalar(b));
}
-inline SkPath::FillType WebCoreWindRuleToSkFillType(WindRule rule) {
- return static_cast<SkPath::FillType>(rule);
+inline SkPathFillType WebCoreWindRuleToSkFillType(WindRule rule) {
+ return static_cast<SkPathFillType>(rule);
}
-inline WindRule SkFillTypeToWindRule(SkPath::FillType fill_type) {
+inline WindRule SkFillTypeToWindRule(SkPathFillType fill_type) {
switch (fill_type) {
- case SkPath::kWinding_FillType:
- case SkPath::kEvenOdd_FillType:
+ case SkPathFillType::kWinding:
+ case SkPathFillType::kEvenOdd:
return static_cast<WindRule>(fill_type);
default:
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
index 2dd398f4b50..ae6cb2afc46 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -11,7 +11,6 @@
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPaint.h"
@@ -21,20 +20,6 @@
namespace blink {
-scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
- sk_sp<SkImage> image,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>
- context_provider_wrapper) {
- if (!image)
- return nullptr;
- if (image->isTextureBacked()) {
- CHECK(context_provider_wrapper);
- return AcceleratedStaticBitmapImage::CreateFromSkImage(
- image, std::move(context_provider_wrapper));
- }
- return UnacceleratedStaticBitmapImage::Create(image);
-}
-
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(PaintImage image) {
DCHECK(!image.GetSkImage()->isTextureBacked());
return UnacceleratedStaticBitmapImage::Create(std::move(image));
@@ -43,7 +28,7 @@ scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(PaintImage image) {
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
sk_sp<SkData> data,
const SkImageInfo& info) {
- return Create(
+ return UnacceleratedStaticBitmapImage::Create(
SkImage::MakeRasterData(info, std::move(data), info.minRowBytes()));
}
@@ -77,54 +62,45 @@ scoped_refptr<StaticBitmapImage> StaticBitmapImage::ConvertToColorSpace(
skia_image->makeColorTypeAndColorSpace(color_type, color_space);
}
- return StaticBitmapImage::Create(skia_image, skia_image->isTextureBacked()
- ? ContextProviderWrapper()
- : nullptr);
+ if (skia_image->isTextureBacked()) {
+ return AcceleratedStaticBitmapImage::CreateFromSkImage(
+ skia_image, ContextProviderWrapper());
+ }
+ return UnacceleratedStaticBitmapImage::Create(skia_image);
}
-bool StaticBitmapImage::ConvertToArrayBufferContents(
- scoped_refptr<StaticBitmapImage> src_image,
- WTF::ArrayBufferContents& dest_contents,
+base::CheckedNumeric<size_t> StaticBitmapImage::GetSizeInBytes(
const IntRect& rect,
- const CanvasColorParams& color_params,
- bool is_accelerated) {
+ const CanvasColorParams& color_params) {
uint8_t bytes_per_pixel = color_params.BytesPerPixel();
- base::CheckedNumeric<int> data_size = bytes_per_pixel;
+ base::CheckedNumeric<size_t> data_size = bytes_per_pixel;
data_size *= rect.Size().Area();
- if (!data_size.IsValid() ||
- data_size.ValueOrDie() > v8::TypedArray::kMaxLength)
+ return data_size;
+}
+
+bool StaticBitmapImage::MayHaveStrayArea(
+ scoped_refptr<StaticBitmapImage> src_image,
+ const IntRect& rect) {
+ if (!src_image)
return false;
- int alloc_size_in_bytes = data_size.ValueOrDie();
- if (!src_image) {
- WTF::ArrayBufferContents result(alloc_size_in_bytes, 1,
- WTF::ArrayBufferContents::kNotShared,
- WTF::ArrayBufferContents::kZeroInitialize);
-
- // Check if the ArrayBuffer backing store was allocated correctly.
- if (result.DataLength() != static_cast<size_t>(alloc_size_in_bytes)) {
- return false;
- }
- result.Transfer(dest_contents);
+ return rect.X() < 0 || rect.Y() < 0 ||
+ rect.MaxX() > src_image->Size().Width() ||
+ rect.MaxY() > src_image->Size().Height();
+}
+
+bool StaticBitmapImage::CopyToByteArray(
+ scoped_refptr<StaticBitmapImage> src_image,
+ base::span<uint8_t> dst,
+ const IntRect& rect,
+ const CanvasColorParams& color_params) {
+ DCHECK_EQ(dst.size(), GetSizeInBytes(rect, color_params).ValueOrDie());
+
+ if (!src_image)
return true;
- }
- const bool may_have_stray_area =
- is_accelerated // GPU readback may fail silently
- || rect.X() < 0 || rect.Y() < 0 ||
- rect.MaxX() > src_image->Size().Width() ||
- rect.MaxY() > src_image->Size().Height();
- WTF::ArrayBufferContents::InitializationPolicy initialization_policy =
- may_have_stray_area ? WTF::ArrayBufferContents::kZeroInitialize
- : WTF::ArrayBufferContents::kDontInitialize;
-
- WTF::ArrayBufferContents result(alloc_size_in_bytes, 1,
- WTF::ArrayBufferContents::kNotShared,
- initialization_policy);
- // Check if the ArrayBuffer backing store was allocated correctly.
- if (result.DataLength() != static_cast<size_t>(alloc_size_in_bytes)) {
- return false;
- }
+ if (dst.size() == 0)
+ return true;
SkColorType color_type =
(color_params.GetSkColorType() == kRGBA_F16_SkColorType)
@@ -137,11 +113,10 @@ bool StaticBitmapImage::ConvertToArrayBufferContents(
if (!sk_image)
return false;
bool read_pixels_successful = sk_image->readPixels(
- info, result.Data(), info.minRowBytes(), rect.X(), rect.Y());
+ info, dst.data(), info.minRowBytes(), rect.X(), rect.Y());
DCHECK(read_pixels_successful ||
!sk_image->bounds().intersect(SkIRect::MakeXYWH(
rect.X(), rect.Y(), info.width(), info.height())));
- result.Transfer(dest_contents);
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
index 85a393afe8e..7366bdebcdc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
@@ -11,16 +11,9 @@
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-namespace WTF {
-
-class ArrayBufferContents;
-
-} // namespace WTF
-
namespace gpu {
namespace gles2 {
class GLES2Interface;
@@ -33,13 +26,6 @@ class WebGraphicsContext3DProviderWrapper;
class PLATFORM_EXPORT StaticBitmapImage : public Image {
public:
- // WebGraphicsContext3DProviderWrapper argument only needs to be provided if
- // The SkImage is texture backed, in which case it must be a reference to the
- // context provider that owns the GrContext with which the SkImage is
- // associated.
- static scoped_refptr<StaticBitmapImage> Create(
- sk_sp<SkImage>,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> = nullptr);
static scoped_refptr<StaticBitmapImage> Create(PaintImage);
static scoped_refptr<StaticBitmapImage> Create(sk_sp<SkData> data,
const SkImageInfo&);
@@ -114,12 +100,17 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
sk_sp<SkColorSpace>,
SkColorType = kN32_SkColorType);
- static bool ConvertToArrayBufferContents(
- scoped_refptr<StaticBitmapImage> src_image,
- WTF::ArrayBufferContents& dest_contents,
- const IntRect&,
- const CanvasColorParams&,
- bool is_accelerated = false);
+ static base::CheckedNumeric<size_t> GetSizeInBytes(
+ const IntRect& rect,
+ const CanvasColorParams& color_params);
+
+ static bool MayHaveStrayArea(scoped_refptr<StaticBitmapImage> src_image,
+ const IntRect& rect);
+
+ static bool CopyToByteArray(scoped_refptr<StaticBitmapImage> src_image,
+ base::span<uint8_t> dst,
+ const IntRect&,
+ const CanvasColorParams&);
protected:
// Helper for sub-classes
diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_test.cc
index 45c31b826b4..4784533fa9d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_test.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "v8/include/v8.h"
@@ -23,13 +23,13 @@ TEST_F(StaticBitmapImageTest,
EXPECT_TRUE(!!surface);
scoped_refptr<StaticBitmapImage> image =
- StaticBitmapImage::Create(surface->makeImageSnapshot());
+ UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot());
IntRect too_big_rect(IntPoint(0, 0),
IntSize(1, (v8::TypedArray::kMaxLength / 4) + 1));
- WTF::ArrayBufferContents contents;
- EXPECT_FALSE(StaticBitmapImage::ConvertToArrayBufferContents(
- image, contents, too_big_rect, CanvasColorParams()));
+ EXPECT_GT(StaticBitmapImage::GetSizeInBytes(too_big_rect, CanvasColorParams())
+ .ValueOrDie(),
+ v8::TypedArray::kMaxLength);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index 986247a64de..1f551556454 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -534,7 +534,7 @@ viz::CompositorFrame VideoFrameSubmitter::CreateCompositorFrame(
base::TimeTicks value;
if (video_frame && video_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::DECODE_TIME, &value)) {
+ media::VideoFrameMetadata::DECODE_END_TIME, &value)) {
TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0("media", "VideoFrameSubmitter",
*next_frame_token_, value);
TRACE_EVENT_ASYNC_STEP_PAST0("media", "VideoFrameSubmitter",
diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
index 43fabbc3f3a..c21068565d3 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -21,8 +21,6 @@ buildflag_header("blink_heap_buildflags") {
blink_platform_sources("heap") {
sources = [
- "address_cache.cc",
- "address_cache.h",
"atomic_entry_flag.h",
"blink_gc.cc",
"blink_gc.h",
@@ -55,6 +53,7 @@ blink_platform_sources("heap") {
"marking_visitor.h",
"member.h",
"name_traits.h",
+ "page_bloom_filter.h",
"page_memory.cc",
"page_memory.h",
"page_pool.cc",
@@ -123,9 +122,9 @@ jumbo_source_set("blink_heap_unittests_sources") {
testonly = true
sources = [
"../testing/run_all_tests.cc",
- "address_cache_test.cc",
"blink_gc_memory_dump_provider_test.cc",
"cancelable_task_scheduler_test.cc",
+ "concurrent_marking_test.cc",
"gc_info_test.cc",
"heap_compact_test.cc",
"heap_stats_collector_test.cc",
@@ -138,6 +137,7 @@ jumbo_source_set("blink_heap_unittests_sources") {
"object_start_bitmap_test.cc",
"persistent_test.cc",
"thread_state_scheduling_test.cc",
+ "weakness_marking_test.cc",
"worklist_test.cc",
"write_barrier_perftest.cc",
]
diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
index ac60de45424..f1415c771a5 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
+++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
@@ -1,16 +1,15 @@
# Blink GC API reference
-This is a through document for Oilpan API usage.
-If you want to learn the API usage quickly, look at
+This document describes the usage of Oilpan -- Blink's garbage collector.
+If you just want to get an overview of the API you can have a look at
[this tutorial](https://docs.google.com/presentation/d/1XPu03ymz8W295mCftEC9KshH9Icxfq81YwIJQzQrvxo/edit#slide=id.p).
-If you're just interested in wrapper tracing,
-see [Wrapper Tracing Reference](../bindings/TraceWrapperReference.md).
+If you're interested in wrapper tracing, see [Wrapper Tracing Reference](../bindings/TraceWrapperReference.md).
[TOC]
## Header file
-Unless otherwise noted, any of the primitives explained in this page requires the following `#include` statement:
+Unless otherwise noted, any of the primitives explained on this page require the following `#include` statement:
```c++
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -20,8 +19,7 @@ Unless otherwise noted, any of the primitives explained in this page requires th
### GarbageCollected
-A class that wants the lifetime management of its instances to be managed by Blink GC (Oilpan), it must inherit from
-`GarbageCollected<YourClass>`.
+A class that wants the lifetime management of its instances to be managed by Oilpan, it must inherit from `GarbageCollected<T>`.
```c++
class YourClass : public GarbageCollected<YourClass> {
@@ -29,91 +27,89 @@ class YourClass : public GarbageCollected<YourClass> {
};
```
-Instances of such classes are said to be *on Oilpan heap*, or *on heap* for short, while instances of other classes
-are called *off heap*. In the rest of this document, the terms "on heap" or "on-heap objects" are used to mean the
-objects on Oilpan heap instead of on normal (default) dynamic allocator's heap space.
+Instances of such classes are said to be *on Oilpan heap*, or *on heap* for short, while instances of other classes are called *off heap*.
+In the rest of this document, the terms *on heap* or *on-heap objects* are used to mean the objects on Oilpan heap instead of on normal (default) dynamic allocator's heap space.
-You can create an instance of your class normally through `new`, while you may not free the object with `delete`,
-as the Blink GC system is responsible for deallocating the object once it determines the object is unreachable.
+You can create an instance of your class through `MakeGarbageCollected<T>`, while you may not free the object with `delete`, as Oilpan is responsible for deallocating the object once it determines the object is unreachable.
You may not allocate an on-heap object on stack.
Your class may need to have a tracing method. See [Tracing](#Tracing) for details.
-Your class will be automatically finalized as long as it is non-trivially destructible. Non-final classes are
-required to have a virtual destructor.
-
+Your class will be automatically finalized as long as it is non-trivially destructible.
+Non-final classes that are not trivially destructible are required to have a virtual destructor.
+Trivially destructible classes should not have a destructor. Adding a destructor to such classes would make then non-trivially destructible and would hinder performance.
Note that finalization is done at an arbitrary time after the object becomes unreachable.
+Any destructor executed within the finalization period *must not* touch any other on-heap object because destructors can be executed in any order.
-Any destructor executed within the finalization period must not touch any other on-heap object, because destructors
-can be executed in any order.
-
-`GarbageCollected<T>` or any class deriving from `GarbageCollected<T>`, directly or indirectly, must be the first
-element in its base class list (called "leftmost derivation rule"). This rule is needed to assure each on-heap object
-has its own canonical address.
+`GarbageCollected<T>` or any class deriving from `GarbageCollected<T>`, directly or indirectly, must be the first element in its base class list (called "leftmost derivation rule").
+This rule is needed to assure each on-heap object has its own canonical address.
```c++
-class A : public GarbageCollected<A>, public P { // OK, GarbageCollected<A> is leftmost.
+class A : public GarbageCollected<A>, public P {
+ // OK: GarbageCollected<A> is leftmost.
};
-class B : public A, public Q { // OK, A is leftmost.
+class B : public A, public Q {
+ // OK: A is leftmost.
};
-// class C : public R, public A { // BAD, A must be the first base class.
+// class C : public R, public A {
+// BAD: A must be the first base class.
+// If R is also garbage collected, A should be [GarbageCollectedMixin](#GarbageCollectedMixin).
// };
```
-If a non-leftmost base class needs to retain an on-heap object, that base class needs to inherit from
-[GarbageCollectedMixin](#GarbageCollectedMixin). It's generally recommended to make *any* non-leftmost base class
-inherit from `GarbageCollectedMixin`, because it's dangerous to save a pointer to a non-leftmost
-non-`GarbageCollectedMixin` subclass of an on-heap object.
+If a non-leftmost base class needs to retain an on-heap object, that base class needs to inherit from [GarbageCollectedMixin](#GarbageCollectedMixin). It's generally recommended to make *any* non-leftmost base class inherit from `GarbageCollectedMixin` because it's dangerous to save a pointer to a non-leftmost non-`GarbageCollectedMixin` subclass of an on-heap object.
```c++
-void someFunction(P*);
+P* raw_pointer;
+void someFunction(P* p) {
+ ...
+ raw_pointer = p;
+ ...
+}
class A : public GarbageCollected<A>, public P {
public:
void someMemberFunction()
{
- someFunction(this); // DANGEROUS, a raw pointer to an on-heap object.
+ someFunction(this); // DANGEROUS, a raw pointer to an on-heap object. Object might be collected, resulting in a dangling pointer and possible memory corruption.
}
};
```
### GarbageCollectedMixin
-A non-leftmost base class of a garbage-collected class may derive from `GarbageCollectedMixin`. If a direct child
-class of `GarbageCollected<T>` has a non-leftmost base class deriving from `GarbageCollectedMixin`, the
-garbage-collected class must declare the `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` macro in its class declaration.
+A non-leftmost base class of a garbage-collected class should derive from `GarbageCollectedMixin`.
+If a child class of `GarbageCollected<T>` has a non-leftmost base class deriving from `GarbageCollectedMixin`, the garbage-collected class must declare the `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` macro in its class declaration.
-A class deriving from `GarbageCollectedMixin` can be treated similarly as garbage-collected classes. Specifically, it
-can have `Member<T>`s and `WeakMember<T>`s, and a tracing method. A pointer to such a class must be retained in the
-same smart pointer wrappers as a pointer to a garbage-collected class, such as `Member<T>` or `Persistent<T>`.
-The tracing method of a garbage-collected class, if any, must contain a delegating call for each mixin base class.
+A class deriving from `GarbageCollectedMixin` can be treated similarly as garbage-collected classes.
+Specifically, it can have `Member<T>`s and `WeakMember<T>`s, and a tracing method.
+A pointer to such a class must be retained in the same smart pointer wrappers as a pointer to a garbage-collected class, such as `Member<T>` or `Persistent<T>`.
+The [tracing](#Tracing) method of a garbage-collected class, if any, must contain a delegating call for each mixin base class.
```c++
class P : public GarbageCollectedMixin {
public:
- // OK, needs to trace q_.
+ // OK: Needs to trace q_.
virtual void Trace(Visitor* visitor) { visitor->Trace(q_); }
private:
- // OK, allowed to have Member<T>.
+ // OK: Allowed to have Member<T>.
Member<Q> q_;
};
-class A : public GarbageCollected<A>, public P {
+class A final : public GarbageCollected<A>, public P {
USING_GARBAGE_COLLECTED_MIXIN(A);
public:
// Delegating call for P is needed.
- virtual void Trace(Visitor* visitor) { ...; P::Trace(visitor); }
- ...
+ virtual void Trace(Visitor* visitor) { P::Trace(visitor); }
};
```
-Internally, `GarbageCollectedMixin` defines pure virtual functions, and `USING_GARBAGE_COLLECTED_MIXIN(ClassName)`
-implements these virtual functions. Therefore, you cannot instantiate a class that is a descendant of
-`GarbageCollectedMixin` but not a descendant of `GarbageCollected<T>`. Two or more base classes inheritng from
-`GarbageCollectedMixin` can be resolved with a single `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` declaration.
+Internally, `GarbageCollectedMixin` defines pure virtual functions, and `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` implements these virtual functions.
+Therefore, you cannot instantiate a class that is a descendant of `GarbageCollectedMixin` but not a descendant of `GarbageCollected<T>`.
+Two or more base classes inheritng from `GarbageCollectedMixin` can be resolved with a single `USING_GARBAGE_COLLECTED_MIXIN(ClassName)` declaration.
```c++
class P : public GarbageCollectedMixin { };
@@ -121,17 +117,18 @@ class Q : public GarbageCollectedMixin { };
class R : public Q { };
class A : public GarbageCollected<A>, public P, public R {
- USING_GARBAGE_COLLECTED_MIXIN(A); // OK, resolving pure virtual functions of P and R.
+ USING_GARBAGE_COLLECTED_MIXIN(A);
+ // OK: Resolving pure virtual functions of P and R.
};
class B : public GarbageCollected<B>, public P {
- USING_GARBAGE_COLLECTED_MIXIN(B); // OK, different garbage-collected classes may inherit from the same mixin (P).
+ USING_GARBAGE_COLLECTED_MIXIN(B);
+ // OK: Different garbage-collected classes may inherit from the same mixin (P).
};
-void someFunction()
-{
- MakeGarbageCollected<A>(); // OK, A can be instantiated.
- // MakeGarbageCollected<R>(); // BAD, R has pure virtual functions.
+void foo() {
+ MakeGarbageCollected<A>(); // OK: A can be instantiated.
+ // MakeGarbageCollected<R>(); // BAD: R has pure virtual functions.
}
```
@@ -146,8 +143,7 @@ See [GarbageCollectedMixin](#GarbageCollectedMixin) for the use of `GarbageColle
### USING_PRE_FINALIZER
-`USING_PRE_FINALIZER(ClassName, FunctionName)` in a class declaration declares the class has a *pre-finalizer* of name
-`FunctionName`.
+`USING_PRE_FINALIZER(ClassName, FunctionName)` in a class declaration declares the class has a *pre-finalizer* of name `FunctionName`.
A pre-finalizer must have the function signature `void()` but can have any name.
A pre-finalizer is a user-defined member function of a garbage-collected class that is called when the object is going to be reclaimed.
@@ -205,12 +201,11 @@ Especially, avoid defining a pre-finalizer in a class that can be allocated a lo
### STACK_ALLOCATED
-Class level annotation that should be used if the object is only stack allocated; it disallows use
-of `operator new`. Any garbage-collected objects should be kept as `Member<T>` references, but you do not
-need to define a `Trace()` method as they are on the stack, and automatically traced and kept alive should
-a conservative GC be required.
+Class level annotation that should be used if the object is only stack allocated; it disallows use of `operator new`. Any fields holding garbage-collected objects should use `Member<T>` references, but you do not need to define a `Trace()` method as they are on the stack, and automatically traced and kept alive should a conservative GC be required.
+
+Classes with this annotation do not need a `Trace()` method and must not inherit a on-heap garbage collected class.
-Classes with this annotation do not need a `Trace()` method, and should not inherit a garbage collected class.
+Marking a class as STACK_ALLOCATED implicitly implies [DISALLOW_NEW](#DISALLOW_NEW).
### DISALLOW_NEW
@@ -222,7 +217,6 @@ part object must call upon. The clang Blink GC plugin checks and enforces this.
Classes with this annotation need a `Trace()` method, but should not inherit a garbage collected class.
-
## Handles
Class templates in this section are smart pointers, each carrying a pointer to an on-heap object (think of `scoped_refptr<T>`
@@ -232,11 +226,11 @@ On-heap objects must be retained by any of these, depending on the situation.
### Raw pointers
-On-stack references to on-heap objects must be raw pointers.
+Raw pointers to garbage-collected objects should be avoided as they may cause memory corruptions.
+An exception to this rule is on-stack references to on-heap objects (including function parameters and return types) which must be raw pointers.
```c++
-void someFunction()
-{
+void someFunction() {
SomeGarbageCollectedClass* object = MakeGarbageCollected<SomeGarbageCollectedClass>(); // OK, retained by a pointer.
...
}
@@ -274,6 +268,15 @@ Otherwise, `Member<T>` should be used.
You need to trace every `Member<T>` and `WeakMember<T>` in your class. See [Tracing](#Tracing).
+### UntracedMember
+
+`UntracedMember<T>` represents a reference to a garbage collected object which is ignored by Oilpan.
+
+Unlike 'Member<T>', 'UntracedMember<T>' will not keep an object alive. However, unlike 'WeakMember<T>', the reference will not be cleared (i.e. set to 'nullptr') if the referenced object dies.
+Furthermore, class fields of type 'UntracedMember<T>' should not be traced by the class' tracing method.
+
+Users should use 'UntracedMember<T>' when implementing [custom weakness semantics](#Custom weak callbacks).
+
### Persistent, WeakPersistent, CrossThreadPersistent, CrossThreadWeakPersistent
In a non-garbage-collected class, on-heap objects must be retained by `Persistent<T>`, `WeakPersistent<T>`,
@@ -319,16 +322,15 @@ are really necessary.
## Tracing
-A garbage-collected class may need to have *a tracing method*, which lists up all the on-heap objects it has. The
-tracing method is called when the garbage collector needs to determine (1) all the on-heap objects referred from a
-live object, and (2) all the weak handles that may be filled with `nullptr` later. These are done in the "marking"
-phase of the mark-and-sweep GC.
+A garbage-collected class is required to have *a tracing method*, which lists up all the on-heap objects it has.
+The tracing method is called when the garbage collector needs to determine (1) all the on-heap objects referred from a
+live object, and (2) all the weak handles that may be filled with `nullptr` later.
The basic form of tracing is illustrated below:
```c++
// In a header file:
-class SomeGarbageCollectedClass
+class SomeGarbageCollectedClass final
: public GarbageCollected<SomeGarbageCollectedClass> {
public:
void Trace(Visitor*);
@@ -343,37 +345,31 @@ void SomeGarbageCollectedClass::Trace(Visitor* visitor) {
}
```
-Specifically, if your class needs a tracing method, you need to declare and
-define a `Trace(Visitor*)` method. This method is normally declared in the
-header file and defined once in the implementation file, but there are
-variations. Another common variation is to declare a virtual `Trace()` for base
-classes that will be subclassed.
+Specifically, if your class needs a tracing method, you need to declare and define a `Trace(Visitor*)` method.
+This method is normally declared in the header file and defined once in the implementation file, but there are variations.
+Another common variation is to declare a virtual `Trace()` for base classes that will be subclassed.
The function implementation must contain:
-
-* For each on-heap object `object` in your class, a tracing call: `visitor->Trace(object_);`.
-* If your class has one or more weak references (`WeakMember<T>`), you have the option of
- registering a *weak callback* for the object. See details below for how.
-* For each base class of your class `BaseClass` that is a descendant of `GarbageCollected<T>` or
- `GarbageCollectedMixin`, a delegation call to base class: `BaseClass::Trace(visitor);`"
-
+- For each on-heap object `object` in your class, a tracing call: `visitor->Trace(object);`.
+- For each base class of your class `BaseClass` that is a descendant of `GarbageCollected<T>` or `GarbageCollectedMixin`, a delegation call to base class: `BaseClass::Trace(visitor)`.
It is recommended that the delegation call, if any, is put at the end of a tracing method.
+- See [Advanced weak handling](#Advanced%20Weak%20Handling) for implementing non-trivial weakness.
The following example shows more involved usage:
```c++
class A : public GarbageCollected<A> {
public:
- virtual void Trace(Visitor*) { } // Nothing to trace here.
+ virtual void Trace(Visitor*) {} // Nothing to trace here.
};
class B : public A {
// Nothing to trace here; exempted from having a tracing method.
};
-class C : public B {
+class C final : public B {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) final;
private:
Member<X> x_;
@@ -389,110 +385,124 @@ void C::Trace(Visitor* visitor) {
}
```
-Given that the class `C` above contained a `WeakMember<Y>` field, you could alternatively
-register a *weak callback* in the trace method, and have it be invoked after the marking
-phase:
-
-```c++
-
-void C::ClearWeakMembers(Visitor* visitor)
-{
- if (ThreadHeap::isHeapObjectAlive(y_))
- return;
-
- // |y_| is not referred to by anyone else, clear the weak
- // reference along with updating state / clearing any other
- // resources at the same time. None of those operations are
- // allowed to perform heap allocations:
- y_->detach();
-
- // Note: if the weak callback merely clears the weak reference,
- // it is much simpler to just |trace| the field rather than
- // install a custom weak callback.
- y_ = nullptr;
-}
-
-void C::Trace(Visitor* visitor) {
- visitor->template registerWeakMembers<C, &C::ClearWeakMembers>(this);
- visitor->Trace(x_);
- visitor->Trace(z_); // Heap collection does, too.
- B::Trace(visitor); // Delegate to the parent. In this case it's empty, but this is required.
-}
-```
-
-Please notice that if the object (of type `C`) is also not reachable, its `Trace` method
-will not be invoked and any follow-on weak processing will not be done. Hence, if the
-object must always perform some operation when the weak reference is cleared, that
-needs to (also) happen during finalization.
-
-Weak callbacks have so far seen little use in Blink, but a mechanism that's available.
-
## Heap collections
-Heap collections are WTF collection types that support `Member<T>`, `WeakMember<T>`(see [below](#Weak collections)), and garbage collected objects as its elements.
+Oilpan, like any other managed runtime library, provides basic support for collections that integrate its managed types `Member<T>` and `WeakMember<T>`.
+Do not use heap collection with persistent types (e.g. HeapVector<Persistent<T>>).
-Here is the complete list:
+Collections compared to other libraries used in Blink:
-- WTF::Vector → blink::HeapVector
-- WTF::Deque → blink::HeapDeque
-- WTF::HashMap → blink::HeapHashMap
-- WTF::HashSet → blink::HeapHashSet
-- WTF::LinkedHashSet → blink::HeapLinkedHashSet
-- WTF::ListHashSet → blink::HeapListHashSet
-- WTF::HashCountedSet → blink::HeapHashCountedSet
+| stdlib | WTF | Oilpan |
+| ------------------ | ------------------- | ------------------------- |
+| std::vector | WTF::Vector | blink::HeapVector |
+| std::deque | WTF::Deque | blink::HeapDeque |
+| std::unordered_map | WTF::HashMap | blink::HeapHashMap |
+| std::unordered_set | WTF::HashSet | blink::HeapHashSet |
+| - | WTF::LinkedHashSet | blink::HeapLinkedHashSet |
+| - | WTF::ListHashSet | blink::HeapListHashSet |
+| - | WTF::HashCountedSet | blink::HeapHashCountedSet |
-These heap collections work mostly the same way as their WTF collection counterparts but there are some things to keep in mind.
-
-Heap collections are special in that the types themselves do not inherit from GarbageCollected (hence they are not allocated on the Oilpan heap) but they still *need to be traced* from the trace method (because we need to trace the backing store which is on the Oilpan heap).
+These heap collections work mostly the same way as their stdlib or WTF collection counterparts but there are some things to keep in mind.
+Heap collections do not inherit from `GarbageCollected` but are nonetheless allocated on-heap and thus must be properly traced from a `Trace` method.
```c++
-class MyGarbageCollectedClass : public GarbageCollected<MyGarbageCollectedClass> {
+class A final : public GarbageCollected<A> {
public:
- void Trace(Visitor* visitor) { visitor->Trace(list_); }
+ void Trace(Visitor* visitor) { visitor->Trace(vec_); }
private:
- HeapVector<Member<AnotherGarbageCollectedClass>> list_;
+ HeapVector<Member<B>> vec_;
};
```
-When you want to add a heap collection as a member of a non-garbage-collected class (on the main thread), please use a Persistent to reference it.
+Like any other object, they may be referred to from a non-garbage-collected class using `Persistent`.
```c++
-class MyNotGarbageCollectedClass {
+class NonGCed final {
private:
- Persistent<HeapVector<Member<MyGarbageCollectedClass>>> list_;
+ Persistent<HeapVector<Member<B>>> vec_;
};
```
-On non-main threads these persistent heap collections have been disabled to simplify the thread termination sequence. Please wrap the heap collections in a `Persistent` instead.
+## Advanced weak handling
-Please be very cautious if you want to use a heap collection from multiple threads. Reference to heap collections may be passed to another thread using CrossThreadPersistents, but *you may not modify the collection from the non-owner thread*. This is because modifications to collections may trigger backing store reallocations, and Oilpan's per thread heap requires that modifications to a heap happen on its owner thread.
+In addition to basic weak handling using `WeakMember<T>` Oilpan also supports:
+- Weak collections
+- Custom weak callbacks
### Weak collections
-You can put `WeakMember<T>` in heap collections except for `HeapVector` and `HeapDeque` which we do not support.
+Like regular weakness, collections support weakness by putting references in `WeakMember<T>`.
-During an Oilpan GC, the weak members that refernce a collected object will be removed from its heap collection, meaning the size of the collection will shrink and you do not have to check for null weak members when iterating through the collection.
+In sequence containers such as `HeapVector` the `WeakMember<T>` references are just cleared without adding any additional handling (cleared references are not automatically removed from the container).
-## Traits helpers
+In associative containers such as `HeapHashMap` or `HeapHashSet` Oilpan distinguishes between *pure weakness* and *mixed weakness*:
+- Pure weakness: All entries in such containers are wrapped in `WeakMember<T>`.
+ Examples are `HeapHashSet<WeakMember<T>>` and `HeapHashMap<WeakMember<T>, WeakMember<U>>`.
+- Mixed weakness: Only some entries in such containers are wrapped in `WeakMember<T>`.
+ This can only happen in `HeapHashMap`.
+ Examples are `HeapHashMap<WeakMember<T>, Member<U>>, HeapHashMap<Member<T>, WeakMember<U>>, HeapHashMap<WeakMember<T>, int>, and HeapHashMap<int, WeakMember<T>>.
+ Note that in the last example the type `int` is traced even though it does not support tracing.
-At times, one may be working on code that needs to deal with both "regular" types and classes managed by the Blink GC. The following helpers can aid in writing code that needs to use different wrappers and containers based on whether a type is managed by Oilpan.
+The semantics then are as follows:
+- Pure weakness: Oilpan will automatically remove the entries from the container if any of its declared `WeakMember<T>` fields points to a dead object.
+- Mixed weakness: Oilpan applies ephemeron semantics meaning that the strong parts of an entry are only treated as strong if the `WeakMember<T>` fields point to a live object.
-### AddMemberIfNeeded<T>
+### Custom weak callbacks
+
+In case very specific weakness semantics are required Oilpan allows adding custom weakness callbacks through its tracing method.
+
+There exist two helper methods on `blink::Visitor` to add such callbacks:
+- `RegisterWeakCallback`: Used to add custom weak callbacks of the form `void(void*, const blink::WeakCallbackInfo&)`.
+- `RegisterWeakCallbackMethod`: Helper for adding an instance method.
+
+Note that custom weak callbacks should not be used to clear `WeakMember<T>` fields as such fields are automatically handled by Oilpan.
+Instead, for managed fields that require custom weakness semantics, users should wrap such fields in `UntracedMember<T>` indicating that Oilpan is ignoring those fields.
-Given a type `T`, defines a type alias that is either `Member<T>` or `T` depending on whether `T` is a type managed by the Blink GC.
+The following example shows how this can be used:
```c++
-class MyGarbageCollectedClass : public GarbageCollected<MyGarbageCollectedClass> {
- // ...
-};
-class MyNotGarbageCollectedClass {
- // ...
+class W final : public GarbageCollected<W> {
+ public:
+ virtual void Trace(Visitor*);
+ private:
+ void ProcessCustomWeakness(const WeakCallbackInfo&);
+
+ UntracedMember<C> other_;
};
-AddMemberIfNeeded<MyNotGarbageCollectedClass> v1; // MyNotGarbageCollectedClass v1;
-AddMemberIfNeeded<int32_t> v2; // int32_t v2;
-AddMemberIfNeeded<MyGarbageCollectedClass> v3; // Member<MyGarbageCollectedClass> v3;
+void W::Trace(Visitor* visitor) {
+ visitor->template RegisterCustomWeakMethod<W, &W::ProcessCustomWeakness>(this);
+}
+
+void W::ProcessCustomWeakness(const WeakCallbackInfo& info) {
+ if (info.IsHeapObjectAlive(other_)) {
+ // Do something with other_.
+ }
+ other_ = nullptr;
+}
+```
+
+Note that the custom weakness callback in this example is only executed if `W` is alive and properly traced.
+If `W` itself dies than the callback will not be executed.
+Operations that must always happen should instead go into destructors or pre-finalizers.
+
+## Traits helpers
+
+At times, one may be working on code that needs to deal with both, off heap and on heap, objects.
+The following helpers can aid in writing code that needs to use different wrappers and containers based on whether a type is managed by Oilpan.
+
+### AddMemberIfNeeded<T>
+
+Given a type `T`, defines a type alias that is either `Member<T>` or `T` depending on whether `T` is a type managed by Oilpan.
+
+```c++
+class A final : public GarbageCollected<A> {};
+class B final {};
+
+AddMemberIfNeeded<B> v1; // B v1;
+AddMemberIfNeeded<int32_t> v2; // int32_t v2;
+AddMemberIfNeeded<A> v3; // Member<A> v3;
```
### VectorOf<T>
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache.cc b/chromium/third_party/blink/renderer/platform/heap/address_cache.cc
deleted file mode 100644
index fb93fbcbe22..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache.cc
+++ /dev/null
@@ -1,68 +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 "third_party/blink/renderer/platform/heap/address_cache.h"
-
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-
-namespace blink {
-
-AddressCache::EnabledScope::EnabledScope(AddressCache* address_cache)
- : address_cache_(address_cache) {
- address_cache_->FlushIfDirty();
- address_cache_->EnableLookup();
-}
-
-AddressCache::EnabledScope::~EnabledScope() {
- address_cache_->DisableLookup();
-}
-
-void AddressCache::Flush() {
- if (has_entries_) {
- for (size_t i = 0; i < kNumberOfEntries; ++i)
- entries_[i] = nullptr;
- has_entries_ = false;
- }
- dirty_ = false;
-}
-
-void AddressCache::FlushIfDirty() {
- if (dirty_) {
- Flush();
- dirty_ = false;
- }
-}
-
-size_t AddressCache::GetHash(Address address) {
- size_t value = (reinterpret_cast<size_t>(address) >> kBlinkPageSizeLog2);
- value ^= value >> kNumberOfEntriesLog2;
- value ^= value >> (kNumberOfEntriesLog2 * 2);
- value &= kNumberOfEntries - 1;
- return value & ~1; // Returns only even number.
-}
-
-bool AddressCache::Lookup(Address address) {
- DCHECK(enabled_);
- DCHECK(!dirty_);
-
- size_t index = GetHash(address);
- DCHECK(!(index & 1));
- Address cache_page = RoundToBlinkPageStart(address);
- if (entries_[index] == cache_page)
- return entries_[index];
- if (entries_[index + 1] == cache_page)
- return entries_[index + 1];
- return false;
-}
-
-void AddressCache::AddEntry(Address address) {
- has_entries_ = true;
- size_t index = GetHash(address);
- DCHECK(!(index & 1));
- Address cache_page = RoundToBlinkPageStart(address);
- entries_[index + 1] = entries_[index];
- entries_[index] = cache_page;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache.h b/chromium/third_party/blink/renderer/platform/heap/address_cache.h
deleted file mode 100644
index 5ccea412d2e..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_
-
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-// Negative cache for addresses outside of Blink's garbage collected heap.
-// - Internally maps to pages (NormalPage) to cover a larger range of addresses.
-// - Requires flushing when adding new addresses.
-class PLATFORM_EXPORT AddressCache {
- USING_FAST_MALLOC(AddressCache);
-
- public:
- class PLATFORM_EXPORT EnabledScope {
- STACK_ALLOCATED();
-
- public:
- explicit EnabledScope(AddressCache*);
- ~EnabledScope();
-
- private:
- AddressCache* const address_cache_;
- };
-
- AddressCache()
- : entries_{}, enabled_(false), has_entries_(false), dirty_(false) {}
-
- void EnableLookup() { enabled_ = true; }
- void DisableLookup() { enabled_ = false; }
-
- void MarkDirty() { dirty_ = true; }
- void Flush();
- void FlushIfDirty();
- bool IsEmpty() const { return !has_entries_; }
-
- // Perform a lookup in the cache. Returns true if the address is guaranteed
- // to not in Blink's heap and false otherwise.
- bool Lookup(Address);
-
- // Add an entry to the cache.
- void AddEntry(Address);
-
- private:
- static constexpr size_t kNumberOfEntriesLog2 = 12;
- static constexpr size_t kNumberOfEntries = 1 << kNumberOfEntriesLog2;
-
- static size_t GetHash(Address);
-
- Address entries_[kNumberOfEntries];
- bool enabled_ : 1;
- bool has_entries_ : 1;
- bool dirty_ : 1;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc b/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc
deleted file mode 100644
index 280920dd1c4..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc
+++ /dev/null
@@ -1,80 +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 "third_party/blink/renderer/platform/heap/address_cache.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-
-namespace blink {
-
-namespace {
-
-const Address kObjectAddress = reinterpret_cast<Address>(kBlinkPageSize);
-
-} // namespace
-
-TEST(AddressCacheTest, Scope) {
- AddressCache cache;
- AddressCache::EnabledScope scope(&cache);
- EXPECT_FALSE(cache.Lookup(kObjectAddress));
-}
-
-TEST(AddressCacheTest, InitialIsEmpty) {
- AddressCache cache;
- cache.EnableLookup();
- EXPECT_TRUE(cache.IsEmpty());
-}
-
-TEST(AddressCacheTest, LookupOnEmpty) {
- AddressCache cache;
- cache.EnableLookup();
- EXPECT_FALSE(cache.Lookup(kObjectAddress));
-}
-
-TEST(AddressCacheTest, LookupAfterAddEntry) {
- AddressCache cache;
- cache.EnableLookup();
- cache.AddEntry(kObjectAddress);
- EXPECT_TRUE(cache.Lookup(kObjectAddress));
-}
-
-TEST(AddressCacheTest, AddEntryAddsWholePage) {
- AddressCache cache;
- cache.EnableLookup();
- cache.AddEntry(kObjectAddress);
- for (Address current = kObjectAddress;
- current < (kObjectAddress + kBlinkPageSize); current++) {
- EXPECT_TRUE(cache.Lookup(current));
- }
-}
-
-TEST(AddressCacheTest, AddEntryOnlyAddsPageForGivenAddress) {
- AddressCache cache;
- cache.EnableLookup();
- cache.AddEntry(kObjectAddress);
- EXPECT_FALSE(cache.Lookup(kObjectAddress - 1));
- EXPECT_FALSE(cache.Lookup(kObjectAddress + kBlinkPageSize + 1));
-}
-
-TEST(AddressCacheTest, FlushIfDirtyIgnoresNonDirty) {
- AddressCache cache;
- cache.EnableLookup();
- cache.AddEntry(kObjectAddress);
- cache.FlushIfDirty();
- // Cannot do lookup in dirty cache.
- EXPECT_FALSE(cache.IsEmpty());
-}
-
-TEST(AddressCacheTest, FlushIfDirtyHandlesDirty) {
- AddressCache cache;
- cache.EnableLookup();
- cache.AddEntry(kObjectAddress);
- cache.MarkDirty();
- cache.FlushIfDirty();
- // Cannot do lookup in dirty cache.
- EXPECT_TRUE(cache.IsEmpty());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
index 3eebe011100..a1ba0e53a23 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -14,6 +14,7 @@
namespace blink {
+class WeakCallbackInfo;
class MarkingVisitor;
class Visitor;
@@ -23,7 +24,7 @@ using FinalizationCallback = void (*)(void*);
using VisitorCallback = void (*)(Visitor*, void*);
using MarkingVisitorCallback = void (*)(MarkingVisitor*, void*);
using TraceCallback = VisitorCallback;
-using WeakCallback = VisitorCallback;
+using WeakCallback = void (*)(const WeakCallbackInfo&, void*);
using EphemeronCallback = VisitorCallback;
// Simple alias to avoid heap compaction type signatures turning into
@@ -47,11 +48,7 @@ using MovingObjectCallback = void (*)(MovableReference from,
H(NormalPage2) \
H(NormalPage3) \
H(NormalPage4) \
- H(Vector1) \
- H(Vector2) \
- H(Vector3) \
- H(Vector4) \
- H(InlineVector) \
+ H(Vector) \
H(HashTable) \
H(Node) \
H(CSSValue) \
diff --git a/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
new file mode 100644
index 00000000000..af57b2607c2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
@@ -0,0 +1,212 @@
+// 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 "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+
+namespace blink {
+
+class ConcurrentMarkingTest : public TestSupportingGC {};
+
+namespace concurrent_marking_test {
+
+template <typename T>
+class CollectionWrapper : public GarbageCollected<CollectionWrapper<T>> {
+ public:
+ CollectionWrapper() : collection_(MakeGarbageCollected<T>()) {}
+
+ void Trace(Visitor* visitor) { visitor->Trace(collection_); }
+
+ T* GetCollection() { return collection_.Get(); }
+
+ private:
+ Member<T> collection_;
+};
+
+// =============================================================================
+// Tests that expose data races when modifying collections ================
+// =============================================================================
+
+TEST_F(ConcurrentMarkingTest, AddToHashMap) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Map>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Map>>();
+ Map* map = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ int num = 100 * i + j;
+ map->insert(MakeGarbageCollected<IntegerObject>(num),
+ MakeGarbageCollected<IntegerObject>(num));
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, RemoveFromHashMap) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Map>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Map>>();
+ Map* map = persistent->GetCollection();
+ for (int i = 0; i < 10000; ++i) {
+ map->insert(MakeGarbageCollected<IntegerObject>(i),
+ MakeGarbageCollected<IntegerObject>(i));
+ }
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ map->erase(map->begin());
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, SwapHashMaps) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Map>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Map>>();
+ Map* map = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ Map new_map;
+ for (int j = 0; j < 10 * i; ++j) {
+ new_map.insert(MakeGarbageCollected<IntegerObject>(j),
+ MakeGarbageCollected<IntegerObject>(j));
+ }
+ driver.SingleConcurrentStep();
+ map->swap(new_map);
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, AddToHashSet) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Set = HeapHashSet<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Set>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Set>>();
+ Set* set = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ int num = 100 * i + j;
+ set->insert(MakeGarbageCollected<IntegerObject>(num));
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, RemoveFromHashSet) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Set = HeapHashSet<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Set>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Set>>();
+ Set* set = persistent->GetCollection();
+ for (int i = 0; i < 10000; ++i) {
+ set->insert(MakeGarbageCollected<IntegerObject>(i));
+ }
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ set->erase(set->begin());
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, SwapHashSets) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using Set = HeapHashSet<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<Set>> persistent =
+ MakeGarbageCollected<CollectionWrapper<Set>>();
+ Set* set = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ Set new_set;
+ for (int j = 0; j < 10 * i; ++j) {
+ new_set.insert(MakeGarbageCollected<IntegerObject>(j));
+ }
+ driver.SingleConcurrentStep();
+ set->swap(new_set);
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, AddToVector) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using V = HeapVector<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<V>> persistent =
+ MakeGarbageCollected<CollectionWrapper<V>>();
+ V* vector = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ int num = 100 * i + j;
+ vector->push_back(MakeGarbageCollected<IntegerObject>(num));
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, RemoveFromVector) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using V = HeapVector<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<V>> persistent =
+ MakeGarbageCollected<CollectionWrapper<V>>();
+ V* vector = persistent->GetCollection();
+ for (int i = 0; i < 10000; ++i) {
+ vector->push_back(MakeGarbageCollected<IntegerObject>(i));
+ }
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ driver.SingleConcurrentStep();
+ for (int j = 0; j < 100; ++j) {
+ vector->pop_back();
+ }
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST_F(ConcurrentMarkingTest, SwapVectors) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ using V = HeapVector<Member<IntegerObject>>;
+ Persistent<CollectionWrapper<V>> persistent =
+ MakeGarbageCollected<CollectionWrapper<V>>();
+ V* vector = persistent->GetCollection();
+ driver.Start();
+ for (int i = 0; i < 100; ++i) {
+ V new_vector;
+ for (int j = 0; j < 10 * i; ++j) {
+ new_vector.push_back(MakeGarbageCollected<IntegerObject>(j));
+ }
+ driver.SingleConcurrentStep();
+ vector->swap(new_vector);
+ }
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+} // namespace concurrent_marking_test
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
index 118cadb044e..f17c43066dd 100644
--- a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
+++ b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
@@ -11,7 +11,8 @@ namespace blink {
// DisallowNewWrapper wraps a disallow new type in a GarbageCollected class.
template <typename T>
-class DisallowNewWrapper : public GarbageCollected<DisallowNewWrapper<T>> {
+class DisallowNewWrapper final
+ : public GarbageCollected<DisallowNewWrapper<T>> {
public:
explicit DisallowNewWrapper(const T& value) : value_(value) {
static_assert(WTF::IsDisallowNew<T>::value,
diff --git a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
index d96e35642b4..03ff1d959fb 100644
--- a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
@@ -38,18 +38,27 @@ template <typename T>
struct FinalizerTraitImpl<T, true> {
private:
STATIC_ONLY(FinalizerTraitImpl);
- struct CustomDispatch {
+ struct Custom {
static void Call(void* obj) {
static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
}
};
- struct DestructorDispatch {
- static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
+ struct Destructor {
+ static void Call(void* obj) {
+// The garbage collector differs from regular C++ here as it remembers whether
+// an object's base class has a virtual destructor. In case there is no virtual
+// destructor present, the object is always finalized through its leaf type. In
+// other words: there is no finalization through a base pointer.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdelete-non-abstract-non-virtual-dtor"
+ static_cast<T*>(obj)->~T();
+#pragma GCC diagnostic pop
+ }
};
using FinalizeImpl =
std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value,
- CustomDispatch,
- DestructorDispatch>;
+ Custom,
+ Destructor>;
public:
static void Finalize(void* obj) {
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.h b/chromium/third_party/blink/renderer/platform/heap/gc_info.h
index fa960e46af7..36b53cc0c17 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.h
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.h
@@ -93,11 +93,9 @@ class PLATFORM_EXPORT GCInfoTable {
Mutex table_mutex_;
};
-// GCInfoAtBaseType should be used when returning a unique 14 bit integer
-// for a given gcInfo.
template <typename T>
-struct GCInfoAtBaseType {
- STATIC_ONLY(GCInfoAtBaseType);
+struct GCInfoTrait {
+ STATIC_ONLY(GCInfoTrait);
static uint32_t Index() {
static_assert(sizeof(T), "T must be fully defined");
static const GCInfo kGcInfo = {
@@ -117,31 +115,6 @@ struct GCInfoAtBaseType {
}
};
-template <typename T,
- bool = WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type,
- GarbageCollected>::value>
-struct GetGarbageCollectedType;
-
-template <typename T>
-struct GetGarbageCollectedType<T, true> {
- STATIC_ONLY(GetGarbageCollectedType);
- using type = typename T::GarbageCollectedType;
-};
-
-template <typename T>
-struct GetGarbageCollectedType<T, false> {
- STATIC_ONLY(GetGarbageCollectedType);
- using type = T;
-};
-
-template <typename T>
-struct GCInfoTrait {
- STATIC_ONLY(GCInfoTrait);
- static uint32_t Index() {
- return GCInfoAtBaseType<typename GetGarbageCollectedType<T>::type>::Index();
- }
-};
-
template <typename U>
class GCInfoTrait<const U> : public GCInfoTrait<U> {};
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h b/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
index 9bbc3023480..b00f3b24d1f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
@@ -51,7 +51,7 @@ class GCTaskObserver final : public Thread::TaskObserver {
DCHECK(!nesting_ || nesting_ == 1);
}
- void WillProcessTask(const base::PendingTask&) override { nesting_++; }
+ void WillProcessTask(const base::PendingTask&, bool) override { nesting_++; }
void DidProcessTask(const base::PendingTask&) override {
// In the production code WebKit::initialize is called from inside the
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.cc b/chromium/third_party/blink/renderer/platform/heap/heap.cc
index af6f4b3903f..6f4ce3f280d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.cc
@@ -39,11 +39,11 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
-#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/page_bloom_filter.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
@@ -95,18 +95,9 @@ ThreadHeap::ThreadHeap(ThreadState* thread_state)
: thread_state_(thread_state),
heap_stats_collector_(std::make_unique<ThreadHeapStatsCollector>()),
region_tree_(std::make_unique<RegionTree>()),
- address_cache_(std::make_unique<AddressCache>()),
+ page_bloom_filter_(std::make_unique<PageBloomFilter>()),
free_page_pool_(std::make_unique<PagePool>()),
- process_heap_reporter_(std::make_unique<ProcessHeapReporter>()),
- marking_worklist_(nullptr),
- not_fully_constructed_worklist_(nullptr),
- weak_callback_worklist_(nullptr),
- movable_reference_worklist_(nullptr),
- weak_table_worklist_(nullptr),
- backing_store_callback_worklist_(nullptr),
- v8_references_worklist_(nullptr),
- vector_backing_arena_index_(BlinkGC::kVector1ArenaIndex),
- current_arena_ages_(0) {
+ process_heap_reporter_(std::make_unique<ProcessHeapReporter>()) {
if (ThreadState::Current()->IsMainThread())
main_thread_heap_ = this;
@@ -116,10 +107,6 @@ ThreadHeap::ThreadHeap(ThreadState* thread_state)
arenas_[BlinkGC::kLargeObjectArenaIndex] =
new LargeObjectArena(thread_state_, BlinkGC::kLargeObjectArenaIndex);
- likely_to_be_promptly_freed_ =
- std::make_unique<int[]>(kLikelyToBePromptlyFreedArraySize);
- ClearArenaAges();
-
stats_collector()->RegisterObserver(process_heap_reporter_.get());
}
@@ -133,31 +120,27 @@ Address ThreadHeap::CheckAndMarkPointer(MarkingVisitor* visitor,
DCHECK(thread_state_->InAtomicMarkingPause());
#if !DCHECK_IS_ON()
- if (address_cache_->Lookup(address))
+ if (!page_bloom_filter_->MayContain(address)) {
return nullptr;
+ }
#endif
if (BasePage* page = LookupPageForAddress(address)) {
#if DCHECK_IS_ON()
DCHECK(page->Contains(address));
#endif
- DCHECK(!address_cache_->Lookup(address));
+ DCHECK(page_bloom_filter_->MayContain(address));
DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap());
visitor->ConservativelyMarkAddress(page, address);
return address;
}
-#if !DCHECK_IS_ON()
- address_cache_->AddEntry(address);
-#else
- if (!address_cache_->Lookup(address))
- address_cache_->AddEntry(address);
-#endif
return nullptr;
}
void ThreadHeap::SetupWorklists() {
marking_worklist_.reset(new MarkingWorklist());
+ write_barrier_worklist_.reset(new WriteBarrierWorklist());
not_fully_constructed_worklist_.reset(new NotFullyConstructedWorklist());
previously_not_fully_constructed_worklist_.reset(
new NotFullyConstructedWorklist());
@@ -171,6 +154,7 @@ void ThreadHeap::SetupWorklists() {
void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
marking_worklist_.reset(nullptr);
+ write_barrier_worklist_.reset(nullptr);
previously_not_fully_constructed_worklist_.reset(nullptr);
weak_callback_worklist_.reset(nullptr);
weak_table_worklist_.reset();
@@ -261,17 +245,19 @@ void ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor) {
// Then we iterate over the new callbacks found by the marking visitor.
// Callbacks found by the concurrent marking will be flushed eventually
// and then invoked by the mutator thread (in the atomic pause at latest).
- while (!weak_table_worklist_->IsGlobalEmpty()) {
+ while (
+ !weak_table_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread)) {
// Read ephemeron callbacks from worklist to ephemeron_callbacks_ hashmap.
WeakTableWorklist::View ephemerons_worklist(weak_table_worklist_.get(),
WorklistTaskId::MutatorThread);
WeakTableItem item;
while (ephemerons_worklist.Pop(&item)) {
- auto result = ephemeron_callbacks_.insert(item.object, item.callback);
+ auto result =
+ ephemeron_callbacks_.insert(item.base_object_payload, item.callback);
DCHECK(result.is_new_entry ||
result.stored_value->value == item.callback);
if (result.is_new_entry) {
- item.callback(visitor, item.object);
+ item.callback(visitor, item.base_object_payload);
}
}
}
@@ -318,17 +304,32 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
finished = DrainWorklistWithDeadline(
deadline, marking_worklist_.get(),
[visitor](const MarkingItem& item) {
- DCHECK(!HeapObjectHeader::FromPayload(item.object)
- ->IsInConstruction());
- item.callback(visitor, item.object);
+ HeapObjectHeader* header =
+ HeapObjectHeader::FromPayload(item.base_object_payload);
+ DCHECK(!MarkingVisitor::IsInConstruction(header));
+ item.callback(visitor, item.base_object_payload);
+ visitor->AccountMarkedBytes(header);
+ },
+ WorklistTaskId::MutatorThread);
+ if (!finished)
+ break;
+
+ finished = DrainWorklistWithDeadline(
+ deadline, write_barrier_worklist_.get(),
+ [visitor](HeapObjectHeader* header) {
+ DCHECK(!MarkingVisitor::IsInConstruction(header));
+ GCInfoTable::Get()
+ .GCInfoFromIndex(header->GcInfoIndex())
+ ->trace(visitor, header->Payload());
+ visitor->AccountMarkedBytes(header);
},
WorklistTaskId::MutatorThread);
if (!finished)
break;
- // Iteratively mark all objects that were previously discovered while
- // being in construction. The objects can be processed incrementally once
- // a safepoint was reached.
+ // Convert |previously_not_fully_constructed_worklist_| to
+ // |marking_worklist_|. This merely re-adds items with the proper
+ // callbacks.
finished = DrainWorklistWithDeadline(
deadline, previously_not_fully_constructed_worklist_.get(),
[visitor](const NotFullyConstructedItem& item) {
@@ -342,7 +343,7 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
InvokeEphemeronCallbacks(visitor);
// Rerun loop if ephemeron processing queued more objects for tracing.
- } while (!marking_worklist_->IsGlobalEmpty());
+ } while (!marking_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread));
FlushV8References();
@@ -351,17 +352,33 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
base::TimeTicks deadline) {
+ bool finished = false;
// Iteratively mark all objects that are reachable from the objects
// currently pushed onto the marking worklist.
- return DrainWorklistWithDeadline(
+ finished = DrainWorklistWithDeadline(
deadline, marking_worklist_.get(),
[visitor](const MarkingItem& item) {
- DCHECK(
- !HeapObjectHeader::FromPayload(item.object)
- ->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
- item.callback(visitor, item.object);
+ HeapObjectHeader* header =
+ HeapObjectHeader::FromPayload(item.base_object_payload);
+ DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ item.callback(visitor, item.base_object_payload);
+ visitor->AccountMarkedBytes(header);
},
visitor->task_id());
+ if (!finished)
+ return false;
+
+ finished = DrainWorklistWithDeadline(
+ deadline, write_barrier_worklist_.get(),
+ [visitor](HeapObjectHeader* header) {
+ DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ GCInfoTable::Get()
+ .GCInfoFromIndex(header->GcInfoIndex())
+ ->trace(visitor, header->Payload());
+ visitor->AccountMarkedBytes(header);
+ },
+ visitor->task_id());
+ return finished;
}
void ThreadHeap::WeakProcessing(MarkingVisitor* visitor) {
@@ -376,8 +393,9 @@ void ThreadHeap::WeakProcessing(MarkingVisitor* visitor) {
// Call weak callbacks on objects that may now be pointing to dead objects.
CustomCallbackItem item;
+ WeakCallbackInfo broker;
while (weak_callback_worklist_->Pop(WorklistTaskId::MutatorThread, &item)) {
- item.callback(visitor, item.object);
+ item.callback(broker, item.parameter);
}
// Weak callbacks should not add any new objects for marking.
DCHECK(marking_worklist_->IsGlobalEmpty());
@@ -444,7 +462,7 @@ void ThreadHeap::Compact() {
// Compact the hash table backing store arena first, it usually has
// higher fragmentation and is larger.
- for (int i = BlinkGC::kHashTableArenaIndex; i >= BlinkGC::kVector1ArenaIndex;
+ for (int i = BlinkGC::kHashTableArenaIndex; i >= BlinkGC::kVectorArenaIndex;
--i)
static_cast<NormalPageArena*>(arenas_[i])->SweepAndCompact();
Compaction()->Finish();
@@ -474,54 +492,6 @@ void ThreadHeap::InvokeFinalizersOnSweptPages() {
arenas_[i]->InvokeFinalizersOnSweptPages();
}
-void ThreadHeap::ClearArenaAges() {
- memset(arena_ages_, 0, sizeof(size_t) * BlinkGC::kNumberOfArenas);
- memset(likely_to_be_promptly_freed_.get(), 0,
- sizeof(int) * kLikelyToBePromptlyFreedArraySize);
- current_arena_ages_ = 0;
-}
-
-int ThreadHeap::ArenaIndexOfVectorArenaLeastRecentlyExpanded(
- int begin_arena_index,
- int end_arena_index) {
- size_t min_arena_age = arena_ages_[begin_arena_index];
- int arena_index_with_min_arena_age = begin_arena_index;
- for (int arena_index = begin_arena_index + 1; arena_index <= end_arena_index;
- arena_index++) {
- if (arena_ages_[arena_index] < min_arena_age) {
- min_arena_age = arena_ages_[arena_index];
- arena_index_with_min_arena_age = arena_index;
- }
- }
- DCHECK(IsVectorArenaIndex(arena_index_with_min_arena_age));
- return arena_index_with_min_arena_age;
-}
-
-BaseArena* ThreadHeap::ExpandedVectorBackingArena(uint32_t gc_info_index) {
- uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
- --likely_to_be_promptly_freed_[entry_index];
- int arena_index = vector_backing_arena_index_;
- arena_ages_[arena_index] = ++current_arena_ages_;
- vector_backing_arena_index_ = ArenaIndexOfVectorArenaLeastRecentlyExpanded(
- BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex);
- return arenas_[arena_index];
-}
-
-void ThreadHeap::AllocationPointAdjusted(int arena_index) {
- arena_ages_[arena_index] = ++current_arena_ages_;
- if (vector_backing_arena_index_ == arena_index) {
- vector_backing_arena_index_ = ArenaIndexOfVectorArenaLeastRecentlyExpanded(
- BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex);
- }
-}
-
-void ThreadHeap::PromptlyFreed(uint32_t gc_info_index) {
- DCHECK(thread_state_->CheckThread());
- uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
- // See the comment in vectorBackingArena() for why this is +3.
- likely_to_be_promptly_freed_[entry_index] += 3;
-}
-
#if defined(ADDRESS_SANITIZER)
void ThreadHeap::PoisonUnmarkedObjects() {
// Poisoning all unmarked objects in the other arenas.
@@ -574,9 +544,9 @@ void ThreadHeap::FlushV8References() {
if (!thread_state_->IsUnifiedGCMarkingInProgress())
return;
- DCHECK(v8_references_worklist_->IsGlobalEmpty() ||
- base::FeatureList::IsEnabled(
- blink::features::kBlinkHeapConcurrentMarking));
+ DCHECK(base::FeatureList::IsEnabled(
+ blink::features::kBlinkHeapConcurrentMarking) ||
+ v8_references_worklist_->IsGlobalEmpty());
V8ReferencesWorklist::View v8_references(v8_references_worklist_.get(),
WorklistTaskId::MutatorThread);
@@ -585,7 +555,8 @@ void ThreadHeap::FlushV8References() {
reinterpret_cast<v8::EmbedderHeapTracer*>(
thread_state_->unified_heap_controller());
while (v8_references.Pop(&reference)) {
- controller->RegisterEmbedderReference(reference->Get());
+ controller->RegisterEmbedderReference(
+ reference->template Cast<v8::Data>().Get());
}
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h
index e5a7316a7d0..5fa69d97c07 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.h
@@ -56,19 +56,18 @@ namespace incremental_marking_test {
class IncrementalMarkingScopeBase;
} // namespace incremental_marking_test
-class AddressCache;
+namespace weakness_marking_test {
+class EphemeronCallbacksCounter;
+} // namespace weakness_marking_test
+
class ConcurrentMarkingVisitor;
class ThreadHeapStatsCollector;
+class PageBloomFilter;
class PagePool;
class ProcessHeapReporter;
class RegionTree;
-struct MarkingItem {
- void* object;
- TraceCallback callback;
-};
-
-using CustomCallbackItem = MarkingItem;
+using MarkingItem = TraceDescriptor;
using NotFullyConstructedItem = void*;
using WeakTableItem = MarkingItem;
@@ -77,11 +76,17 @@ struct BackingStoreCallbackItem {
MovingObjectCallback callback;
};
+struct CustomCallbackItem {
+ WeakCallback callback;
+ void* parameter;
+};
+
using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
// Segment size of 512 entries necessary to avoid throughput regressions. Since
// the work list is currently a temporary object this is not a problem.
using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>;
+using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 256>;
using NotFullyConstructedWorklist =
Worklist<NotFullyConstructedItem, 16 /* local entries */>;
using WeakCallbackWorklist =
@@ -227,6 +232,10 @@ class PLATFORM_EXPORT ThreadHeap {
return marking_worklist_.get();
}
+ WriteBarrierWorklist* GetWriteBarrierWorklist() const {
+ return write_barrier_worklist_.get();
+ }
+
NotFullyConstructedWorklist* GetNotFullyConstructedWorklist() const {
return not_fully_constructed_worklist_.get();
}
@@ -303,8 +312,6 @@ class PLATFORM_EXPORT ThreadHeap {
size_t ObjectPayloadSizeForTesting();
void ResetAllocationPointForTesting();
- AddressCache* address_cache() const { return address_cache_.get(); }
-
PagePool* GetFreePagePool() { return free_page_pool_.get(); }
// This look-up uses the region search tree and a negative contains cache to
@@ -323,60 +330,10 @@ class PLATFORM_EXPORT ThreadHeap {
return arenas_[arena_index];
}
- // VectorBackingArena() returns an arena that the vector allocation should
- // use. We have four vector arenas and want to choose the best arena here.
- //
- // The goal is to improve the succession rate where expand and
- // promptlyFree happen at an allocation point. This is a key for reusing
- // the same memory as much as possible and thus improves performance.
- // To achieve the goal, we use the following heuristics:
- //
- // - A vector that has been expanded recently is likely to be expanded
- // again soon.
- // - A vector is likely to be promptly freed if the same type of vector
- // has been frequently promptly freed in the past.
- // - Given the above, when allocating a new vector, look at the four vectors
- // that are placed immediately prior to the allocation point of each arena.
- // Choose the arena where the vector is least likely to be expanded
- // nor promptly freed.
- //
- // To implement the heuristics, we add an arenaAge to each arena. The arenaAge
- // is updated if:
- //
- // - a vector on the arena is expanded; or
- // - a vector that meets the condition (*) is allocated on the arena
- //
- // (*) More than 33% of the same type of vectors have been promptly
- // freed since the last GC.
- //
- BaseArena* VectorBackingArena(uint32_t gc_info_index) {
- DCHECK(thread_state_->CheckThread());
- uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
- --likely_to_be_promptly_freed_[entry_index];
- int arena_index = vector_backing_arena_index_;
- // If likely_to_be_promptly_freed_[entryIndex] > 0, that means that
- // more than 33% of vectors of the type have been promptly freed
- // since the last GC.
- if (likely_to_be_promptly_freed_[entry_index] > 0) {
- arena_ages_[arena_index] = ++current_arena_ages_;
- vector_backing_arena_index_ =
- ArenaIndexOfVectorArenaLeastRecentlyExpanded(
- BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex);
- }
- DCHECK(IsVectorArenaIndex(arena_index));
- return arenas_[arena_index];
- }
- BaseArena* ExpandedVectorBackingArena(uint32_t gc_info_index);
static bool IsVectorArenaIndex(int arena_index) {
- return BlinkGC::kVector1ArenaIndex <= arena_index &&
- arena_index <= BlinkGC::kVector4ArenaIndex;
+ return BlinkGC::kVectorArenaIndex == arena_index;
}
static bool IsNormalArenaIndex(int);
- void AllocationPointAdjusted(int arena_index);
- void PromptlyFreed(uint32_t gc_info_index);
- void ClearArenaAges();
- int ArenaIndexOfVectorArenaLeastRecentlyExpanded(int begin_arena_index,
- int end_arena_index);
void MakeConsistentForGC();
// MakeConsistentForMutator() drops marks from marked objects and rebuild
@@ -415,6 +372,8 @@ class PLATFORM_EXPORT ThreadHeap {
}
#endif
+ PageBloomFilter* page_bloom_filter() { return page_bloom_filter_.get(); }
+
private:
static int ArenaIndexForObjectSize(size_t);
@@ -429,7 +388,7 @@ class PLATFORM_EXPORT ThreadHeap {
ThreadState* thread_state_;
std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
std::unique_ptr<RegionTree> region_tree_;
- std::unique_ptr<AddressCache> address_cache_;
+ std::unique_ptr<PageBloomFilter> page_bloom_filter_;
std::unique_ptr<PagePool> free_page_pool_;
std::unique_ptr<ProcessHeapReporter> process_heap_reporter_;
@@ -438,6 +397,11 @@ class PLATFORM_EXPORT ThreadHeap {
// contain almost all objects.
std::unique_ptr<MarkingWorklist> marking_worklist_;
+ // Objects on this worklist have been collected in the write barrier. The
+ // worklist is different from |marking_worklist_| to minimize execution in the
+ // path where a write barrier is executed.
+ std::unique_ptr<WriteBarrierWorklist> write_barrier_worklist_;
+
// Objects on this worklist were observed to be in construction (in their
// constructor) and thus have been delayed for processing. They have not yet
// been assigned a valid header and trace callback.
@@ -479,18 +443,6 @@ class PLATFORM_EXPORT ThreadHeap {
std::unique_ptr<HeapCompact> compaction_;
BaseArena* arenas_[BlinkGC::kNumberOfArenas];
- int vector_backing_arena_index_;
- size_t arena_ages_[BlinkGC::kNumberOfArenas];
- size_t current_arena_ages_;
-
- // Ideally we want to allocate an array of size |gcInfoTableMax| but it will
- // waste memory. Thus we limit the array size to 2^8 and share one entry
- // with multiple types of vectors. This won't be an issue in practice,
- // since there will be less than 2^8 types of objects in common cases.
- static const int kLikelyToBePromptlyFreedArraySize = (1 << 8);
- static const int kLikelyToBePromptlyFreedArrayMask =
- kLikelyToBePromptlyFreedArraySize - 1;
- std::unique_ptr<int[]> likely_to_be_promptly_freed_;
static ThreadHeap* main_thread_heap_;
@@ -498,6 +450,7 @@ class PLATFORM_EXPORT ThreadHeap {
template <typename T>
friend class Member;
friend class ThreadState;
+ friend class weakness_marking_test::EphemeronCallbacksCounter;
};
template <typename T>
@@ -518,22 +471,43 @@ class GarbageCollected {
#endif
public:
- using GarbageCollectedType = T;
+ using ParentMostGarbageCollectedType = T;
void* operator new(size_t size) = delete; // Must use MakeGarbageCollected.
+ template <typename Derived>
static void* AllocateObject(size_t size) {
- if (IsGarbageCollectedMixin<T>::value) {
- // Ban large mixin so we can use PageFromObject() on them.
- CHECK_GE(kLargeObjectSizeThreshold, size)
- << "GarbageCollectedMixin may not be a large object";
- }
- return ThreadHeap::Allocate<T>(size);
+ return ThreadHeap::Allocate<GCInfoFoldedType<Derived>>(size);
}
void operator delete(void* p) { NOTREACHED(); }
protected:
+ // This trait in theory can be moved to gc_info.h, but that would cause
+ // significant memory bloat caused by huge number of ThreadHeap::Allocate<>
+ // instantiations, which linker is not able to fold.
+ template <typename Derived>
+ class GCInfoFolded {
+ static constexpr bool is_virtual_destructor_at_base =
+ std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
+ static constexpr bool both_trivially_destructible =
+ std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
+ std::is_trivially_destructible<Derived>::value;
+ static constexpr bool has_custom_dispatch_at_base =
+ internal::HasFinalizeGarbageCollectedObject<
+ ParentMostGarbageCollectedType>::value;
+
+ public:
+ using Type = std::conditional_t<is_virtual_destructor_at_base ||
+ both_trivially_destructible ||
+ has_custom_dispatch_at_base,
+ ParentMostGarbageCollectedType,
+ Derived>;
+ };
+
+ template <typename Derived>
+ using GCInfoFoldedType = typename GCInfoFolded<Derived>::Type;
+
GarbageCollected() = default;
DISALLOW_COPY_AND_ASSIGN(GarbageCollected);
@@ -551,8 +525,11 @@ T* MakeGarbageCollected(Args&&... args) {
internal::IsGarbageCollectedContainer<T>::value ||
internal::HasFinalizeGarbageCollectedObject<T>::value,
"Finalized GarbageCollected class should either have a virtual "
- "destructor or be marked as final.");
- void* memory = T::AllocateObject(sizeof(T));
+ "destructor or be marked as final");
+ static_assert(!IsGarbageCollectedMixin<T>::value ||
+ sizeof(T) <= kLargeObjectSizeThreshold,
+ "GarbageCollectedMixin may not be a large object");
+ void* memory = T::template AllocateObject<T>(sizeof(T));
HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
// Placement new as regular operator new() is deleted.
T* object = ::new (memory) T(std::forward<Args>(args)...);
@@ -579,7 +556,13 @@ T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
internal::HasFinalizeGarbageCollectedObject<T>::value,
"Finalized GarbageCollected class should either have a virtual "
"destructor or be marked as final.");
- void* memory = T::AllocateObject(sizeof(T) + additional_bytes.value);
+ const size_t size = sizeof(T) + additional_bytes.value;
+ if (IsGarbageCollectedMixin<T>::value) {
+ // Ban large mixin so we can use PageFromObject() on them.
+ CHECK_GE(kLargeObjectSizeThreshold, size)
+ << "GarbageCollectedMixin may not be a large object";
+ }
+ void* memory = T::template AllocateObject<T>(size);
HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
// Placement new as regular operator new() is deleted.
T* object = ::new (memory) T(std::forward<Args>(args)...);
@@ -638,7 +621,7 @@ Address ThreadHeap::Allocate(size_t size) {
}
template <typename T>
-void Visitor::HandleWeakCell(Visitor* self, void* object) {
+void Visitor::HandleWeakCell(const WeakCallbackInfo&, void* object) {
WeakMember<T>* weak_member = reinterpret_cast<WeakMember<T>*>(object);
if (weak_member->Get()) {
if (weak_member->IsHashTableDeletedValue()) {
@@ -652,6 +635,37 @@ void Visitor::HandleWeakCell(Visitor* self, void* object) {
}
}
+class PLATFORM_EXPORT WeakCallbackInfo final {
+ public:
+ template <typename T>
+ bool IsHeapObjectAlive(const T*) const;
+ template <typename T>
+ bool IsHeapObjectAlive(const WeakMember<T>&) const;
+ template <typename T>
+ bool IsHeapObjectAlive(const UntracedMember<T>&) const;
+
+ private:
+ WeakCallbackInfo() = default;
+ friend class ThreadHeap;
+};
+
+template <typename T>
+bool WeakCallbackInfo::IsHeapObjectAlive(const T* object) const {
+ return ThreadHeap::IsHeapObjectAlive(object);
+}
+
+template <typename T>
+bool WeakCallbackInfo::IsHeapObjectAlive(
+ const WeakMember<T>& weak_member) const {
+ return ThreadHeap::IsHeapObjectAlive(weak_member);
+}
+
+template <typename T>
+bool WeakCallbackInfo::IsHeapObjectAlive(
+ const UntracedMember<T>& untraced_member) const {
+ return ThreadHeap::IsHeapObjectAlive(untraced_member.Get());
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
index 034f753ddc2..f4e2745e671 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
@@ -14,8 +14,7 @@ struct BackingModifier {
HeapObjectHeader* const header;
};
-BackingModifier CanFreeOrShrinkBacking(ThreadState* const state,
- void* address) {
+BackingModifier CanModifyBacking(ThreadState* const state, void* address) {
// - |SweepForbidden| protects against modifying objects from destructors.
// - |IsSweepingInProgress| protects against modifying objects while
// concurrent sweeping is in progress.
@@ -51,11 +50,10 @@ void HeapAllocator::BackingFree(void* address) {
return;
ThreadState* const state = ThreadState::Current();
- BackingModifier result = CanFreeOrShrinkBacking(state, address);
+ BackingModifier result = CanModifyBacking(state, address);
if (!result.can_modify)
return;
- state->Heap().PromptlyFreed(result.header->GcInfoIndex());
static_cast<NormalPage*>(result.page)
->ArenaForNormalPage()
->PromptlyFreeObject(result.header);
@@ -65,10 +63,6 @@ void HeapAllocator::FreeVectorBacking(void* address) {
BackingFree(address);
}
-void HeapAllocator::FreeInlineVectorBacking(void* address) {
- BackingFree(address);
-}
-
void HeapAllocator::FreeHashTableBacking(void* address) {
BackingFree(address);
}
@@ -78,8 +72,9 @@ bool HeapAllocator::BackingExpand(void* address, size_t new_size) {
return false;
ThreadState* state = ThreadState::Current();
- // Don't expand if concurrent sweeping is in progress.
- if (state->SweepForbidden() || state->IsSweepingInProgress())
+
+ BackingModifier result = CanModifyBacking(state, address);
+ if (!result.can_modify)
return false;
DCHECK(!state->in_atomic_pause());
DCHECK(state->IsAllocationAllowed());
@@ -93,26 +88,13 @@ bool HeapAllocator::BackingExpand(void* address, size_t new_size) {
HeapObjectHeader* header = HeapObjectHeader::FromPayload(address);
NormalPageArena* arena = static_cast<NormalPage*>(page)->ArenaForNormalPage();
- const size_t old_size = header->size();
- bool succeed = arena->ExpandObject(header, new_size);
- if (succeed) {
- state->Heap().AllocationPointAdjusted(arena->ArenaIndex());
- if (header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>() &&
- state->IsMarkingInProgress()) {
- state->CurrentVisitor()->AdjustMarkedBytes(header, old_size);
- }
- }
- return succeed;
+ return arena->ExpandObject(header, new_size);
}
bool HeapAllocator::ExpandVectorBacking(void* address, size_t new_size) {
return BackingExpand(address, new_size);
}
-bool HeapAllocator::ExpandInlineVectorBacking(void* address, size_t new_size) {
- return BackingExpand(address, new_size);
-}
-
bool HeapAllocator::ExpandHashTableBacking(void* address, size_t new_size) {
return BackingExpand(address, new_size);
}
@@ -126,7 +108,7 @@ bool HeapAllocator::BackingShrink(void* address,
DCHECK_LT(quantized_shrunk_size, quantized_current_size);
ThreadState* const state = ThreadState::Current();
- BackingModifier result = CanFreeOrShrinkBacking(state, address);
+ BackingModifier result = CanModifyBacking(state, address);
if (!result.can_modify)
return false;
@@ -144,10 +126,7 @@ bool HeapAllocator::BackingShrink(void* address,
!arena->IsObjectAllocatedAtAllocationPoint(result.header))
return true;
- bool succeeded_at_allocation_point =
- arena->ShrinkObject(result.header, quantized_shrunk_size);
- if (succeeded_at_allocation_point)
- state->Heap().AllocationPointAdjusted(arena->ArenaIndex());
+ arena->ShrinkObject(result.header, quantized_shrunk_size);
return true;
}
@@ -157,10 +136,4 @@ bool HeapAllocator::ShrinkVectorBacking(void* address,
return BackingShrink(address, quantized_current_size, quantized_shrunk_size);
}
-bool HeapAllocator::ShrinkInlineVectorBacking(void* address,
- size_t quantized_current_size,
- size_t quantized_shrunk_size) {
- return BackingShrink(address, quantized_current_size, quantized_shrunk_size);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
index 351f61fe604..d41fe4e422c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -71,6 +71,7 @@ class PLATFORM_EXPORT HeapAllocator {
STATIC_ONLY(HeapAllocator);
public:
+ using WeakCallbackInfo = blink::WeakCallbackInfo;
using Visitor = blink::Visitor;
static constexpr bool kIsGarbageCollected = true;
@@ -91,43 +92,18 @@ class PLATFORM_EXPORT HeapAllocator {
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
DCHECK(state->IsAllocationAllowed());
uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
- NormalPageArena* arena = static_cast<NormalPageArena*>(
- state->Heap().VectorBackingArena(gc_info_index));
- return reinterpret_cast<T*>(MarkAsConstructed(arena->AllocateObject(
- ThreadHeap::AllocationSizeFromSize(size), gc_info_index)));
- }
- template <typename T>
- static T* AllocateExpandedVectorBacking(size_t size) {
- ThreadState* state =
- ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- DCHECK(state->IsAllocationAllowed());
- uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
- NormalPageArena* arena = static_cast<NormalPageArena*>(
- state->Heap().ExpandedVectorBackingArena(gc_info_index));
- return reinterpret_cast<T*>(MarkAsConstructed(arena->AllocateObject(
- ThreadHeap::AllocationSizeFromSize(size), gc_info_index)));
+ const char* type_name =
+ WTF_HEAP_PROFILER_TYPE_NAME(HeapHashTableBacking<HeapVectorBacking<T>>);
+ return reinterpret_cast<T*>(
+ MarkAsConstructed(state->Heap().AllocateOnArenaIndex(
+ state, ThreadHeap::AllocationSizeFromSize(size),
+ BlinkGC::kVectorArenaIndex, gc_info_index, type_name)));
}
static void FreeVectorBacking(void*);
static bool ExpandVectorBacking(void*, size_t);
static bool ShrinkVectorBacking(void* address,
size_t quantized_current_size,
size_t quantized_shrunk_size);
- template <typename T>
- static T* AllocateInlineVectorBacking(size_t size) {
- uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
- ThreadState* state =
- ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(HeapVectorBacking<T>);
- return reinterpret_cast<T*>(
- MarkAsConstructed(state->Heap().AllocateOnArenaIndex(
- state, size, BlinkGC::kInlineVectorArenaIndex, gc_info_index,
- type_name)));
- }
- static void FreeInlineVectorBacking(void*);
- static bool ExpandInlineVectorBacking(void*, size_t);
- static bool ShrinkInlineVectorBacking(void* address,
- size_t quantized_current_size,
- size_t quantized_shrunk_size);
template <typename T, typename HashTable>
static T* AllocateHashTableBacking(size_t size) {
@@ -165,16 +141,6 @@ class PLATFORM_EXPORT HeapAllocator {
}
}
- template <typename T>
- static void BackingWriteBarrier(Member<T>* address, size_t size) {
- MarkingVisitor::WriteBarrier(address);
- }
-
- template <typename T>
- static void BackingWriteBarrier(T* address, size_t size) {
- MarkingVisitor::WriteBarrier(address);
- }
-
template <typename Return, typename Metadata>
static Return Malloc(size_t size, const char* type_name) {
return reinterpret_cast<Return>(
@@ -206,17 +172,10 @@ class PLATFORM_EXPORT HeapAllocator {
return ThreadHeap::IsHeapObjectAlive(object);
}
- template <typename VisitorDispatcher, typename T, typename Traits>
- static void Trace(VisitorDispatcher visitor, T& t) {
- TraceCollectionIfEnabled<Traits::kWeakHandlingFlag, T, Traits>::Trace(
- visitor, t);
- }
-
- template <typename VisitorDispatcher>
- static bool RegisterWeakTable(VisitorDispatcher visitor,
- const void* closure,
- EphemeronCallback iteration_callback) {
- return visitor->RegisterWeakTable(closure, iteration_callback);
+ template <typename T, typename Traits>
+ static void Trace(blink::Visitor* visitor, T& t) {
+ TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
+ Traits>::Trace(visitor, &t);
}
template <typename T, typename VisitorDispatcher>
@@ -249,10 +208,8 @@ class PLATFORM_EXPORT HeapAllocator {
// No weak handling for write barriers. Modifying weakly reachable objects
// strongifies them for the current cycle.
DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*object));
- TraceCollectionIfEnabled<
- WTF::kNoWeakHandling, T, Traits>::Trace(thread_state
- ->CurrentVisitor(),
- *object);
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), object);
}
}
@@ -272,10 +229,8 @@ class PLATFORM_EXPORT HeapAllocator {
while (len-- > 0) {
DCHECK(!Traits::kCanHaveDeletedValue ||
!Traits::IsDeletedValue(*array));
- TraceCollectionIfEnabled<
- WTF::kNoWeakHandling, T, Traits>::Trace(thread_state
- ->CurrentVisitor(),
- *array);
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), array);
array++;
}
}
@@ -305,7 +260,7 @@ class PLATFORM_EXPORT HeapAllocator {
T** backing_slot,
WeakCallback callback,
void* parameter) {
- visitor->TraceBackingStoreWeakly(
+ visitor->TraceBackingStoreWeakly<HashTable>(
reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing),
reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot),
callback, parameter);
@@ -371,7 +326,7 @@ static void TraceListHashSetValue(VisitorDispatcher visitor, Value& value) {
// strongify template argument, so we specify WTF::WeakPointersActWeak,
// arbitrarily.
TraceCollectionIfEnabled<WTF::kNoWeakHandling, Value,
- WTF::HashTraits<Value>>::Trace(visitor, value);
+ WTF::HashTraits<Value>>::Trace(visitor, &value);
}
// The inline capacity is just a dummy template argument to match the off-heap
@@ -510,6 +465,7 @@ class HeapHashMap : public HashMap<KeyArg,
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<
HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>>(
@@ -539,6 +495,7 @@ class HeapHashSet
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<HeapHashSet<ValueArg, HashArg, TraitsArg>>(
size);
@@ -568,6 +525,7 @@ class HeapLinkedHashSet
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<
HeapLinkedHashSet<ValueArg, HashArg, TraitsArg>>(size);
@@ -601,6 +559,7 @@ class HeapListHashSet
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<
HeapListHashSet<ValueArg, inlineCapacity, HashArg>>(size);
@@ -629,6 +588,7 @@ class HeapHashCountedSet
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<
HeapHashCountedSet<Value, HashFunctions, Traits>>(size);
@@ -655,6 +615,7 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
// On-heap HeapVectors generally should not have inline capacity, but it is
// hard to avoid when using a type alias. Hence we only disallow the
@@ -706,6 +667,7 @@ class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
}
public:
+ template <typename>
static void* AllocateObject(size_t size) {
// On-heap HeapDeques generally should not have inline capacity, but it is
// hard to avoid when using a type alias. Hence we only disallow the
@@ -753,17 +715,6 @@ struct VectorTraits<blink::Member<T>> : VectorTraitsBase<blink::Member<T>> {
};
template <typename T>
-struct VectorTraits<blink::SameThreadCheckedMember<T>>
- : VectorTraitsBase<blink::SameThreadCheckedMember<T>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanMoveWithMemcpy = true;
- static const bool kCanSwapUsingCopyOrMove = false;
-};
-
-template <typename T>
struct VectorTraits<blink::WeakMember<T>>
: VectorTraitsBase<blink::WeakMember<T>> {
STATIC_ONLY(VectorTraits);
@@ -863,42 +814,6 @@ struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
};
template <typename T>
-struct HashTraits<blink::SameThreadCheckedMember<T>>
- : SimpleClassHashTraits<blink::SameThreadCheckedMember<T>> {
- STATIC_ONLY(HashTraits);
- // FIXME: Implement proper const'ness for iterator types. Requires support
- // in the marking Visitor.
- using PeekInType = T*;
- using IteratorGetType = blink::SameThreadCheckedMember<T>*;
- using IteratorConstGetType = const blink::SameThreadCheckedMember<T>*;
- using IteratorReferenceType = blink::SameThreadCheckedMember<T>&;
- using IteratorConstReferenceType = const blink::SameThreadCheckedMember<T>&;
- static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
- return *x;
- }
- static IteratorConstReferenceType GetToReferenceConstConversion(
- IteratorConstGetType x) {
- return *x;
- }
-
- using PeekOutType = T*;
-
- template <typename U>
- static void Store(const U& value,
- blink::SameThreadCheckedMember<T>& storage) {
- storage = value;
- }
-
- static PeekOutType Peek(const blink::SameThreadCheckedMember<T>& value) {
- return value;
- }
-
- static blink::SameThreadCheckedMember<T> EmptyValue() {
- return blink::SameThreadCheckedMember<T>(nullptr, nullptr);
- }
-};
-
-template <typename T>
struct HashTraits<blink::WeakMember<T>>
: SimpleClassHashTraits<blink::WeakMember<T>> {
STATIC_ONLY(HashTraits);
@@ -926,21 +841,6 @@ struct HashTraits<blink::WeakMember<T>>
}
static PeekOutType Peek(const blink::WeakMember<T>& value) { return value; }
-
- static bool IsAlive(blink::WeakMember<T>& weak_member) {
- return blink::ThreadHeap::IsHeapObjectAlive(weak_member);
- }
-
- template <typename VisitorDispatcher>
- static bool TraceInCollection(VisitorDispatcher visitor,
- blink::WeakMember<T>& weak_member,
- WeakHandlingFlag weakness) {
- if (weakness == kNoWeakHandling) {
- visitor->Trace(weak_member.Get()); // Strongified visit.
- return false;
- }
- return !blink::ThreadHeap::IsHeapObjectAlive(weak_member);
- }
};
template <typename T>
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc b/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
index 2b210308f4d..1d9a577d2e3 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -316,18 +316,12 @@ void HeapCompact::MovableObjectFixups::VerifyUpdatedSlot(
HeapCompact::HeapCompact(ThreadHeap* heap) : heap_(heap) {
// The heap compaction implementation assumes the contiguous range,
//
- // [Vector1ArenaIndex, HashTableArenaIndex]
+ // [VectorArenaIndex, HashTableArenaIndex]
//
// in a few places. Use static asserts here to not have that assumption
// be silently invalidated by ArenaIndices changes.
- static_assert(BlinkGC::kVector1ArenaIndex + 3 == BlinkGC::kVector4ArenaIndex,
+ static_assert(BlinkGC::kVectorArenaIndex + 1 == BlinkGC::kHashTableArenaIndex,
"unexpected ArenaIndices ordering");
- static_assert(
- BlinkGC::kVector4ArenaIndex + 1 == BlinkGC::kInlineVectorArenaIndex,
- "unexpected ArenaIndices ordering");
- static_assert(
- BlinkGC::kInlineVectorArenaIndex + 1 == BlinkGC::kHashTableArenaIndex,
- "unexpected ArenaIndices ordering");
}
HeapCompact::~HeapCompact() = default;
@@ -393,7 +387,7 @@ void HeapCompact::UpdateHeapResidency() {
#if DEBUG_HEAP_FREELIST
std::stringstream stream;
#endif
- for (int i = BlinkGC::kVector1ArenaIndex; i <= BlinkGC::kHashTableArenaIndex;
+ for (int i = BlinkGC::kVectorArenaIndex; i <= BlinkGC::kHashTableArenaIndex;
++i) {
NormalPageArena* arena = static_cast<NormalPageArena*>(heap_->Arena(i));
size_t arena_size = arena->ArenaSize();
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h b/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
index e455f9f4f85..be7b142e17b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -37,7 +37,7 @@ class PLATFORM_EXPORT HeapCompact final {
public:
// Returns |true| if the ongoing GC may compact the given arena/sub-heap.
static bool IsCompactableArena(int arena_index) {
- return arena_index >= BlinkGC::kVector1ArenaIndex &&
+ return arena_index >= BlinkGC::kVectorArenaIndex &&
arena_index <= BlinkGC::kHashTableArenaIndex;
}
@@ -103,12 +103,7 @@ class PLATFORM_EXPORT HeapCompact final {
// Returns true if one or more vector arenas are being compacted.
bool IsCompactingVectorArenasForTesting() const {
- for (int i = BlinkGC::kVector1ArenaIndex; i <= BlinkGC::kVector4ArenaIndex;
- ++i) {
- if (IsCompactingArena(i))
- return true;
- }
- return false;
+ return IsCompactingArena(BlinkGC::kVectorArenaIndex);
}
size_t LastFixupCountForTesting() const {
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
index 48fa884bee4..953d4214834 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -35,11 +35,11 @@
#include "base/trace_event/process_memory_dump.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_verifier.h"
+#include "third_party/blink/renderer/platform/heap/page_bloom_filter.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
@@ -87,14 +87,6 @@
namespace blink {
-#if DCHECK_IS_ON() && defined(ARCH_CPU_64_BITS)
-NO_SANITIZE_ADDRESS
-void HeapObjectHeader::ZapMagic() {
- CheckHeader();
- magic_ = kZappedMagic;
-}
-#endif
-
void HeapObjectHeader::Finalize(Address object, size_t object_size) {
HeapAllocHooks::FreeHookIfEnabled(object);
const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex());
@@ -639,7 +631,6 @@ bool NormalPageArena::PagesToBeSweptContains(Address address) {
#endif
void NormalPageArena::AllocatePage() {
- GetThreadState()->Heap().address_cache()->MarkDirty();
PageMemory* page_memory =
GetThreadState()->Heap().GetFreePagePool()->Take(ArenaIndex());
@@ -676,8 +667,9 @@ void NormalPageArena::AllocatePage() {
new (page_memory->WritableStart()) NormalPage(page_memory, this);
swept_pages_.PushLocked(page);
- GetThreadState()->Heap().stats_collector()->IncreaseAllocatedSpace(
- page->size());
+ ThreadHeap& heap = GetThreadState()->Heap();
+ heap.stats_collector()->IncreaseAllocatedSpace(page->size());
+ heap.page_bloom_filter()->Add(page->GetAddress());
#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
// Allow the following addToFreeList() to add the newly allocated memory
// to the free list.
@@ -691,8 +683,9 @@ void NormalPageArena::AllocatePage() {
}
void NormalPageArena::FreePage(NormalPage* page) {
- GetThreadState()->Heap().stats_collector()->DecreaseAllocatedSpace(
- page->size());
+ ThreadHeap& heap = GetThreadState()->Heap();
+ heap.stats_collector()->DecreaseAllocatedSpace(page->size());
+ heap.page_bloom_filter()->Remove(page->GetAddress());
PageMemory* memory = page->Storage();
page->~NormalPage();
@@ -979,7 +972,6 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
large_object_size += kAllocationGranularity;
#endif
- GetThreadState()->Heap().address_cache()->MarkDirty();
PageMemory* page_memory = PageMemory::Allocate(
large_object_size, GetThreadState()->Heap().GetRegionTree());
Address large_object_address = page_memory->WritableStart();
@@ -1005,6 +997,14 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
swept_pages_.PushLocked(large_object);
+ // Add all segments of kBlinkPageSize to the bloom filter so that the large
+ // object can be kept by derived pointers on stack. An alternative might be to
+ // prohibit derived pointers to large objects, but that is dangerous since the
+ // compiler is free to optimize on-stack base pointers away.
+ for (Address page_begin = RoundToBlinkPageStart(large_object->GetAddress());
+ page_begin < large_object->PayloadEnd(); page_begin += kBlinkPageSize) {
+ GetThreadState()->Heap().page_bloom_filter()->Add(page_begin);
+ }
GetThreadState()->Heap().stats_collector()->IncreaseAllocatedSpace(
large_object->size());
GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
@@ -1015,8 +1015,9 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
void LargeObjectArena::FreeLargeObjectPage(LargeObjectPage* object) {
ASAN_UNPOISON_MEMORY_REGION(object->Payload(), object->PayloadSize());
object->ObjectHeader()->Finalize(object->Payload(), object->PayloadSize());
- GetThreadState()->Heap().stats_collector()->DecreaseAllocatedSpace(
- object->size());
+ ThreadHeap& heap = GetThreadState()->Heap();
+ heap.stats_collector()->DecreaseAllocatedSpace(object->size());
+ heap.page_bloom_filter()->Remove(object->GetAddress());
// Unpoison the object header and allocationGranularity bytes after the
// object before freeing.
@@ -1304,8 +1305,7 @@ void FreeList::CollectStatistics(
}
BasePage::BasePage(PageMemory* storage, BaseArena* arena, PageType page_type)
- : magic_(GetMagic()),
- storage_(storage),
+ : storage_(storage),
arena_(arena),
thread_state_(arena->GetThreadState()),
page_type_(page_type) {
@@ -1663,7 +1663,6 @@ void NormalPage::VerifyObjectStartBitmapIsConsistentWithPayload() {
const HeapObjectHeader* object_header =
reinterpret_cast<HeapObjectHeader*>(object_address);
DCHECK_EQ(object_header, current_header);
- DCHECK(object_header->IsValidOrZapped());
current_header = reinterpret_cast<HeapObjectHeader*>(object_address +
object_header->size());
// Skip over allocation area.
@@ -1724,7 +1723,6 @@ HeapObjectHeader* NormalPage::ConservativelyFindHeaderFromAddress(
return nullptr;
HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
object_start_bit_map()->FindHeader(address));
- DCHECK(header->IsValidOrZapped());
if (header->IsFree())
return nullptr;
DCHECK_LT(0u, header->GcInfoIndex());
@@ -1732,17 +1730,6 @@ HeapObjectHeader* NormalPage::ConservativelyFindHeaderFromAddress(
return header;
}
-HeapObjectHeader* NormalPage::FindHeaderFromAddress(Address address) {
- DCHECK(ContainedInObjectPayload(address));
- DCHECK(!ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address));
- HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
- object_start_bit_map()->FindHeader(address));
- DCHECK(header->IsValid());
- DCHECK_LT(0u, header->GcInfoIndex());
- DCHECK_GT(header->PayloadEnd(), address);
- return header;
-}
-
void NormalPage::CollectStatistics(
ThreadState::Statistics::ArenaStatistics* arena_stats) {
HeapObjectHeader* header = nullptr;
@@ -1859,76 +1846,4 @@ bool LargeObjectPage::Contains(Address object) {
}
#endif
-ALWAYS_INLINE uint32_t RotateLeft16(uint32_t x) {
-#if defined(COMPILER_MSVC)
- return _lrotr(x, 16);
-#else
- // http://blog.regehr.org/archives/1063
- return (x << 16) | (x >> (-16 & 31));
-#endif
-}
-
-uint32_t ComputeRandomMagic() {
-// Ignore C4319: It is OK to 0-extend into the high-order bits of the uintptr_t
-// on 64-bit, in this case.
-#if defined(COMPILER_MSVC)
-#pragma warning(push)
-#pragma warning(disable : 4319)
-#endif
-
- // Get an ASLR'd address from one of our own DLLs/.sos, and then another from
- // a system DLL/.so:
-
- const uint32_t random1 =
- ~(RotateLeft16(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(
- base::trace_event::MemoryAllocatorDump::kNameSize))));
-
-#if defined(OS_WIN)
- uintptr_t random2 = reinterpret_cast<uintptr_t>(::ReadFile);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
- uintptr_t random2 = reinterpret_cast<uintptr_t>(::read);
-#else
-#error platform not supported
-#endif
-
-#if defined(ARCH_CPU_64_BITS)
- static_assert(sizeof(uintptr_t) == sizeof(uint64_t),
- "uintptr_t is not uint64_t");
- // Shift in some high-order bits.
- random2 = random2 >> 16;
-#elif defined(ARCH_CPU_32_BITS)
- // Although we don't use heap metadata canaries on 32-bit due to memory
- // pressure, keep this code around just in case we do, someday.
- static_assert(sizeof(uintptr_t) == sizeof(uint32_t),
- "uintptr_t is not uint32_t");
-#else
-#error architecture not supported
-#endif
-
- random2 = ~(RotateLeft16(static_cast<uint32_t>(random2)));
-
- // Combine the 2 values:
- const uint32_t random = (random1 & 0x0000FFFFUL) |
- (static_cast<uint32_t>(random2) & 0xFFFF0000UL);
-
-#if defined(COMPILER_MSVC)
-#pragma warning(pop)
-#endif
-
- return random;
-}
-
-#if defined(ARCH_CPU_64_BITS)
-// Returns a random magic value.
-uint32_t HeapObjectHeader::GetMagic() {
- static const uint32_t magic = ComputeRandomMagic() ^ 0x6e0b6ead;
- return magic;
-}
-#endif // defined(ARCH_CPU_64_BITS)
-
-uint32_t BasePage::GetMagic() {
- static const uint32_t magic = ComputeRandomMagic() ^ 0xba5e4a9e;
- return magic;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.h b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
index 733b97bd7ef..4a937e53c1d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
@@ -133,21 +133,9 @@ class NormalPageArena;
class PageMemory;
class BaseArena;
-// Returns a random value.
-//
-// The implementation gets its randomness from the locations of 2 independent
-// sources of address space layout randomization: a function in a Chrome
-// executable image, and a function in an external DLL/so. This implementation
-// should be fast and small, and should have the benefit of requiring
-// attackers to discover and use 2 independent weak infoleak bugs, or 1
-// arbitrary infoleak bug (used twice).
-uint32_t ComputeRandomMagic();
-
-// HeapObjectHeader is a 64-bit (64-bit platforms) or 32-bit (32-bit platforms)
-// object that has the following layout:
-//
-// | random magic value (32 bits) | Only present on 64-bit platforms.
+// HeapObjectHeader is a 32-bit object that has the following layout:
//
+// | padding (32 bits) | Only present on 64-bit platforms.
// | gc_info_index (14 bits) |
// | unused (1 bit) |
// | in construction (1 bit) | true: bit not set; false bit set
@@ -234,15 +222,8 @@ class PLATFORM_EXPORT HeapObjectHeader {
enum HeaderLocation : uint8_t { kNormalPage, kLargePage };
enum class AccessMode : uint8_t { kNonAtomic, kAtomic };
- // The following values are used when zapping free list entries.
- // Regular zapping value.
- static const uint32_t kZappedMagic = 0xDEAD4321;
- // On debug and sanitizer builds the zap values differ, indicating when free
- // list entires are allowed to be reused.
- static const uint32_t kZappedMagicAllowed = 0x2a2a2a2a;
- static const uint32_t kZappedMagicForbidden = 0x2c2c2c2c;
-
static HeapObjectHeader* FromPayload(const void*);
+ template <AccessMode = AccessMode::kNonAtomic>
static HeapObjectHeader* FromInnerAddress(const void*);
// Checks sanity of the header given a payload pointer.
@@ -262,6 +243,7 @@ class PLATFORM_EXPORT HeapObjectHeader {
return (encoded & kHeaderGCInfoIndexMask) >> kHeaderGCInfoIndexShift;
}
+ template <AccessMode = AccessMode::kNonAtomic>
size_t size() const;
void SetSize(size_t size);
@@ -285,6 +267,7 @@ class PLATFORM_EXPORT HeapObjectHeader {
// size does not include the sizeof(HeapObjectHeader).
Address Payload() const;
size_t PayloadSize() const;
+ template <AccessMode = AccessMode::kNonAtomic>
Address PayloadEnd() const;
void Finalize(Address, size_t);
@@ -295,21 +278,7 @@ class PLATFORM_EXPORT HeapObjectHeader {
// Returns a human-readable name of this object.
const char* Name() const;
- // Returns true if magic number is valid.
- bool IsValid() const;
- // Returns true if magic number is valid or zapped.
- bool IsValidOrZapped() const;
-
- protected:
-#if DCHECK_IS_ON() && defined(ARCH_CPU_64_BITS)
- // Zap |m_magic| with a new magic number that means there was once an object
- // allocated here, but it was freed because nobody marked it during GC.
- void ZapMagic();
-#endif
-
private:
- void CheckHeader() const;
-
enum class EncodedHalf : uint8_t { kLow, kHigh };
template <AccessMode, EncodedHalf>
@@ -318,11 +287,8 @@ class PLATFORM_EXPORT HeapObjectHeader {
void StoreEncoded(uint16_t bits, uint16_t mask);
#if defined(ARCH_CPU_64_BITS)
- // Returns a random magic value.
- static uint32_t GetMagic();
- uint32_t magic_;
+ uint32_t padding_ = 0;
#endif // defined(ARCH_CPU_64_BITS)
-
uint16_t encoded_high_;
uint16_t encoded_low_;
};
@@ -335,10 +301,6 @@ class FreeListEntry final : public HeapObjectHeader {
kGcInfoIndexForFreeListHeader,
HeapObjectHeader::kNormalPage),
next_(nullptr) {
-#if DCHECK_IS_ON() && defined(ARCH_CPU_64_BITS)
- DCHECK_GE(size, sizeof(HeapObjectHeader));
- ZapMagic();
-#endif
}
Address GetAddress() { return reinterpret_cast<Address>(this); }
@@ -543,16 +505,9 @@ class BasePage {
return page_type_ == PageType::kLargeObjectPage;
}
- // Returns true if magic number is valid.
- bool IsValid() const;
-
virtual void VerifyMarking() = 0;
private:
- // Returns a random magic value.
- PLATFORM_EXPORT static uint32_t GetMagic();
-
- uint32_t const magic_;
PageMemory* const storage_;
BaseArena* const arena_;
ThreadState* const thread_state_;
@@ -756,6 +711,8 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
// Uses the object_start_bit_map_ to find an object for a given address. It is
// assumed that the address points into a valid heap object. Use the
// conservative version if that assumption does not hold.
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
HeapObjectHeader* FindHeaderFromAddress(Address);
void VerifyMarking() override;
@@ -1076,8 +1033,6 @@ PLATFORM_EXPORT ALWAYS_INLINE BasePage* PageFromObject(const void* object) {
Address address = reinterpret_cast<Address>(const_cast<void*>(object));
BasePage* page = reinterpret_cast<BasePage*>(BlinkPageAddress(address) +
kBlinkGuardPageSize);
- // Page must have a valid magic.
- CHECK(page->IsValid());
#if DCHECK_IS_ON()
DCHECK(page->Contains(address));
#endif
@@ -1088,16 +1043,16 @@ inline HeapObjectHeader* HeapObjectHeader::FromPayload(const void* payload) {
Address addr = reinterpret_cast<Address>(const_cast<void*>(payload));
HeapObjectHeader* header =
reinterpret_cast<HeapObjectHeader*>(addr - sizeof(HeapObjectHeader));
- header->CheckHeader();
return header;
}
+template <HeapObjectHeader::AccessMode mode>
inline HeapObjectHeader* HeapObjectHeader::FromInnerAddress(
const void* address) {
BasePage* const page = PageFromObject(address);
return page->IsLargeObjectPage()
? static_cast<LargeObjectPage*>(page)->ObjectHeader()
- : static_cast<NormalPage*>(page)->FindHeaderFromAddress(
+ : static_cast<NormalPage*>(page)->FindHeaderFromAddress<mode>(
reinterpret_cast<Address>(const_cast<void*>(address)));
}
@@ -1105,8 +1060,22 @@ inline void HeapObjectHeader::CheckFromPayload(const void* payload) {
(void)FromPayload(payload);
}
+template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const {
- const size_t result = internal::DecodeSize(encoded_low_);
+ uint16_t encoded_low_value;
+ if (mode == AccessMode::kNonAtomic) {
+ encoded_low_value = encoded_low_;
+ } else {
+ // mode == AccessMode::kAtomic
+ // Relaxed load as size is immutable after construction while either
+ // marking or sweeping is running
+ internal::AsanUnpoisonScope unpoison_scope(
+ static_cast<const void*>(&encoded_low_), sizeof(encoded_low_));
+ encoded_low_value =
+ reinterpret_cast<const std::atomic<uint16_t>&>(encoded_low_)
+ .load(std::memory_order_relaxed);
+ }
+ const size_t result = internal::DecodeSize(encoded_low_value);
// Large objects should not refer to header->size() but use
// LargeObjectPage::PayloadSize().
DCHECK(result != kLargeObjectSizeInHeader);
@@ -1115,8 +1084,8 @@ NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const {
}
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::SetSize(size_t size) {
+ DCHECK(!PageFromObject(Payload())->thread_state()->IsIncrementalMarking());
DCHECK_LT(size, kNonLargeObjectPageSizeMax);
- CheckHeader();
encoded_low_ = static_cast<uint16_t>(internal::EncodeSize(size) |
(encoded_low_ & ~kHeaderSizeMask));
}
@@ -1133,46 +1102,23 @@ NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsInConstruction() const {
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::MarkFullyConstructed() {
- DCHECK(IsInConstruction<mode>());
+ DCHECK(IsInConstruction());
StoreEncoded<mode, EncodedHalf::kHigh>(kHeaderIsInConstructionMask,
kHeaderIsInConstructionMask);
}
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsValid() const {
-#if defined(ARCH_CPU_64_BITS)
- return GetMagic() == magic_;
-#else
- return true;
-#endif
-}
-
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsValidOrZapped() const {
-#if defined(ARCH_CPU_64_BITS)
- return IsValid() || kZappedMagic == magic_ || kZappedMagicAllowed == magic_ ||
- kZappedMagicForbidden == magic_;
-#else
- return true;
-#endif
-}
-
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::CheckHeader() const {
-#if defined(ARCH_CPU_64_BITS)
- CHECK(IsValid());
-#endif
-}
-
inline Address HeapObjectHeader::Payload() const {
return reinterpret_cast<Address>(const_cast<HeapObjectHeader*>(this)) +
sizeof(HeapObjectHeader);
}
+template <HeapObjectHeader::AccessMode mode>
inline Address HeapObjectHeader::PayloadEnd() const {
return reinterpret_cast<Address>(const_cast<HeapObjectHeader*>(this)) +
- size();
+ size<mode>();
}
NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::PayloadSize() const {
- CheckHeader();
const size_t size = internal::DecodeSize(encoded_low_);
if (UNLIKELY(size == kLargeObjectSizeInHeader)) {
DCHECK(PageFromObject(this)->IsLargeObjectPage());
@@ -1184,21 +1130,18 @@ NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::PayloadSize() const {
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsMarked() const {
- CheckHeader();
const uint16_t encoded = LoadEncoded<mode, EncodedHalf::kLow>();
return encoded & kHeaderMarkBitMask;
}
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Mark() {
- CheckHeader();
DCHECK(!IsMarked<mode>());
StoreEncoded<mode, EncodedHalf::kLow>(kHeaderMarkBitMask, kHeaderMarkBitMask);
}
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Unmark() {
- CheckHeader();
DCHECK(IsMarked<mode>());
StoreEncoded<mode, EncodedHalf::kLow>(0u, kHeaderMarkBitMask);
}
@@ -1207,7 +1150,6 @@ NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Unmark() {
// called, i.e. SetSize() and TryMark() can't be called concurrently.
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::TryMark() {
- CheckHeader();
if (mode == AccessMode::kNonAtomic) {
if (encoded_low_ & kHeaderMarkBitMask)
return false;
@@ -1227,10 +1169,6 @@ NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::TryMark() {
std::memory_order_relaxed);
}
-NO_SANITIZE_ADDRESS inline bool BasePage::IsValid() const {
- return GetMagic() == magic_;
-}
-
inline Address NormalPageArena::AllocateObject(size_t allocation_size,
size_t gc_info_index) {
if (LIKELY(allocation_size <= remaining_allocation_size_)) {
@@ -1319,11 +1257,6 @@ NO_SANITIZE_ADDRESS inline HeapObjectHeader::HeapObjectHeader(
static_assert(
sizeof(HeapObjectHeader) <= kAllocationGranularity,
"size of HeapObjectHeader must be smaller than kAllocationGranularity");
-#if defined(ARCH_CPU_64_BITS)
- static_assert(sizeof(HeapObjectHeader) == 8,
- "sizeof(HeapObjectHeader) must be 8 bytes");
- magic_ = GetMagic();
-#endif
DCHECK_LT(gc_info_index, GCInfoTable::kMaxIndex);
DCHECK_LT(size, kNonLargeObjectPageSizeMax);
@@ -1375,6 +1308,17 @@ NO_SANITIZE_ADDRESS inline void HeapObjectHeader::StoreEncoded(uint16_t bits,
atomic_encoded->store(value, std::memory_order_release);
}
+template <HeapObjectHeader::AccessMode mode>
+HeapObjectHeader* NormalPage::FindHeaderFromAddress(Address address) {
+ DCHECK(ContainedInObjectPayload(address));
+ DCHECK(!ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address));
+ HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
+ object_start_bit_map()->FindHeader(address));
+ DCHECK_LT(0u, header->GcInfoIndex());
+ DCHECK_GT(header->PayloadEnd<mode>(), address);
+ return header;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
index 397692250dd..6b8dc5c4cfd 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -196,7 +196,7 @@ base::TimeDelta ThreadHeapStatsCollector::Event::foreground_marking_time()
base::TimeDelta ThreadHeapStatsCollector::Event::background_marking_time()
const {
return base::TimeDelta::FromMicroseconds(
- concurrent_scope_data[kConcurrentMark]);
+ base::subtle::NoBarrier_Load(&concurrent_scope_data[kConcurrentMark]));
}
base::TimeDelta ThreadHeapStatsCollector::Event::marking_time() const {
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
index 54b950c1874..b9bf108f948 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -45,7 +45,6 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/buildflags.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_linked_stack.h"
@@ -208,91 +207,6 @@ struct ThreadMarkerHash {
static const bool safe_to_compare_to_empty_or_deleted = false;
};
-typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> StrongWeakPair;
-
-struct PairWithWeakHandling : public StrongWeakPair {
- DISALLOW_NEW();
-
- public:
- // Regular constructor.
- PairWithWeakHandling(IntWrapper* one, IntWrapper* two)
- : StrongWeakPair(one, two) {
- DCHECK(one); // We use null first field to indicate empty slots in the hash
- // table.
- }
-
- // The HashTable (via the HashTrait) calls this constructor with a
- // placement new to mark slots in the hash table as being deleted. We will
- // never call trace or the destructor on these slots. We mark ourselves
- // deleted
- // with a pointer to -1 in the first field.
- PairWithWeakHandling(WTF::HashTableDeletedValueType)
- : StrongWeakPair(WTF::kHashTableDeletedValue, nullptr) {}
-
- // Used by the HashTable (via the HashTrait) to skip deleted slots in the
- // table. Recognizes objects that were 'constructed' using the above
- // constructor.
- bool IsHashTableDeletedValue() const {
- return first.IsHashTableDeletedValue();
- }
-
- bool IsAlive() { return ThreadHeap::IsHeapObjectAlive(second); }
-
- // Since we don't allocate independent objects of this type, we don't need
- // a regular trace method. Instead, we use a traceInCollection method. If
- // the entry should be deleted from the collection we return true and don't
- // trace the strong pointer.
- template <typename VisitorDispatcher>
- bool TraceInCollection(VisitorDispatcher visitor,
- WTF::WeakHandlingFlag weakness) {
- HashTraits<WeakMember<IntWrapper>>::TraceInCollection(visitor, second,
- weakness);
- if (!ThreadHeap::IsHeapObjectAlive(second))
- return true;
-
- visitor->Trace(first);
- return false;
- }
-
- // Incremental marking requires that these objects have a regular tracing
- // method that is used for eagerly tracing through them in case they are
- // in-place constructed in a container. In this case, we only care about
- // strong fields.
- void Trace(blink::Visitor* visitor) { visitor->Trace(first); }
-};
-
-template <typename T>
-struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<T> {
- // We want to treat the object as a weak object in the sense that it can
- // disappear from hash sets and hash maps.
- static const WTF::WeakHandlingFlag kWeakHandlingFlag = WTF::kWeakHandling;
- // Normally whether or not an object needs tracing is inferred
- // automatically from the presence of the trace method, but we don't
- // necessarily have a trace method, and we may not need one because T
- // can perhaps only be allocated inside collections, never as independent
- // objects. Explicitly mark this as needing tracing and it will be traced
- // in collections using the traceInCollection method, which it must have.
- template <typename U = void>
- struct IsTraceableInCollection {
- static const bool value = true;
- };
- // The traceInCollection method traces differently depending on whether we
- // are strongifying the trace operation. We strongify the trace operation
- // when there are active iterators on the object. In this case all
- // WeakMembers are marked like strong members so that elements do not
- // suddenly disappear during iteration. Returns true if weak pointers to
- // dead objects were found: In this case any strong pointers were not yet
- // traced and the entry should be removed from the collection.
- template <typename VisitorDispatcher>
- static bool TraceInCollection(VisitorDispatcher visitor,
- T& t,
- WTF::WeakHandlingFlag weakness) {
- return t.TraceInCollection(visitor, weakness);
- }
-
- static bool IsAlive(T& t) { return t.IsAlive(); }
-};
-
} // namespace
} // namespace blink
@@ -319,44 +233,6 @@ struct HashTraits<blink::ThreadMarker>
}
};
-// The hash algorithm for our custom pair class is just the standard double
-// hash for pairs. Note that this means you can't mutate either of the parts of
-// the pair while they are in the hash table, as that would change their hash
-// code and thus their preferred placement in the table.
-template <>
-struct DefaultHash<blink::PairWithWeakHandling> {
- typedef PairHash<blink::Member<blink::IntWrapper>,
- blink::WeakMember<blink::IntWrapper>>
- Hash;
-};
-
-// Custom traits for the pair. These are weakness handling traits, which means
-// PairWithWeakHandling must implement the traceInCollection method.
-// In addition, these traits are concerned with the two magic values for the
-// object, that represent empty and deleted slots in the hash table. The
-// SimpleClassHashTraits allow empty slots in the table to be initialzed with
-// memset to zero, and we use -1 in the first part of the pair to represent
-// deleted slots.
-template <>
-struct HashTraits<blink::PairWithWeakHandling>
- : blink::WeakHandlingHashTraits<blink::PairWithWeakHandling> {
- static const bool kHasIsEmptyValueFunction = true;
- static bool IsEmptyValue(const blink::PairWithWeakHandling& value) {
- return !value.first;
- }
- static void ConstructDeletedValue(blink::PairWithWeakHandling& slot, bool) {
- new (NotNull, &slot) blink::PairWithWeakHandling(kHashTableDeletedValue);
- }
- static bool IsDeletedValue(const blink::PairWithWeakHandling& value) {
- return value.IsHashTableDeletedValue();
- }
-};
-
-template <>
-struct IsTraceable<blink::PairWithWeakHandling> {
- static const bool value = IsTraceable<blink::StrongWeakPair>::value;
-};
-
template <>
struct DefaultHash<blink::KeyWithCopyingMoveConstructor> {
using Hash = blink::KeyWithCopyingMoveConstructor::Hash;
@@ -503,7 +379,7 @@ class ThreadedTesterBase {
std::unique_ptr<Thread> threads[kNumberOfThreads];
for (auto& thread : threads) {
thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("blink gc testing thread"));
PostCrossThreadTask(
*thread->GetTaskRunner(), FROM_HERE,
@@ -982,11 +858,12 @@ class Weak : public Bar {
void Trace(blink::Visitor* visitor) override {
visitor->Trace(strong_bar_);
- visitor->template RegisterWeakMembers<Weak, &Weak::ZapWeakMembers>(this);
+ visitor->template RegisterWeakCallbackMethod<Weak, &Weak::ZapWeakMembers>(
+ this);
}
- void ZapWeakMembers(Visitor* visitor) {
- if (!ThreadHeap::IsHeapObjectAlive(weak_bar_))
+ void ZapWeakMembers(const WeakCallbackInfo& info) {
+ if (!info.IsHeapObjectAlive(weak_bar_))
weak_bar_ = nullptr;
}
@@ -1130,13 +1007,13 @@ class FinalizationObserver : public GarbageCollected<FinalizationObserver<T>> {
bool DidCallWillFinalize() const { return did_call_will_finalize_; }
void Trace(blink::Visitor* visitor) {
- visitor->template RegisterWeakMembers<
+ visitor->template RegisterWeakCallbackMethod<
FinalizationObserver<T>, &FinalizationObserver<T>::ZapWeakMembers>(
this);
}
- void ZapWeakMembers(Visitor* visitor) {
- if (data_ && !ThreadHeap::IsHeapObjectAlive(data_)) {
+ void ZapWeakMembers(const WeakCallbackInfo& info) {
+ if (data_ && !info.IsHeapObjectAlive(data_)) {
data_->WillFinalize();
data_ = nullptr;
did_call_will_finalize_ = true;
@@ -1660,7 +1537,7 @@ class LargeMixin : public GarbageCollected<LargeMixin>, public Mixin {
};
TEST(HeapDeathTest, LargeGarbageCollectedMixin) {
- EXPECT_DEATH(MakeGarbageCollected<LargeMixin>(), "");
+ EXPECT_DEATH(MakeGarbageCollected<LargeMixin>(AdditionalBytes(1)), "");
}
TEST_F(HeapTest, Transition) {
@@ -3965,8 +3842,9 @@ namespace {
void ExpectObjectMarkedAndUnmark(MarkingWorklist* worklist, void* expected) {
MarkingItem item;
CHECK(worklist->Pop(0, &item));
- CHECK_EQ(expected, item.object);
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(item.object);
+ CHECK_EQ(expected, item.base_object_payload);
+ HeapObjectHeader* header =
+ HeapObjectHeader::FromPayload(item.base_object_payload);
CHECK(header->IsMarked());
header->Unmark();
CHECK(worklist->IsGlobalEmpty());
@@ -4003,8 +3881,6 @@ TEST_F(HeapTest, CheckAndMarkPointer) {
ThreadHeapStatsCollector::Scope stats_scope(
heap.stats_collector(),
ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
- heap.address_cache()->EnableLookup();
- heap.address_cache()->Flush();
// Conservative marker should find the interesting objects by using anything
// between object start and end.
@@ -4036,8 +3912,6 @@ TEST_F(HeapTest, CheckAndMarkPointer) {
ThreadHeapStatsCollector::Scope stats_scope(
heap.stats_collector(),
ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
- heap.address_cache()->EnableLookup();
- heap.address_cache()->Flush();
// After collecting all interesting objects the conservative marker should
// not find them anymore.
@@ -4709,238 +4583,6 @@ TEST_F(HeapTest, NeedsAdjustPointer) {
"A const UseMixin pointer does not need adjustment");
}
-template <typename Set>
-void SetWithCustomWeaknessHandling() {
- typedef typename Set::iterator Iterator;
- Persistent<IntWrapper> living_int(MakeGarbageCollected<IntWrapper>(42));
- Persistent<Set> set1(MakeGarbageCollected<Set>());
- {
- Set set2;
- Set* set3 = MakeGarbageCollected<Set>();
- set2.insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(0),
- MakeGarbageCollected<IntWrapper>(1)));
- set3->insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(2),
- MakeGarbageCollected<IntWrapper>(3)));
- set1->insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(4),
- MakeGarbageCollected<IntWrapper>(5)));
- TestSupportingGC::ConservativelyCollectGarbage();
- // The first set is pointed to from a persistent, so it's referenced, but
- // the weak processing may have taken place.
- if (set1->size()) {
- Iterator i1 = set1->begin();
- EXPECT_EQ(4, i1->first->Value());
- EXPECT_EQ(5, i1->second->Value());
- }
- // The second set is on-stack, so its backing store must be referenced from
- // the stack. That makes the weak references strong.
- Iterator i2 = set2.begin();
- EXPECT_EQ(0, i2->first->Value());
- EXPECT_EQ(1, i2->second->Value());
- // The third set is pointed to from the stack, so it's referenced, but the
- // weak processing may have taken place.
- if (set3->size()) {
- Iterator i3 = set3->begin();
- EXPECT_EQ(2, i3->first->Value());
- EXPECT_EQ(3, i3->second->Value());
- }
- }
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_EQ(0u, set1->size());
- set1->insert(
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(103), living_int));
- // This one gets zapped at GC time because nothing holds the 103 alive.
- set1->insert(
- PairWithWeakHandling(living_int, MakeGarbageCollected<IntWrapper>(103)));
- set1->insert(PairWithWeakHandling(
- MakeGarbageCollected<IntWrapper>(103),
- MakeGarbageCollected<IntWrapper>(103))); // This one gets zapped too.
- set1->insert(PairWithWeakHandling(living_int, living_int));
- // This one is identical to the previous and doesn't add anything.
- set1->insert(PairWithWeakHandling(living_int, living_int));
- EXPECT_EQ(4u, set1->size());
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_EQ(2u, set1->size());
- Iterator i1 = set1->begin();
- EXPECT_TRUE(i1->first->Value() == 103 || i1->first == living_int);
- EXPECT_EQ(living_int, i1->second);
- ++i1;
- EXPECT_TRUE(i1->first->Value() == 103 || i1->first == living_int);
- EXPECT_EQ(living_int, i1->second);
-}
-
-TEST_F(HeapTest, SetWithCustomWeaknessHandling) {
- SetWithCustomWeaknessHandling<HeapHashSet<PairWithWeakHandling>>();
- SetWithCustomWeaknessHandling<HeapLinkedHashSet<PairWithWeakHandling>>();
-}
-
-TEST_F(HeapTest, MapWithCustomWeaknessHandling) {
- typedef HeapHashMap<PairWithWeakHandling, scoped_refptr<OffHeapInt>> Map;
- typedef Map::iterator Iterator;
- ClearOutOldGarbage();
- OffHeapInt::destructor_calls_ = 0;
-
- Persistent<Map> map1(MakeGarbageCollected<Map>());
- Persistent<IntWrapper> living_int(MakeGarbageCollected<IntWrapper>(42));
- {
- Map map2;
- Map* map3 = MakeGarbageCollected<Map>();
- map2.insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(0),
- MakeGarbageCollected<IntWrapper>(1)),
- OffHeapInt::Create(1001));
- map3->insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(2),
- MakeGarbageCollected<IntWrapper>(3)),
- OffHeapInt::Create(1002));
- map1->insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(4),
- MakeGarbageCollected<IntWrapper>(5)),
- OffHeapInt::Create(1003));
- EXPECT_EQ(0, OffHeapInt::destructor_calls_);
-
- ConservativelyCollectGarbage();
- // The first map2 is pointed to from a persistent, so it's referenced, but
- // the weak processing may have taken place.
- if (map1->size()) {
- Iterator i1 = map1->begin();
- EXPECT_EQ(4, i1->key.first->Value());
- EXPECT_EQ(5, i1->key.second->Value());
- EXPECT_EQ(1003, i1->value->Value());
- }
- // The second map2 is on-stack, so its backing store must be referenced from
- // the stack. That makes the weak references strong.
- Iterator i2 = map2.begin();
- EXPECT_EQ(0, i2->key.first->Value());
- EXPECT_EQ(1, i2->key.second->Value());
- EXPECT_EQ(1001, i2->value->Value());
- // The third map2 is pointed to from the stack, so it's referenced, but the
- // weak processing may have taken place.
- if (map3->size()) {
- Iterator i3 = map3->begin();
- EXPECT_EQ(2, i3->key.first->Value());
- EXPECT_EQ(3, i3->key.second->Value());
- EXPECT_EQ(1002, i3->value->Value());
- }
- }
- PreciselyCollectGarbage();
-
- EXPECT_EQ(0u, map1->size());
- EXPECT_EQ(3, OffHeapInt::destructor_calls_);
-
- OffHeapInt::destructor_calls_ = 0;
-
- map1->insert(
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(103), living_int),
- OffHeapInt::Create(2000));
- map1->insert(
- PairWithWeakHandling(living_int, MakeGarbageCollected<IntWrapper>(103)),
- OffHeapInt::Create(2001)); // This one gets zapped at GC time
- // because nothing holds the 103 alive.
- map1->insert(PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(103),
- MakeGarbageCollected<IntWrapper>(103)),
- OffHeapInt::Create(2002)); // This one gets zapped too.
- scoped_refptr<OffHeapInt> dupe_int(OffHeapInt::Create(2003));
- map1->insert(PairWithWeakHandling(living_int, living_int), dupe_int);
- map1->insert(
- PairWithWeakHandling(living_int, living_int),
- dupe_int); // This one is identical to the previous and doesn't add
- // anything.
- dupe_int = nullptr;
-
- EXPECT_EQ(0, OffHeapInt::destructor_calls_);
- EXPECT_EQ(4u, map1->size());
- PreciselyCollectGarbage();
- EXPECT_EQ(2, OffHeapInt::destructor_calls_);
- EXPECT_EQ(2u, map1->size());
- Iterator i1 = map1->begin();
- EXPECT_TRUE(i1->key.first->Value() == 103 || i1->key.first == living_int);
- EXPECT_EQ(living_int, i1->key.second);
- ++i1;
- EXPECT_TRUE(i1->key.first->Value() == 103 || i1->key.first == living_int);
- EXPECT_EQ(living_int, i1->key.second);
-}
-
-TEST_F(HeapTest, MapWithCustomWeaknessHandling2) {
- typedef HeapHashMap<scoped_refptr<OffHeapInt>, PairWithWeakHandling> Map;
- typedef Map::iterator Iterator;
- ClearOutOldGarbage();
- OffHeapInt::destructor_calls_ = 0;
-
- Persistent<Map> map1(MakeGarbageCollected<Map>());
- Persistent<IntWrapper> living_int(MakeGarbageCollected<IntWrapper>(42));
-
- {
- Map map2;
- Map* map3 = MakeGarbageCollected<Map>();
- map2.insert(OffHeapInt::Create(1001),
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(0),
- MakeGarbageCollected<IntWrapper>(1)));
- map3->insert(OffHeapInt::Create(1002),
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(2),
- MakeGarbageCollected<IntWrapper>(3)));
- map1->insert(OffHeapInt::Create(1003),
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(4),
- MakeGarbageCollected<IntWrapper>(5)));
- EXPECT_EQ(0, OffHeapInt::destructor_calls_);
-
- ConservativelyCollectGarbage();
- // The first map2 is pointed to from a persistent, so it's referenced, but
- // the weak processing may have taken place.
- if (map1->size()) {
- Iterator i1 = map1->begin();
- EXPECT_EQ(4, i1->value.first->Value());
- EXPECT_EQ(5, i1->value.second->Value());
- EXPECT_EQ(1003, i1->key->Value());
- }
- // The second map2 is on-stack, so its backing store must be referenced from
- // the stack. That makes the weak references strong.
- Iterator i2 = map2.begin();
- EXPECT_EQ(0, i2->value.first->Value());
- EXPECT_EQ(1, i2->value.second->Value());
- EXPECT_EQ(1001, i2->key->Value());
- // The third map2 is pointed to from the stack, so it's referenced, but the
- // weak processing may have taken place.
- if (map3->size()) {
- Iterator i3 = map3->begin();
- EXPECT_EQ(2, i3->value.first->Value());
- EXPECT_EQ(3, i3->value.second->Value());
- EXPECT_EQ(1002, i3->key->Value());
- }
- }
- PreciselyCollectGarbage();
-
- EXPECT_EQ(0u, map1->size());
- EXPECT_EQ(3, OffHeapInt::destructor_calls_);
-
- OffHeapInt::destructor_calls_ = 0;
-
- map1->insert(
- OffHeapInt::Create(2000),
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(103), living_int));
- // This one gets zapped at GC time because nothing holds the 103 alive.
- map1->insert(
- OffHeapInt::Create(2001),
- PairWithWeakHandling(living_int, MakeGarbageCollected<IntWrapper>(103)));
- map1->insert(OffHeapInt::Create(2002),
- PairWithWeakHandling(MakeGarbageCollected<IntWrapper>(103),
- MakeGarbageCollected<IntWrapper>(
- 103))); // This one gets zapped too.
- scoped_refptr<OffHeapInt> dupe_int(OffHeapInt::Create(2003));
- map1->insert(dupe_int, PairWithWeakHandling(living_int, living_int));
- // This one is identical to the previous and doesn't add anything.
- map1->insert(dupe_int, PairWithWeakHandling(living_int, living_int));
- dupe_int = nullptr;
-
- EXPECT_EQ(0, OffHeapInt::destructor_calls_);
- EXPECT_EQ(4u, map1->size());
- PreciselyCollectGarbage();
- EXPECT_EQ(2, OffHeapInt::destructor_calls_);
- EXPECT_EQ(2u, map1->size());
- Iterator i1 = map1->begin();
- EXPECT_TRUE(i1->value.first->Value() == 103 || i1->value.first == living_int);
- EXPECT_EQ(living_int, i1->value.second);
- ++i1;
- EXPECT_TRUE(i1->value.first->Value() == 103 || i1->value.first == living_int);
- EXPECT_EQ(living_int, i1->value.second);
-}
-
static void AddElementsToWeakMap(
HeapHashMap<int, WeakMember<IntWrapper>>* map) {
// Key cannot be zero in hashmap.
@@ -4983,93 +4625,6 @@ TEST_F(HeapTest, Bind) {
typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet;
-// These special traits will remove a set from a map when the set is empty.
-struct EmptyClearingHashSetTraits : HashTraits<WeakSet> {
- static const WTF::WeakHandlingFlag kWeakHandlingFlag = WTF::kWeakHandling;
-
- static bool IsAlive(WeakSet& set) {
- bool live_entries_found = false;
- WeakSet::iterator end = set.end();
- for (WeakSet::iterator it = set.begin(); it != end; ++it) {
- if (ThreadHeap::IsHeapObjectAlive(*it)) {
- live_entries_found = true;
- break;
- }
- }
- return live_entries_found;
- }
-
- template <typename VisitorDispatcher>
- static bool TraceInCollection(VisitorDispatcher visitor,
- WeakSet& set,
- WTF::WeakHandlingFlag weakenss) {
- bool live_entries_found = false;
- WeakSet::iterator end = set.end();
- for (WeakSet::iterator it = set.begin(); it != end; ++it) {
- if (ThreadHeap::IsHeapObjectAlive(*it)) {
- live_entries_found = true;
- break;
- }
- }
- // If there are live entries in the set then the set cannot be removed
- // from the map it is contained in, and we need to mark it (and its
- // backing) live. We just trace normally, which will invoke the normal
- // weak handling for any entries that are not live.
- if (live_entries_found)
- set.Trace(visitor);
- return !live_entries_found;
- }
-};
-
-// This is an example to show how you can remove entries from a T->WeakSet map
-// when the weak sets become empty. For this example we are using a type that
-// is given to use (HeapHashSet) rather than a type of our own. This means:
-// 1) We can't just override the HashTrait for the type since this would affect
-// all collections that use this kind of weak set. Instead we have our own
-// traits and use a map with custom traits for the value type. These traits
-// are the 5th template parameter, so we have to supply default values for
-// the 3rd and 4th template parameters
-// 2) We can't just inherit from WeakHandlingHashTraits, since that trait
-// assumes we can add methods to the type, but we can't add methods to
-// HeapHashSet.
-TEST_F(HeapTest, RemoveEmptySets) {
- ClearOutOldGarbage();
- OffHeapInt::destructor_calls_ = 0;
-
- Persistent<IntWrapper> living_int(MakeGarbageCollected<IntWrapper>(42));
-
- typedef scoped_refptr<OffHeapInt> Key;
- typedef HeapHashMap<Key, WeakSet, WTF::DefaultHash<Key>::Hash,
- HashTraits<Key>, EmptyClearingHashSetTraits>
- Map;
- Persistent<Map> map(MakeGarbageCollected<Map>());
- map->insert(OffHeapInt::Create(1), WeakSet());
- {
- WeakSet& set = map->begin()->value;
- set.insert(MakeGarbageCollected<IntWrapper>(
- 103)); // Weak set can't hold this long.
- set.insert(living_int); // This prevents the set from being emptied.
- EXPECT_EQ(2u, set.size());
- }
-
- // The set we add here is empty, so the entry will be removed from the map
- // at the next GC.
- map->insert(OffHeapInt::Create(2), WeakSet());
- EXPECT_EQ(2u, map->size());
-
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, map->size()); // The one with key 2 was removed.
- EXPECT_EQ(1, OffHeapInt::destructor_calls_);
- {
- WeakSet& set = map->begin()->value;
- EXPECT_EQ(1u, set.size());
- }
-
- living_int.Clear(); // The weak set can no longer keep the '42' alive now.
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, map->size());
-}
-
TEST_F(HeapTest, EphemeronsInEphemerons) {
typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap;
typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap;
@@ -5184,18 +4739,8 @@ TEST_F(HeapTest, EphemeronsPointToEphemerons) {
}
TEST_F(HeapTest, Ephemeron) {
- typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling> WeakPairMap;
- typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper>> PairWeakMap;
typedef HeapHashSet<WeakMember<IntWrapper>> Set;
- Persistent<WeakPairMap> weak_pair_map = MakeGarbageCollected<WeakPairMap>();
- Persistent<WeakPairMap> weak_pair_map2 = MakeGarbageCollected<WeakPairMap>();
- Persistent<WeakPairMap> weak_pair_map3 = MakeGarbageCollected<WeakPairMap>();
- Persistent<WeakPairMap> weak_pair_map4 = MakeGarbageCollected<WeakPairMap>();
-
- Persistent<PairWeakMap> pair_weak_map = MakeGarbageCollected<PairWeakMap>();
- Persistent<PairWeakMap> pair_weak_map2 = MakeGarbageCollected<PairWeakMap>();
-
Persistent<Set> set = MakeGarbageCollected<Set>();
Persistent<IntWrapper> wp1 = MakeGarbageCollected<IntWrapper>(1);
@@ -5203,24 +4748,6 @@ TEST_F(HeapTest, Ephemeron) {
Persistent<IntWrapper> pw1 = MakeGarbageCollected<IntWrapper>(3);
Persistent<IntWrapper> pw2 = MakeGarbageCollected<IntWrapper>(4);
- weak_pair_map->insert(wp1, PairWithWeakHandling(wp1, wp1));
- weak_pair_map->insert(wp2, PairWithWeakHandling(wp1, wp1));
- weak_pair_map2->insert(wp1, PairWithWeakHandling(wp1, wp2));
- weak_pair_map2->insert(wp2, PairWithWeakHandling(wp1, wp2));
- // The map from wp1 to (wp2, wp1) would mark wp2 live, so we skip that.
- weak_pair_map3->insert(wp2, PairWithWeakHandling(wp2, wp1));
- weak_pair_map4->insert(wp1, PairWithWeakHandling(wp2, wp2));
- weak_pair_map4->insert(wp2, PairWithWeakHandling(wp2, wp2));
-
- pair_weak_map->insert(PairWithWeakHandling(pw1, pw1), pw1);
- pair_weak_map->insert(PairWithWeakHandling(pw1, pw2), pw1);
- // The map from (pw2, pw1) to pw1 would make pw2 live, so we skip that.
- pair_weak_map->insert(PairWithWeakHandling(pw2, pw2), pw1);
- pair_weak_map2->insert(PairWithWeakHandling(pw1, pw1), pw2);
- pair_weak_map2->insert(PairWithWeakHandling(pw1, pw2), pw2);
- pair_weak_map2->insert(PairWithWeakHandling(pw2, pw1), pw2);
- pair_weak_map2->insert(PairWithWeakHandling(pw2, pw2), pw2);
-
set->insert(wp1);
set->insert(wp2);
set->insert(pw1);
@@ -5228,14 +4755,6 @@ TEST_F(HeapTest, Ephemeron) {
PreciselyCollectGarbage();
- EXPECT_EQ(2u, weak_pair_map->size());
- EXPECT_EQ(2u, weak_pair_map2->size());
- EXPECT_EQ(1u, weak_pair_map3->size());
- EXPECT_EQ(2u, weak_pair_map4->size());
-
- EXPECT_EQ(3u, pair_weak_map->size());
- EXPECT_EQ(4u, pair_weak_map2->size());
-
EXPECT_EQ(4u, set->size());
wp2.Clear(); // Kills all entries in the weakPairMaps except the first.
@@ -5244,14 +4763,6 @@ TEST_F(HeapTest, Ephemeron) {
for (int i = 0; i < 2; i++) {
PreciselyCollectGarbage();
- EXPECT_EQ(1u, weak_pair_map->size());
- EXPECT_EQ(0u, weak_pair_map2->size());
- EXPECT_EQ(0u, weak_pair_map3->size());
- EXPECT_EQ(0u, weak_pair_map4->size());
-
- EXPECT_EQ(1u, pair_weak_map->size());
- EXPECT_EQ(0u, pair_weak_map2->size());
-
EXPECT_EQ(2u, set->size()); // wp1 and pw1.
}
@@ -5260,8 +4771,6 @@ TEST_F(HeapTest, Ephemeron) {
PreciselyCollectGarbage();
- EXPECT_EQ(0u, weak_pair_map->size());
- EXPECT_EQ(0u, pair_weak_map->size());
EXPECT_EQ(0u, set->size());
}
@@ -6100,4 +5609,24 @@ TEST_F(HeapTest, AccessDeletedBackingStore) {
}
}
+class GCBase : public GarbageCollected<GCBase> {
+ public:
+ virtual void Trace(Visitor*) {}
+};
+
+class GCDerived final : public GCBase {
+ public:
+ static int destructor_called;
+ void Trace(Visitor*) override {}
+ ~GCDerived() { ++destructor_called; }
+};
+
+int GCDerived::destructor_called = 0;
+
+TEST_F(HeapTest, CallMostDerivedFinalizer) {
+ MakeGarbageCollected<GCDerived>();
+ PreciselyCollectGarbage();
+ EXPECT_EQ(1, GCDerived::destructor_called);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
index 528bd25aa8e..3292be44245 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
@@ -49,8 +49,7 @@ IncrementalMarkingTestDriver::~IncrementalMarkingTestDriver() {
}
void IncrementalMarkingTestDriver::Start() {
- thread_state_->IncrementalMarkingStart(
- BlinkGC::GCReason::kForcedGCForTesting);
+ thread_state_->IncrementalMarkingStartForTesting();
}
bool IncrementalMarkingTestDriver::SingleStep(BlinkGC::StackState stack_state) {
@@ -70,12 +69,30 @@ void IncrementalMarkingTestDriver::FinishSteps(
}
}
+bool IncrementalMarkingTestDriver::SingleConcurrentStep(
+ BlinkGC::StackState stack_state) {
+ CHECK(thread_state_->IsIncrementalMarking());
+ if (thread_state_->GetGCState() ==
+ ThreadState::kIncrementalMarkingStepScheduled) {
+ thread_state_->IncrementalMarkingStep(stack_state, base::TimeDelta());
+ return true;
+ }
+ return false;
+}
+
+void IncrementalMarkingTestDriver::FinishConcurrentSteps(
+ BlinkGC::StackState stack_state) {
+ CHECK(thread_state_->IsIncrementalMarking());
+ while (SingleConcurrentStep(stack_state)) {
+ }
+}
+
void IncrementalMarkingTestDriver::FinishGC(bool complete_sweep) {
CHECK(thread_state_->IsIncrementalMarking());
FinishSteps(BlinkGC::StackState::kNoHeapPointersOnStack);
CHECK_EQ(ThreadState::kIncrementalMarkingFinalizeScheduled,
thread_state_->GetGCState());
- thread_state_->RunScheduledGC(BlinkGC::StackState::kNoHeapPointersOnStack);
+ thread_state_->IncrementalMarkingFinalize();
CHECK(!thread_state_->IsIncrementalMarking());
if (complete_sweep) {
thread_state_->CompleteSweep();
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
index 0d80e38b360..a9d37305606 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
@@ -156,12 +156,47 @@ class IncrementalMarkingTestDriver {
BlinkGC::StackState::kNoHeapPointersOnStack);
void FinishGC(bool complete_sweep = true);
+ // Methods for forcing a concurrent marking step without any assistance from
+ // mutator thread (i.e. without incremental marking on the mutator thread).
+ bool SingleConcurrentStep(BlinkGC::StackState stack_state =
+ BlinkGC::StackState::kNoHeapPointersOnStack);
+ void FinishConcurrentSteps(BlinkGC::StackState stack_state =
+ BlinkGC::StackState::kNoHeapPointersOnStack);
+
size_t GetHeapCompactLastFixupCount() const;
private:
ThreadState* const thread_state_;
};
+class IntegerObject : public GarbageCollected<IntegerObject> {
+ public:
+ void Trace(blink::Visitor* visitor) {}
+
+ int Value() const { return x_; }
+
+ bool operator==(const IntegerObject& other) const {
+ return other.Value() == Value();
+ }
+
+ unsigned GetHash() { return IntHash<int>::GetHash(x_); }
+
+ explicit IntegerObject(int x) : x_(x) {}
+
+ private:
+ int x_;
+};
+
+struct IntegerObjectHash {
+ static unsigned GetHash(const IntegerObject& key) {
+ return WTF::HashInt(static_cast<uint32_t>(key.Value()));
+ }
+
+ static bool Equal(const IntegerObject& a, const IntegerObject& b) {
+ return a == b;
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TEST_UTILITIES_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
index b278208dd5b..80ef9b05470 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
@@ -81,7 +81,7 @@ class AlternatingThreadTester {
ActiveThread() = kMainThreadActive;
std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("Test Worker Thread"));
PostCrossThreadTask(
*worker_thread->GetTaskRunner(), FROM_HERE,
@@ -199,16 +199,14 @@ class MarkingSameThreadCheckTester : public AlternatingThreadTester {
};
#if DCHECK_IS_ON()
-// TODO(keishi) This test is flaky on mac-rel bot.
-// crbug.com/709069
-#if !defined(OS_MACOSX)
-TEST_F(HeapThreadDeathTest, MarkingSameThreadCheck) {
+// TODO(keishi) This test is flaky on mac-rel bot. https://crbug.com/709069, and
+// times out on other bots. https://crbug.com/993148.
+TEST_F(HeapThreadDeathTest, DISABLED_MarkingSameThreadCheck) {
// This will crash during marking, at the DCHECK in Visitor::markHeader() or
// earlier.
EXPECT_DEATH(MarkingSameThreadCheckTester().Test(), "");
}
#endif
-#endif
class DestructorLockingObject
: public GarbageCollected<DestructorLockingObject> {
diff --git a/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
index e30bbba1f4a..c3725ad1524 100644
--- a/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -37,7 +37,6 @@ class BackingVisitor : public Visitor {
~BackingVisitor() final {}
void ProcessBackingStore(HeapObjectHeader* header) {
- EXPECT_TRUE(header->IsValid());
EXPECT_TRUE(header->IsMarked());
header->Unmark();
GCInfoTable::Get()
@@ -57,6 +56,19 @@ class BackingVisitor : public Visitor {
header->Mark();
}
+ bool VisitEphemeronKeyValuePair(
+ void* key,
+ void* value,
+ EphemeronTracingCallback key_trace_callback,
+ EphemeronTracingCallback value_trace_callback) final {
+ const bool key_is_dead = key_trace_callback(this, key);
+ if (key_is_dead)
+ return true;
+ const bool value_is_dead = value_trace_callback(this, value);
+ DCHECK(!value_is_dead);
+ return false;
+ }
+
// Unused overrides.
void VisitWeak(void* object,
void* object_weak_ref,
@@ -68,11 +80,12 @@ class BackingVisitor : public Visitor {
void VisitBackingStoreWeakly(void*,
void**,
TraceDescriptor,
+ TraceDescriptor,
WeakCallback,
void*) final {}
void VisitBackingStoreOnly(void*, void**) final {}
void RegisterBackingStoreCallback(void* slot, MovingObjectCallback) final {}
- void RegisterWeakCallback(void* closure, WeakCallback) final {}
+ void RegisterWeakCallback(WeakCallback, void*) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
private:
@@ -111,12 +124,14 @@ class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
: IncrementalMarkingScopeBase(thread_state),
gc_forbidden_scope_(thread_state),
marking_worklist_(heap_.GetMarkingWorklist()),
+ write_barrier_worklist_(heap_.GetWriteBarrierWorklist()),
not_fully_constructed_worklist_(
heap_.GetNotFullyConstructedWorklist()) {
thread_state_->SetGCPhase(ThreadState::GCPhase::kMarking);
ThreadState::AtomicPauseScope atomic_pause_scope_(thread_state_);
ScriptForbiddenScope script_forbidden_scope;
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
thread_state->EnableIncrementalMarkingBarrier();
thread_state->current_gc_data_.visitor = std::make_unique<MarkingVisitor>(
@@ -125,6 +140,7 @@ class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
~IncrementalMarkingScope() {
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
thread_state_->DisableIncrementalMarkingBarrier();
// Need to clear out unused worklists that might have been polluted during
@@ -135,6 +151,9 @@ class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
}
MarkingWorklist* marking_worklist() const { return marking_worklist_; }
+ WriteBarrierWorklist* write_barrier_worklist() const {
+ return write_barrier_worklist_;
+ }
NotFullyConstructedWorklist* not_fully_constructed_worklist() const {
return not_fully_constructed_worklist_;
}
@@ -142,6 +161,7 @@ class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
protected:
ThreadState::GCForbiddenScope gc_forbidden_scope_;
MarkingWorklist* const marking_worklist_;
+ WriteBarrierWorklist* const write_barrier_worklist_;
NotFullyConstructedWorklist* const not_fully_constructed_worklist_;
};
@@ -156,6 +176,7 @@ class ExpectWriteBarrierFires : public IncrementalMarkingScope {
objects_(objects),
backing_visitor_(thread_state_, &objects_) {
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
for (void* object : objects_) {
// Ensure that the object is in the normal arena so we can ignore backing
// objects on the marking stack.
@@ -168,19 +189,36 @@ class ExpectWriteBarrierFires : public IncrementalMarkingScope {
}
~ExpectWriteBarrierFires() {
- EXPECT_FALSE(marking_worklist_->IsGlobalEmpty());
+ // All objects watched should be on the marking or write barrier worklist.
MarkingItem item;
- // All objects watched should be on the marking stack.
while (marking_worklist_->Pop(WorklistTaskId::MutatorThread, &item)) {
// Inspect backing stores to allow specifying objects that are only
// reachable through a backing store.
if (!ThreadHeap::IsNormalArenaIndex(
- PageFromObject(item.object)->Arena()->ArenaIndex())) {
+ PageFromObject(item.base_object_payload)
+ ->Arena()
+ ->ArenaIndex())) {
backing_visitor_.ProcessBackingStore(
- HeapObjectHeader::FromPayload(item.object));
+ HeapObjectHeader::FromPayload(item.base_object_payload));
continue;
}
- auto** pos = std::find(objects_.begin(), objects_.end(), item.object);
+ auto** pos =
+ std::find(objects_.begin(), objects_.end(), item.base_object_payload);
+ if (objects_.end() != pos)
+ objects_.erase(pos);
+ }
+ HeapObjectHeader* header;
+ while (
+ write_barrier_worklist_->Pop(WorklistTaskId::MutatorThread, &header)) {
+ // Inspect backing stores to allow specifying objects that are only
+ // reachable through a backing store.
+ if (!ThreadHeap::IsNormalArenaIndex(
+ PageFromObject(header->Payload())->Arena()->ArenaIndex())) {
+ backing_visitor_.ProcessBackingStore(header);
+ continue;
+ }
+ auto** pos =
+ std::find(objects_.begin(), objects_.end(), header->Payload());
if (objects_.end() != pos)
objects_.erase(pos);
}
@@ -191,6 +229,7 @@ class ExpectWriteBarrierFires : public IncrementalMarkingScope {
header->Unmark();
}
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
}
private:
@@ -208,6 +247,7 @@ class ExpectNoWriteBarrierFires : public IncrementalMarkingScope {
std::initializer_list<void*> objects)
: IncrementalMarkingScope(thread_state) {
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
for (void* object : objects_) {
HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
headers_.push_back(std::make_pair(header, header->IsMarked()));
@@ -216,6 +256,7 @@ class ExpectNoWriteBarrierFires : public IncrementalMarkingScope {
~ExpectNoWriteBarrierFires() {
EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
+ EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
for (const auto& pair : headers_) {
EXPECT_EQ(pair.second, pair.first->IsMarked());
pair.first->Unmark();
@@ -859,120 +900,6 @@ TEST_F(IncrementalMarkingTest, HeapHashSetSwap) {
Swap<HeapHashSet<WeakMember<Object>>>();
}
-class StrongWeakPair : public std::pair<Member<Object>, WeakMember<Object>> {
- DISALLOW_NEW();
-
- typedef std::pair<Member<Object>, WeakMember<Object>> Base;
-
- public:
- StrongWeakPair(Object* obj1, Object* obj2) : Base(obj1, obj2) {}
-
- StrongWeakPair(WTF::HashTableDeletedValueType)
- : Base(WTF::kHashTableDeletedValue, nullptr) {}
-
- bool IsHashTableDeletedValue() const {
- return first.IsHashTableDeletedValue();
- }
-
- // Trace will be called for write barrier invocations. Only strong members
- // are interesting.
- void Trace(blink::Visitor* visitor) { visitor->Trace(first); }
-
- // TraceInCollection will be called for weak processing.
- template <typename VisitorDispatcher>
- bool TraceInCollection(VisitorDispatcher visitor,
- WTF::WeakHandlingFlag weakness) {
- visitor->Trace(first);
- if (weakness == WTF::kNoWeakHandling) {
- visitor->Trace(second);
- }
- return false;
- }
-};
-
-} // namespace incremental_marking_test
-} // namespace blink
-
-namespace WTF {
-
-template <>
-struct HashTraits<blink::incremental_marking_test::StrongWeakPair>
- : SimpleClassHashTraits<blink::incremental_marking_test::StrongWeakPair> {
- static const WTF::WeakHandlingFlag kWeakHandlingFlag = WTF::kWeakHandling;
-
- template <typename U = void>
- struct IsTraceableInCollection {
- static const bool value = true;
- };
-
- static const bool kHasIsEmptyValueFunction = true;
- static bool IsEmptyValue(
- const blink::incremental_marking_test::StrongWeakPair& value) {
- return !value.first;
- }
-
- static void ConstructDeletedValue(
- blink::incremental_marking_test::StrongWeakPair& slot,
- bool) {
- new (NotNull, &slot)
- blink::incremental_marking_test::StrongWeakPair(kHashTableDeletedValue);
- }
-
- static bool IsDeletedValue(
- const blink::incremental_marking_test::StrongWeakPair& value) {
- return value.IsHashTableDeletedValue();
- }
-
- template <typename VisitorDispatcher>
- static bool TraceInCollection(
- VisitorDispatcher visitor,
- blink::incremental_marking_test::StrongWeakPair& t,
- WTF::WeakHandlingFlag weakness) {
- return t.TraceInCollection(visitor, weakness);
- }
-};
-
-template <>
-struct DefaultHash<blink::incremental_marking_test::StrongWeakPair> {
- typedef PairHash<blink::Member<blink::incremental_marking_test::Object>,
- blink::WeakMember<blink::incremental_marking_test::Object>>
- Hash;
-};
-
-template <>
-struct IsTraceable<blink::incremental_marking_test::StrongWeakPair> {
- static const bool value = IsTraceable<std::pair<
- blink::Member<blink::incremental_marking_test::Object>,
- blink::WeakMember<blink::incremental_marking_test::Object>>>::value;
-};
-
-} // namespace WTF
-
-namespace blink {
-namespace incremental_marking_test {
-
-TEST_F(IncrementalMarkingTest, HeapHashSetStrongWeakPair) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashSet<StrongWeakPair> set;
- {
- // Both, the weak and the strong field, are hit by the write barrier.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- set.insert(StrongWeakPair(obj1, obj2));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapLinkedHashSetStrongWeakPair) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapLinkedHashSet<StrongWeakPair> set;
- {
- // Both, the weak and the strong field, are hit by the write barrier.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- set.insert(StrongWeakPair(obj1, obj2));
- }
-}
-
// =============================================================================
// HeapLinkedHashSet support. ==================================================
// =============================================================================
@@ -1316,32 +1243,6 @@ TEST_F(IncrementalMarkingTest, HeapHashMapSwapWeakMemberMember) {
}
}
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertStrongWeakPairMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- HeapHashMap<StrongWeakPair, Member<Object>> map;
- {
- // Tests that the write barrier also fires for entities such as
- // StrongWeakPair that don't overload assignment operators in translators.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj3});
- map.insert(StrongWeakPair(obj1, obj2), obj3);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertMemberStrongWeakPair) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, StrongWeakPair> map;
- {
- // Tests that the write barrier also fires for entities such as
- // StrongWeakPair that don't overload assignment operators in translators.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.insert(obj1, StrongWeakPair(obj2, obj3));
- }
-}
-
TEST_F(IncrementalMarkingTest, HeapHashMapCopyKeysToVectorMember) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
@@ -1442,16 +1343,23 @@ TEST_F(IncrementalMarkingTest, WriteBarrierDuringMixinConstruction) {
// Clear any objects that have been added to the regular marking worklist in
// the process of calling the constructor.
- EXPECT_FALSE(scope.marking_worklist()->IsGlobalEmpty());
MarkingItem marking_item;
while (scope.marking_worklist()->Pop(WorklistTaskId::MutatorThread,
&marking_item)) {
HeapObjectHeader* header =
- HeapObjectHeader::FromPayload(marking_item.object);
+ HeapObjectHeader::FromPayload(marking_item.base_object_payload);
if (header->IsMarked())
header->Unmark();
}
EXPECT_TRUE(scope.marking_worklist()->IsGlobalEmpty());
+ // Clear any write barriers so far.
+ HeapObjectHeader* header;
+ while (scope.write_barrier_worklist()->Pop(WorklistTaskId::MutatorThread,
+ &header)) {
+ if (header->IsMarked())
+ header->Unmark();
+ }
+ EXPECT_TRUE(scope.write_barrier_worklist()->IsGlobalEmpty());
EXPECT_FALSE(scope.not_fully_constructed_worklist()->IsGlobalEmpty());
NotFullyConstructedItem partial_item;
@@ -1615,7 +1523,7 @@ TEST_F(IncrementalMarkingTest, WeakHashMapHeapCompaction) {
driver.FinishGC();
// Weak callback should register the slot.
- EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 1u);
+ EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 2u);
}
TEST_F(IncrementalMarkingTest, ConservativeGCWhileCompactionScheduled) {
@@ -1718,15 +1626,12 @@ TEST_F(IncrementalMarkingTest, StepDuringObjectConstruction) {
// Publish not-fully-constructed object |thiz| by triggering write
// barrier for the object.
holder->set_value(thiz);
- CHECK(HeapObjectHeader::FromPayload(holder->value())->IsValid());
// Finish call incremental steps.
driver->FinishSteps(BlinkGC::StackState::kHeapPointersOnStack);
},
&driver, holder.Get()),
MakeGarbageCollected<Object>());
driver.FinishGC();
- CHECK(HeapObjectHeader::FromPayload(holder->value())->IsValid());
- CHECK(HeapObjectHeader::FromPayload(holder->value()->value())->IsValid());
PreciselyCollectGarbage();
}
@@ -1754,8 +1659,6 @@ TEST_F(IncrementalMarkingTest, StepDuringMixinObjectConstruction) {
&driver, holder.Get()),
MakeGarbageCollected<Object>());
driver.FinishGC();
- CHECK(holder->value()->GetHeapObjectHeader()->IsValid());
- CHECK(HeapObjectHeader::FromPayload(holder->value()->value())->IsValid());
PreciselyCollectGarbage();
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
index 392b774269c..5e0e7fed6db 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
@@ -19,7 +19,6 @@ void MarkingVerifier::VerifyObject(HeapObjectHeader* header) {
const bool can_verify =
!info->has_v_table || blink::VTableInitialized(header->Payload());
if (can_verify) {
- CHECK(header->IsValid());
parent_ = header;
info->trace(this, header->Payload());
}
@@ -53,7 +52,8 @@ void MarkingVerifier::VisitBackingStoreStrongly(void* object,
void MarkingVerifier::VisitBackingStoreWeakly(void* object,
void**,
- TraceDescriptor desc,
+ TraceDescriptor strong_desc,
+ TraceDescriptor weak_desc,
WeakCallback,
void*) {
if (!object)
@@ -64,7 +64,7 @@ void MarkingVerifier::VisitBackingStoreWeakly(void* object,
// treated strongly when found through stack scanning. The verification
// here only makes sure that the backing itself is properly marked. Weak
// backing stores found through
- VerifyChild(object, desc.base_object_payload);
+ VerifyChild(object, weak_desc.base_object_payload);
}
void MarkingVerifier::VerifyChild(void* object, void* base_object_payload) {
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
index 6485dcc377b..14e53676d96 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -28,13 +28,14 @@ class MarkingVerifier final : public Visitor {
void VisitBackingStoreWeakly(void*,
void**,
TraceDescriptor,
+ TraceDescriptor,
WeakCallback,
void*) final;
// Unused overrides.
void VisitBackingStoreOnly(void*, void**) final {}
void RegisterBackingStoreCallback(void*, MovingObjectCallback) final {}
- void RegisterWeakCallback(void*, WeakCallback) final {}
+ void RegisterWeakCallback(WeakCallback, void*) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
private:
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
index f789e3a9b36..8ed5a880494 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -18,9 +18,9 @@ ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) {
} // namespace
-MarkingVisitorBase::MarkingVisitorBase(ThreadState* state,
- MarkingMode marking_mode,
- int task_id)
+MarkingVisitorCommon::MarkingVisitorCommon(ThreadState* state,
+ MarkingMode marking_mode,
+ int task_id)
: Visitor(state),
marking_worklist_(Heap().GetMarkingWorklist(), task_id),
not_fully_constructed_worklist_(Heap().GetNotFullyConstructedWorklist(),
@@ -34,17 +34,17 @@ MarkingVisitorBase::MarkingVisitorBase(ThreadState* state,
marking_mode_(marking_mode),
task_id_(task_id) {}
-void MarkingVisitorBase::FlushCompactionWorklists() {
+void MarkingVisitorCommon::FlushCompactionWorklists() {
movable_reference_worklist_.FlushToGlobal();
backing_store_callback_worklist_.FlushToGlobal();
}
-void MarkingVisitorBase::RegisterWeakCallback(void* object,
- WeakCallback callback) {
- weak_callback_worklist_.Push({object, callback});
+void MarkingVisitorCommon::RegisterWeakCallback(WeakCallback callback,
+ void* object) {
+ weak_callback_worklist_.Push({callback, object});
}
-void MarkingVisitorBase::RegisterBackingStoreReference(void** slot) {
+void MarkingVisitorCommon::RegisterBackingStoreReference(void** slot) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
MovableReference* movable_reference =
@@ -55,7 +55,7 @@ void MarkingVisitorBase::RegisterBackingStoreReference(void** slot) {
}
}
-void MarkingVisitorBase::RegisterBackingStoreCallback(
+void MarkingVisitorCommon::RegisterBackingStoreCallback(
void* backing,
MovingObjectCallback callback) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
@@ -65,19 +65,67 @@ void MarkingVisitorBase::RegisterBackingStoreCallback(
}
}
-bool MarkingVisitorBase::RegisterWeakTable(
- const void* closure,
- EphemeronCallback iteration_callback) {
- weak_table_worklist_.Push({const_cast<void*>(closure), iteration_callback});
- return true;
+void MarkingVisitorCommon::VisitWeak(void* object,
+ void* object_weak_ref,
+ TraceDescriptor desc,
+ WeakCallback callback) {
+ // Filter out already marked values. The write barrier for WeakMember
+ // ensures that any newly set value after this point is kept alive and does
+ // not require the callback.
+ if (desc.base_object_payload != BlinkGC::kNotFullyConstructedObject &&
+ HeapObjectHeader::FromPayload(desc.base_object_payload)
+ ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
+ return;
+ RegisterWeakCallback(callback, object_weak_ref);
}
-void MarkingVisitorBase::AdjustMarkedBytes(HeapObjectHeader* header,
- size_t old_size) {
- DCHECK(header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>());
- // Currently, only expansion of an object is supported during marking.
- DCHECK_GE(header->size(), old_size);
- marked_bytes_ += header->size() - old_size;
+void MarkingVisitorCommon::VisitBackingStoreStrongly(void* object,
+ void** object_slot,
+ TraceDescriptor desc) {
+ RegisterBackingStoreReference(object_slot);
+ if (!object)
+ return;
+ Visit(object, desc);
+}
+
+// All work is registered through RegisterWeakCallback.
+void MarkingVisitorCommon::VisitBackingStoreWeakly(
+ void* object,
+ void** object_slot,
+ TraceDescriptor strong_desc,
+ TraceDescriptor weak_desc,
+ WeakCallback weak_callback,
+ void* weak_callback_parameter) {
+ RegisterBackingStoreReference(object_slot);
+ if (!object)
+ return;
+ RegisterWeakCallback(weak_callback, weak_callback_parameter);
+
+ if (weak_desc.callback)
+ weak_table_worklist_.Push(weak_desc);
+}
+
+bool MarkingVisitorCommon::VisitEphemeronKeyValuePair(
+ void* key,
+ void* value,
+ EphemeronTracingCallback key_trace_callback,
+ EphemeronTracingCallback value_trace_callback) {
+ const bool key_is_dead = key_trace_callback(this, key);
+ if (key_is_dead)
+ return true;
+ const bool value_is_dead = value_trace_callback(this, value);
+ DCHECK(!value_is_dead);
+ return false;
+}
+
+void MarkingVisitorCommon::VisitBackingStoreOnly(void* object,
+ void** object_slot) {
+ RegisterBackingStoreReference(object_slot);
+ if (!object)
+ return;
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
+ MarkHeaderNoTracing(header);
+ AccountMarkedBytes(header);
}
// static
@@ -97,30 +145,27 @@ bool MarkingVisitor::WriteBarrierSlow(void* value) {
HeapObjectHeader* header;
if (LIKELY(!base_page->IsLargeObjectPage())) {
header = reinterpret_cast<HeapObjectHeader*>(
- static_cast<NormalPage*>(base_page)->FindHeaderFromAddress(
- reinterpret_cast<Address>(value)));
+ static_cast<NormalPage*>(base_page)
+ ->FindHeaderFromAddress<HeapObjectHeader::AccessMode::kAtomic>(
+ reinterpret_cast<Address>(value)));
} else {
- header = static_cast<LargeObjectPage*>(base_page)->ObjectHeader();
+ LargeObjectPage* large_page = static_cast<LargeObjectPage*>(base_page);
+ header = large_page->ObjectHeader();
}
- DCHECK(header->IsValid());
if (!header->TryMark<HeapObjectHeader::AccessMode::kAtomic>())
return false;
- if (UNLIKELY(header->IsInConstruction())) {
+ MarkingVisitor* visitor = thread_state->CurrentVisitor();
+ if (UNLIKELY(IsInConstruction(header))) {
// It is assumed that objects on not_fully_constructed_worklist_ are not
// marked.
header->Unmark();
- thread_state->CurrentVisitor()->not_fully_constructed_worklist_.Push(
- header->Payload());
+ visitor->not_fully_constructed_worklist_.Push(header->Payload());
return true;
}
- MarkingVisitor* visitor = thread_state->CurrentVisitor();
- visitor->AccountMarkedBytes(header);
- visitor->marking_worklist_.Push(
- {header->Payload(),
- GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex())->trace});
+ visitor->write_barrier_worklist_.Push(header);
return true;
}
@@ -144,7 +189,9 @@ void MarkingVisitor::TraceMarkedBackingStoreSlow(void* value) {
}
MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
- : MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread) {
+ : MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread),
+ write_barrier_worklist_(Heap().GetWriteBarrierWorklist(),
+ WorklistTaskId::MutatorThread) {
DCHECK(state->InAtomicMarkingPause());
DCHECK(state->CheckThread());
}
@@ -152,10 +199,13 @@ MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
void MarkingVisitor::DynamicallyMarkAddress(Address address) {
HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress(address);
DCHECK(header);
- DCHECK(!header->IsInConstruction());
+ DCHECK(!IsInConstruction(header));
const GCInfo* gc_info =
GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
- MarkHeader(header, gc_info->trace);
+ if (MarkHeaderNoTracing(header)) {
+ marking_worklist_.Push(
+ {reinterpret_cast<void*>(header->Payload()), gc_info->trace});
+ }
}
void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
@@ -171,11 +221,12 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
if (!header || header->IsMarked())
return;
- // Simple case for fully constructed objects.
+ // Simple case for fully constructed objects. This just adds the object to the
+ // regular marking worklist.
const GCInfo* gc_info =
GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
- if (!header->IsInConstruction()) {
- MarkHeader(header, gc_info->trace);
+ if (!IsInConstruction(header)) {
+ MarkHeader(header, {header->Payload(), gc_info->trace});
return;
}
@@ -206,6 +257,7 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
if (maybe_ptr)
Heap().CheckAndMarkPointer(this, maybe_ptr);
}
+ AccountMarkedBytes(header);
}
void MarkingVisitor::FlushMarkingWorklist() {
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
index a75facecbf9..0bb441d6b6a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
@@ -15,81 +15,32 @@ namespace blink {
class BasePage;
// Base visitor used to mark Oilpan objects on any thread.
-class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
+class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
public:
enum MarkingMode {
- // This is a default visitor. This is used for MarkingType=kAtomicMarking
- // and MarkingType=kIncrementalMarking.
+ // Default visitor mode used for regular marking.
kGlobalMarking,
- // Perform global marking along with preparing for additional sweep
- // compaction of heap arenas afterwards. Compared to the GlobalMarking
- // visitor, this visitor will also register references to objects
- // that might be moved during arena compaction -- the compaction
- // pass will then fix up those references when the object move goes
- // ahead.
+ // Visitor mode recording slots for compaction during marking.
kGlobalMarkingWithCompaction,
};
- //
- // Implementation of the visitor interface.
- //
-
- void Visit(void* object, TraceDescriptor desc) final {
- DCHECK(object);
- if (desc.base_object_payload == BlinkGC::kNotFullyConstructedObject) {
- // This means that the objects are not-yet-fully-constructed. See comments
- // on GarbageCollectedMixin for how those objects are handled.
- not_fully_constructed_worklist_.Push(object);
- return;
- }
- MarkHeader(HeapObjectHeader::FromPayload(desc.base_object_payload),
- desc.callback);
- }
-
- void VisitWeak(void* object,
- void* object_weak_ref,
- TraceDescriptor desc,
- WeakCallback callback) final {
- // Filter out already marked values. The write barrier for WeakMember
- // ensures that any newly set value after this point is kept alive and does
- // not require the callback.
- if (desc.base_object_payload != BlinkGC::kNotFullyConstructedObject &&
- HeapObjectHeader::FromPayload(desc.base_object_payload)
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
- return;
- RegisterWeakCallback(object_weak_ref, callback);
- }
-
- void VisitBackingStoreStrongly(void* object,
- void** object_slot,
- TraceDescriptor desc) final {
- RegisterBackingStoreReference(object_slot);
- if (!object)
- return;
- Visit(object, desc);
- }
-
- // All work is registered through RegisterWeakCallback.
- void VisitBackingStoreWeakly(void* object,
- void** object_slot,
- TraceDescriptor desc,
- WeakCallback callback,
- void* parameter) final {
- RegisterBackingStoreReference(object_slot);
- if (!object)
- return;
- RegisterWeakCallback(parameter, callback);
- }
+ void VisitWeak(void*, void*, TraceDescriptor, WeakCallback) final;
+ void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final;
+ void VisitBackingStoreWeakly(void*,
+ void**,
+ TraceDescriptor,
+ TraceDescriptor,
+ WeakCallback,
+ void*) final;
+ bool VisitEphemeronKeyValuePair(void*,
+ void*,
+ EphemeronTracingCallback,
+ EphemeronTracingCallback) final;
// Used to only mark the backing store when it has been registered for weak
// processing. In this case, the contents are processed separately using
// the corresponding traits but the backing store requires marking.
- void VisitBackingStoreOnly(void* object, void** object_slot) final {
- RegisterBackingStoreReference(object_slot);
- if (!object)
- return;
- MarkHeaderNoTracing(HeapObjectHeader::FromPayload(object));
- }
+ void VisitBackingStoreOnly(void*, void**) final;
// This callback mechanism is needed to account for backing store objects
// containing intra-object pointers, all of which must be relocated/rebased
@@ -97,13 +48,8 @@ class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
//
// For Blink, |HeapLinkedHashSet<>| is currently the only abstraction which
// relies on this feature.
- void RegisterBackingStoreCallback(void* backing, MovingObjectCallback) final;
- bool RegisterWeakTable(const void* closure,
- EphemeronCallback iteration_callback) final;
- void RegisterWeakCallback(void* closure, WeakCallback) final;
-
- // Unused cross-component visit methods.
- void Visit(const TraceWrapperV8Reference<v8::Value>&) override {}
+ void RegisterBackingStoreCallback(void*, MovingObjectCallback) final;
+ void RegisterWeakCallback(WeakCallback, void*) final;
// Flush private segments remaining in visitor's worklists to global pools.
void FlushCompactionWorklists();
@@ -112,22 +58,18 @@ class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
int task_id() const { return task_id_; }
- void AdjustMarkedBytes(HeapObjectHeader*, size_t);
+ // Account for object's live bytes. Should only be adjusted when
+ // actually tracing through an already marked object. Logically, this means
+ // accounting for the bytes when transitioning from grey to black.
+ ALWAYS_INLINE void AccountMarkedBytes(HeapObjectHeader*);
protected:
- MarkingVisitorBase(ThreadState*, MarkingMode, int task_id);
- ~MarkingVisitorBase() override = default;
-
- // Marks an object and adds a tracing callback for processing of the object.
- inline void MarkHeader(HeapObjectHeader*, TraceCallback);
+ MarkingVisitorCommon(ThreadState*, MarkingMode, int task_id);
+ ~MarkingVisitorCommon() override = default;
// Try to mark an object without tracing. Returns true when the object was not
// marked upon calling.
- inline bool MarkHeaderNoTracing(HeapObjectHeader*);
-
- // Account for an object's live bytes. Should only be adjusted when
- // transitioning an object from unmarked to marked state.
- ALWAYS_INLINE void AccountMarkedBytes(HeapObjectHeader*);
+ bool MarkHeaderNoTracing(HeapObjectHeader*);
void RegisterBackingStoreReference(void** slot);
@@ -142,7 +84,7 @@ class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
int task_id_;
};
-ALWAYS_INLINE void MarkingVisitorBase::AccountMarkedBytes(
+ALWAYS_INLINE void MarkingVisitorCommon::AccountMarkedBytes(
HeapObjectHeader* header) {
marked_bytes_ +=
header->IsLargeObject()
@@ -150,9 +92,10 @@ ALWAYS_INLINE void MarkingVisitorBase::AccountMarkedBytes(
: header->size();
}
-inline bool MarkingVisitorBase::MarkHeaderNoTracing(HeapObjectHeader* header) {
+ALWAYS_INLINE bool MarkingVisitorCommon::MarkHeaderNoTracing(
+ HeapObjectHeader* header) {
DCHECK(header);
- DCHECK(State()->InAtomicMarkingPause() || State()->IsIncrementalMarking());
+ DCHECK(State()->IsIncrementalMarking() || State()->InAtomicMarkingPause());
// A GC should only mark the objects that belong in its heap.
DCHECK_EQ(State(),
PageFromObject(header->Payload())->Arena()->GetThreadState());
@@ -160,42 +103,75 @@ inline bool MarkingVisitorBase::MarkHeaderNoTracing(HeapObjectHeader* header) {
// freed backing store.
DCHECK(!header->IsFree());
- if (header->TryMark<HeapObjectHeader::AccessMode::kAtomic>()) {
- AccountMarkedBytes(header);
- return true;
+ return header->TryMark<HeapObjectHeader::AccessMode::kAtomic>();
+}
+
+// Base visitor used to mark Oilpan objects on any thread.
+template <class Specialized>
+class PLATFORM_EXPORT MarkingVisitorBase : public MarkingVisitorCommon {
+ public:
+ void Visit(void* object, TraceDescriptor desc) final;
+
+ // Unused cross-component visit methods.
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) override {}
+
+ protected:
+ MarkingVisitorBase(ThreadState* state, MarkingMode marking_mode, int task_id)
+ : MarkingVisitorCommon(state, marking_mode, task_id) {}
+ ~MarkingVisitorBase() override = default;
+
+ // Marks an object and adds a tracing callback for processing of the object.
+ void MarkHeader(HeapObjectHeader*, const TraceDescriptor&);
+};
+
+template <class Specialized>
+inline void MarkingVisitorBase<Specialized>::Visit(void* object,
+ TraceDescriptor desc) {
+ DCHECK(object);
+ if (desc.base_object_payload == BlinkGC::kNotFullyConstructedObject) {
+ // This means that the objects are not-yet-fully-constructed. See comments
+ // on GarbageCollectedMixin for how those objects are handled.
+ not_fully_constructed_worklist_.Push(object);
+ return;
}
- return false;
+ MarkHeader(HeapObjectHeader::FromPayload(desc.base_object_payload), desc);
}
-inline void MarkingVisitorBase::MarkHeader(HeapObjectHeader* header,
- TraceCallback callback) {
+// Marks an object and adds a tracing callback for processing of the object.
+template <class Specialized>
+ALWAYS_INLINE void MarkingVisitorBase<Specialized>::MarkHeader(
+ HeapObjectHeader* header,
+ const TraceDescriptor& desc) {
DCHECK(header);
- DCHECK(callback);
+ DCHECK(desc.callback);
- if (header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
+ if (Specialized::IsInConstruction(header)) {
not_fully_constructed_worklist_.Push(header->Payload());
} else if (MarkHeaderNoTracing(header)) {
- marking_worklist_.Push(
- {reinterpret_cast<void*>(header->Payload()), callback});
+ marking_worklist_.Push(desc);
}
}
// Visitor used to mark Oilpan objects on the main thread. Also implements
// various sorts of write barriers that should only be called from the main
// thread.
-class PLATFORM_EXPORT MarkingVisitor : public MarkingVisitorBase {
+class PLATFORM_EXPORT MarkingVisitor
+ : public MarkingVisitorBase<MarkingVisitor> {
public:
+ // Returns whether an object is in construction.
+ static bool IsInConstruction(HeapObjectHeader* header);
+
// Write barrier that adds |value| to the set of marked objects. The barrier
// bails out if marking is off or the object is not yet marked. Returns true
// if the object was marked on this call.
- ALWAYS_INLINE static bool WriteBarrier(void* value);
+ static bool WriteBarrier(void* value);
// Eagerly traces an already marked backing store ensuring that all its
// children are discovered by the marker. The barrier bails out if marking
// is off and on individual objects reachable if they are already marked. The
// barrier uses the callback function through GcInfo, so it will not inline
// any templated type-specific code.
- ALWAYS_INLINE static void TraceMarkedBackingStore(void* value);
+ static void TraceMarkedBackingStore(void* value);
MarkingVisitor(ThreadState*, MarkingMode);
~MarkingVisitor() override = default;
@@ -216,8 +192,18 @@ class PLATFORM_EXPORT MarkingVisitor : public MarkingVisitorBase {
// Exact version of the marking write barriers.
static bool WriteBarrierSlow(void*);
static void TraceMarkedBackingStoreSlow(void*);
+
+ WriteBarrierWorklist::View write_barrier_worklist_;
};
+// static
+ALWAYS_INLINE bool MarkingVisitor::IsInConstruction(HeapObjectHeader* header) {
+ // No need for atomics when operating on the mutator thread where
+ // construction happens.
+ return header->IsInConstruction<HeapObjectHeader::AccessMode::kNonAtomic>();
+}
+
+// static
ALWAYS_INLINE bool MarkingVisitor::WriteBarrier(void* value) {
if (!ThreadState::IsAnyIncrementalMarking())
return false;
@@ -227,6 +213,7 @@ ALWAYS_INLINE bool MarkingVisitor::WriteBarrier(void* value) {
return WriteBarrierSlow(value);
}
+// static
ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(void* value) {
if (!ThreadState::IsAnyIncrementalMarking())
return;
@@ -237,14 +224,24 @@ ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(void* value) {
}
// Visitor used to mark Oilpan objects on concurrent threads.
-class PLATFORM_EXPORT ConcurrentMarkingVisitor : public MarkingVisitorBase {
+class PLATFORM_EXPORT ConcurrentMarkingVisitor
+ : public MarkingVisitorBase<ConcurrentMarkingVisitor> {
public:
+ // Returns whether an object is in construction.
+ static bool IsInConstruction(HeapObjectHeader* header);
+
ConcurrentMarkingVisitor(ThreadState*, MarkingMode, int);
~ConcurrentMarkingVisitor() override = default;
virtual void FlushWorklists();
};
+// static
+ALWAYS_INLINE bool ConcurrentMarkingVisitor::IsInConstruction(
+ HeapObjectHeader* header) {
+ return header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>();
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/member.h b/chromium/third_party/blink/renderer/platform/heap/member.h
index 5bd7f25ce28..6c6f324271f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/member.h
+++ b/chromium/third_party/blink/renderer/platform/heap/member.h
@@ -73,7 +73,8 @@ class MemberPointerVerifier {
if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
HeapObjectHeader::CheckFromPayload(pointer);
} else {
- DCHECK(HeapObjectHeader::FromInnerAddress(pointer));
+ DCHECK(HeapObjectHeader::FromInnerAddress<
+ HeapObjectHeader::AccessMode::kAtomic>(pointer));
}
}
@@ -325,99 +326,6 @@ class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
friend class WTF::ConstructTraits;
};
-// A checked version of Member<>, verifying that only same-thread references
-// are kept in the smart pointer. Intended to be used to diagnose unclean
-// thread reference usage in release builds. It simply exposes the debug-only
-// MemberBase<> checking we already have in place for select usage to diagnose
-// per-thread issues. Only intended used temporarily while diagnosing suspected
-// problems with cross-thread references.
-template <typename T>
-class SameThreadCheckedMember : public Member<T> {
- DISALLOW_NEW();
- typedef Member<T> Parent;
-
- public:
- SameThreadCheckedMember() : Parent() { SaveCreationThreadState(); }
- SameThreadCheckedMember(std::nullptr_t) : Parent(nullptr) {
- SaveCreationThreadState();
- }
-
- SameThreadCheckedMember(T* raw) : Parent(raw) {
- SaveCreationThreadState();
- CheckPointer();
- }
-
- SameThreadCheckedMember(T& raw) : Parent(raw) {
- SaveCreationThreadState();
- CheckPointer();
- }
-
- SameThreadCheckedMember(WTF::HashTableDeletedValueType x) : Parent(x) {
- SaveCreationThreadState();
- CheckPointer();
- }
-
- SameThreadCheckedMember(const SameThreadCheckedMember& other)
- : Parent(other) {
- SaveCreationThreadState();
- }
- template <typename U>
- SameThreadCheckedMember(const SameThreadCheckedMember<U>& other)
- : Parent(other) {
- SaveCreationThreadState();
- CheckPointer();
- }
-
- template <typename U>
- SameThreadCheckedMember(const Persistent<U>& other) : Parent(other) {
- SaveCreationThreadState();
- CheckPointer();
- }
-
- template <typename U>
- SameThreadCheckedMember& operator=(const Persistent<U>& other) {
- Parent::operator=(other);
- CheckPointer();
- return *this;
- }
-
- template <typename U>
- SameThreadCheckedMember& operator=(const SameThreadCheckedMember<U>& other) {
- Parent::operator=(other);
- CheckPointer();
- return *this;
- }
-
- template <typename U>
- SameThreadCheckedMember& operator=(const WeakMember<U>& other) {
- Parent::operator=(other);
- CheckPointer();
- return *this;
- }
-
- template <typename U>
- SameThreadCheckedMember& operator=(U* other) {
- Parent::operator=(other);
- CheckPointer();
- return *this;
- }
-
- SameThreadCheckedMember& operator=(std::nullptr_t) {
- Parent::operator=(nullptr);
- return *this;
- }
-
- private:
- void CheckPointer() { pointer_verifier_.CheckPointer(this->GetRaw()); }
-
- void SaveCreationThreadState() {
- pointer_verifier_.SaveCreationThreadState(this->GetRaw());
- }
-
- MemberPointerVerifier<T, TracenessMemberConfiguration::kTraced>
- pointer_verifier_;
-};
-
// WeakMember is similar to Member in that it is used to point to other oilpan
// heap allocated objects.
// However instead of creating a strong pointer to the object, the WeakMember
@@ -560,22 +468,13 @@ struct DefaultHash<blink::UntracedMember<T>> {
};
template <typename T>
-struct DefaultHash<blink::SameThreadCheckedMember<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
struct IsTraceable<blink::Member<T>> {
STATIC_ONLY(IsTraceable);
static const bool value = true;
};
template <typename T>
-struct IsWeak<blink::WeakMember<T>> {
- STATIC_ONLY(IsWeak);
- static const bool value = true;
-};
+struct IsWeak<blink::WeakMember<T>> : std::true_type {};
template <typename T>
struct IsTraceable<blink::WeakMember<T>> {
@@ -583,23 +482,26 @@ struct IsTraceable<blink::WeakMember<T>> {
static const bool value = true;
};
-template <typename T>
-struct IsTraceable<blink::SameThreadCheckedMember<T>> {
- STATIC_ONLY(IsTraceable);
- static const bool value = true;
-};
-
template <typename T, typename Traits, typename Allocator>
class ConstructTraits<blink::Member<T>, Traits, Allocator> {
STATIC_ONLY(ConstructTraits);
public:
template <typename... Args>
+ static blink::Member<T>* Construct(void* location, Args&&... args) {
+ return new (NotNull, location)
+ blink::Member<T>(std::forward<Args>(args)...);
+ }
+
+ static void NotifyNewElement(blink::Member<T>* element) {
+ element->WriteBarrier();
+ }
+
+ template <typename... Args>
static blink::Member<T>* ConstructAndNotifyElement(void* location,
Args&&... args) {
- blink::Member<T>* object =
- new (NotNull, location) blink::Member<T>(std::forward<Args>(args)...);
- object->WriteBarrier();
+ blink::Member<T>* object = Construct(location, std::forward<Args>(args)...);
+ NotifyNewElement(object);
return object;
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h b/chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h
new file mode 100644
index 00000000000..5e881212d91
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_BLOOM_FILTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_BLOOM_FILTER_H_
+
+#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/wtf/bloom_filter.h"
+
+namespace blink {
+
+// Bloom filter for Oilpan pages. Use counting to support correct deletion. This
+// is needed for stack scanning to quickly check if an arbitrary address doesn't
+// point inside Oilpan pages. May return false positives but never false
+// negatives.
+class PageBloomFilter {
+ public:
+ void Add(Address address) {
+ filter_.Add(Hash(RoundToBlinkPageStart(address)));
+ }
+
+ void Remove(Address address) {
+ filter_.Remove(Hash(RoundToBlinkPageStart(address)));
+ }
+
+ bool MayContain(Address address) const {
+ return filter_.MayContain(Hash(RoundToBlinkPageStart(address)));
+ }
+
+ private:
+ static constexpr size_t kNumberOfEntriesLog2 = 12;
+ static constexpr size_t kNumberOfEntries = 1 << kNumberOfEntriesLog2;
+
+ static unsigned Hash(Address address) {
+ size_t value = reinterpret_cast<size_t>(address) >> kBlinkPageSizeLog2;
+ value ^= value >> kNumberOfEntriesLog2;
+ value ^= value >> (kNumberOfEntriesLog2 * 2);
+ value &= kNumberOfEntries - 1;
+ return static_cast<unsigned>(value);
+ }
+
+ WTF::BloomFilter<kNumberOfEntriesLog2> filter_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_BLOOM_FILTER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_memory.cc b/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
index 578c32277f5..c94a5866657 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
@@ -35,14 +35,14 @@ PageMemoryRegion::PageMemoryRegion(Address base,
is_large_page_(num_pages == 1),
num_pages_(num_pages),
region_tree_(region_tree) {
+ DCHECK(region_tree);
region_tree_->Add(this);
for (size_t i = 0; i < kBlinkPagesPerRegion; ++i)
in_use_[i] = false;
}
PageMemoryRegion::~PageMemoryRegion() {
- if (region_tree_)
- region_tree_->Remove(this);
+ region_tree_->Remove(this);
Release();
}
@@ -73,66 +73,27 @@ PageMemoryRegion* PageMemoryRegion::Allocate(size_t size,
}
PageMemoryRegion* RegionTree::Lookup(Address address) {
- RegionTreeNode* current = root_;
- while (current) {
- Address base = current->region_->Base();
- if (address < base) {
- current = current->left_;
- continue;
- }
- if (address >= base + current->region_->size()) {
- current = current->right_;
- continue;
- }
- DCHECK(current->region_->Contains(address));
- return current->region_;
- }
+ auto it = set_.upper_bound(address);
+ // This check also covers set_.size() > 0, since for empty vectors it is
+ // guaranteed that begin() == end().
+ if (it == set_.begin())
+ return nullptr;
+ auto* result = std::next(it, -1)->second;
+ if (address < result->Base() + result->size())
+ return result;
return nullptr;
}
void RegionTree::Add(PageMemoryRegion* region) {
DCHECK(region);
- RegionTreeNode* new_tree = new RegionTreeNode(region);
- new_tree->AddTo(&root_);
-}
-
-void RegionTreeNode::AddTo(RegionTreeNode** context) {
- Address base = region_->Base();
- for (RegionTreeNode* current = *context; current; current = *context) {
- DCHECK(!current->region_->Contains(base));
- context =
- (base < current->region_->Base()) ? &current->left_ : &current->right_;
- }
- *context = this;
+ auto result = set_.emplace(region->Base(), region);
+ DCHECK(result.second);
}
void RegionTree::Remove(PageMemoryRegion* region) {
DCHECK(region);
- DCHECK(root_);
- Address base = region->Base();
- RegionTreeNode** context = &root_;
- RegionTreeNode* current = root_;
- for (; current; current = *context) {
- if (region == current->region_)
- break;
- context =
- (base < current->region_->Base()) ? &current->left_ : &current->right_;
- }
-
- // Shutdown via detachMainThread might not have populated the region tree.
- if (!current)
- return;
-
- *context = nullptr;
- if (current->left_) {
- current->left_->AddTo(context);
- current->left_ = nullptr;
- }
- if (current->right_) {
- current->right_->AddTo(context);
- current->right_ = nullptr;
- }
- delete current;
+ auto size = set_.erase(region->Base());
+ DCHECK_EQ(1u, size);
}
PageMemory::PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable)
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_memory.h b/chromium/third_party/blink/renderer/platform/heap/page_memory.h
index 80a36e3d5a5..40884d69b93 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.h
+++ b/chromium/third_party/blink/renderer/platform/heap/page_memory.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_MEMORY_H_
#include "base/atomic_ref_count.h"
+#include "base/containers/flat_map.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_page.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -14,7 +15,6 @@
namespace blink {
class RegionTree;
-class RegionTreeNode;
class MemoryRegion {
USING_FAST_MALLOC(MemoryRegion);
@@ -101,7 +101,7 @@ class PageMemoryRegion : public MemoryRegion {
// bitmap such that thread non-interference comes for free.
bool in_use_[kBlinkPagesPerRegion];
base::AtomicRefCount num_pages_;
- RegionTree* region_tree_;
+ RegionTree* const region_tree_;
};
// A RegionTree is a simple binary search tree of PageMemoryRegions sorted
@@ -110,36 +110,14 @@ class RegionTree {
USING_FAST_MALLOC(RegionTree);
public:
- RegionTree() : root_(nullptr) {}
-
void Add(PageMemoryRegion*);
void Remove(PageMemoryRegion*);
PageMemoryRegion* Lookup(Address);
private:
- RegionTreeNode* root_;
-};
-
-class RegionTreeNode {
- USING_FAST_MALLOC(RegionTreeNode);
-
- public:
- explicit RegionTreeNode(PageMemoryRegion* region)
- : region_(region), left_(nullptr), right_(nullptr) {}
-
- ~RegionTreeNode() {
- delete left_;
- delete right_;
- }
-
- void AddTo(RegionTreeNode** context);
-
- private:
- PageMemoryRegion* region_;
- RegionTreeNode* left_;
- RegionTreeNode* right_;
-
- friend RegionTree;
+ // Using flat_map allows to improve locality to minimize cache misses and
+ // balance binary lookup.
+ base::flat_map<Address, PageMemoryRegion*> set_;
};
// Representation of the memory used for a Blink heap page.
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent.h b/chromium/third_party/blink/renderer/platform/heap/persistent.h
index a2e9ed6e644..0b098c10186 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent.h
@@ -304,7 +304,7 @@ class PersistentBase {
"T needs to be a garbage collected object");
DCHECK(!IsHashTableDeletedValue());
if (weaknessConfiguration == kWeakPersistentConfiguration) {
- visitor->RegisterWeakCallback(this, HandleWeakPersistent);
+ visitor->RegisterWeakCallback(HandleWeakPersistent, this);
} else {
#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
visitor->TraceRoot(raw_, location_.get());
@@ -384,7 +384,8 @@ class PersistentBase {
#endif
}
- static void HandleWeakPersistent(Visitor* self, void* persistent_pointer) {
+ static void HandleWeakPersistent(const WeakCallbackInfo&,
+ void* persistent_pointer) {
using Base =
PersistentBase<typename std::remove_const<T>::type,
weaknessConfiguration, crossThreadnessConfiguration>;
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
index 9e803dccfad..27c2a8b8d19 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -48,7 +48,6 @@
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -67,6 +66,7 @@
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
@@ -98,11 +98,6 @@ uint8_t ThreadState::main_thread_state_storage_[sizeof(ThreadState)];
namespace {
-// Duration of one incremental marking step. Should be short enough that it
-// doesn't cause jank even though it is scheduled as a normal task.
-constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
- base::TimeDelta::FromMilliseconds(2);
-
// Concurrent marking should stop every once in a while to flush private
// segments to v8 marking worklist. It should also stop to avoid priority
// inversion.
@@ -110,6 +105,11 @@ constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
// TODO(omerkatz): What is a good value to set here?
constexpr base::TimeDelta kConcurrentMarkingStepDuration =
base::TimeDelta::FromMilliseconds(2);
+// Number of concurrent marking tasks to use.
+//
+// TODO(omerkatz): kNumberOfMarkingTasks should be set heuristically
+// instead of a constant.
+constexpr uint8_t kNumberOfConcurrentMarkingTasks = 1u;
constexpr size_t kMaxTerminationGCLoops = 20;
@@ -133,6 +133,83 @@ class WorkerPoolTaskRunner : public base::TaskRunner {
} // namespace
+constexpr base::TimeDelta ThreadState::kDefaultIncrementalMarkingStepDuration;
+
+class ThreadState::IncrementalMarkingScheduler {
+ public:
+ explicit IncrementalMarkingScheduler(ThreadState* thread_state)
+ : thread_state_(thread_state) {}
+
+ // Starts incremental marking with further scheduled steps.
+ void Start(BlinkGC::GCReason reason) {
+ Init(reason);
+ thread_state_->IncrementalMarkingStart(reason_);
+ ScheduleTask();
+ }
+
+ // Cancels incremental marking task in case there is any pending.
+ void Cancel() { task_.Cancel(); }
+
+ private:
+ void Init(BlinkGC::GCReason reason) {
+ DCHECK(!task_.IsActive());
+ reason_ = reason;
+ next_incremental_marking_step_duration_ =
+ kDefaultIncrementalMarkingStepDuration;
+ previous_incremental_marking_time_left_ = base::TimeDelta::Max();
+ }
+
+ void ScheduleTask() {
+ // Reassigning to the task will cancel the currently scheduled one.
+ task_ = PostNonNestableCancellableTask(
+ *ThreadScheduler::Current()->V8TaskRunner(), FROM_HERE,
+ WTF::Bind(&IncrementalMarkingScheduler::Dispatch,
+ WTF::Unretained(this)));
+ }
+
+ void Dispatch() {
+ switch (thread_state_->GetGCState()) {
+ case ThreadState::kIncrementalGCScheduled:
+ thread_state_->IncrementalMarkingStart(reason_);
+ ScheduleTask();
+ break;
+ case ThreadState::kIncrementalMarkingStepScheduled:
+ thread_state_->IncrementalMarkingStep(
+ BlinkGC::kNoHeapPointersOnStack,
+ next_incremental_marking_step_duration_);
+ UpdateIncrementalMarkingStepDuration();
+ ScheduleTask();
+ break;
+ case ThreadState::kIncrementalMarkingFinalizeScheduled:
+ thread_state_->IncrementalMarkingFinalize();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateIncrementalMarkingStepDuration() {
+ const ThreadHeap& heap = thread_state_->Heap();
+ base::TimeDelta time_left =
+ heap.stats_collector()->estimated_marking_time() -
+ heap.stats_collector()->marking_time_so_far();
+ // Increase step size if estimated time left is increasing.
+ if (previous_incremental_marking_time_left_ < time_left) {
+ constexpr double ratio = 2.0;
+ next_incremental_marking_step_duration_ *= ratio;
+ }
+ previous_incremental_marking_time_left_ = time_left;
+ }
+
+ ThreadState* thread_state_;
+ BlinkGC::GCReason reason_;
+ base::TimeDelta next_incremental_marking_step_duration_ =
+ kDefaultIncrementalMarkingStepDuration;
+ base::TimeDelta previous_incremental_marking_time_left_ =
+ base::TimeDelta::Max();
+ TaskHandle task_;
+};
+
ThreadState::ThreadState()
: thread_(CurrentThread()),
persistent_region_(std::make_unique<PersistentRegion>()),
@@ -141,6 +218,8 @@ ThreadState::ThreadState()
#if defined(ADDRESS_SANITIZER)
asan_fake_stack_(__asan_get_current_fake_stack()),
#endif
+ incremental_marking_scheduler_(
+ std::make_unique<IncrementalMarkingScheduler>(this)),
marker_scheduler_(std::make_unique<CancelableTaskScheduler>(
base::MakeRefCounted<WorkerPoolTaskRunner>())),
sweeper_scheduler_(std::make_unique<CancelableTaskScheduler>(
@@ -367,8 +446,6 @@ void ThreadState::ScheduleGCIfNeeded() {
VLOG(2) << "[state:" << this << "] ScheduleGCIfNeeded";
DCHECK(CheckThread());
- UpdateIncrementalMarkingStepDuration();
-
// Allocation is allowed during sweeping, but those allocations should not
// trigger nested GCs.
if (IsGCForbidden() || SweepForbidden())
@@ -389,7 +466,7 @@ void ThreadState::ScheduleGCIfNeeded() {
blink::features::kBlinkHeapIncrementalMarkingStress)) {
VLOG(2) << "[state:" << this << "] "
<< "ScheduleGCIfNeeded: Scheduled incremental marking for testing";
- IncrementalMarkingStart(BlinkGC::GCReason::kForcedGCForTesting);
+ StartIncrementalMarking(BlinkGC::GCReason::kForcedGCForTesting);
return;
}
}
@@ -466,14 +543,17 @@ void ThreadState::PerformConcurrentSweep() {
}
}
-void ThreadState::ScheduleIncrementalMarkingStep() {
- CHECK(!IsSweepingInProgress());
- SetGCState(kIncrementalMarkingStepScheduled);
-}
-
-void ThreadState::ScheduleIncrementalMarkingFinalize() {
- CHECK(!IsSweepingInProgress());
- SetGCState(kIncrementalMarkingFinalizeScheduled);
+void ThreadState::StartIncrementalMarking(BlinkGC::GCReason reason) {
+ DCHECK(CheckThread());
+ // Schedule an incremental GC only when no GC is scheduled. Otherwise, already
+ // scheduled GCs should be prioritized.
+ if (GetGCState() != kNoGCScheduled) {
+ return;
+ }
+ CompleteSweep();
+ reason_for_scheduled_gc_ = reason;
+ SetGCState(kIncrementalGCScheduled);
+ incremental_marking_scheduler_->Start(reason);
}
void ThreadState::ScheduleIdleLazySweep() {
@@ -505,17 +585,6 @@ void ThreadState::SchedulePreciseGC() {
SetGCState(kPreciseGCScheduled);
}
-void ThreadState::ScheduleIncrementalGC(BlinkGC::GCReason reason) {
- DCHECK(CheckThread());
- // Schedule an incremental GC only when no GC is scheduled. Otherwise, already
- // scheduled GCs should be prioritized.
- if (GetGCState() == kNoGCScheduled) {
- CompleteSweep();
- reason_for_scheduled_gc_ = reason;
- SetGCState(kIncrementalGCScheduled);
- }
-}
-
namespace {
#define UNEXPECTED_GCSTATE(s) \
@@ -635,15 +704,6 @@ void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) {
BlinkGC::kConcurrentAndLazySweeping,
BlinkGC::GCReason::kPreciseGC);
break;
- case kIncrementalMarkingStepScheduled:
- IncrementalMarkingStep(stack_state);
- break;
- case kIncrementalMarkingFinalizeScheduled:
- IncrementalMarkingFinalize();
- break;
- case kIncrementalGCScheduled:
- IncrementalMarkingStart(reason_for_scheduled_gc_);
- break;
default:
break;
}
@@ -657,6 +717,7 @@ void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
ThreadHeapStatsCollector::kAtomicPauseMarkPrologue, "epoch", gc_age_,
"forced", IsForcedGC(reason));
EnterAtomicPause();
+ EnterNoAllocationScope();
EnterGCForbiddenScope();
// Compaction needs to be canceled when incremental marking ends with a
// conservative GC.
@@ -672,7 +733,15 @@ void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
// Stop concurrent markers
marker_scheduler_->CancelAndWait();
active_markers_ = 0;
+ available_concurrent_marking_task_ids_.clear();
+ }
+#if DCHECK_IS_ON()
+ MarkingWorklist* worklist = Heap().GetMarkingWorklist();
+ for (int concurrent_task = WorklistTaskId::ConcurrentThreadBase;
+ concurrent_task < worklist->num_tasks(); ++concurrent_task) {
+ DCHECK(worklist->IsLocalEmpty(concurrent_task));
}
+#endif // DCHECK_IS_ON()
DisableIncrementalMarkingBarrier();
current_gc_data_.reason = reason;
current_gc_data_.stack_state = stack_state;
@@ -687,7 +756,6 @@ void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
DCHECK(InAtomicMarkingPause());
Heap().MakeConsistentForGC();
- Heap().ClearArenaAges();
// AtomicPauseMarkPrologue is the common entry point for marking. The
// requirement is to lock from roots marking to weakness processing which is
// why the lock is taken at the end of the prologue.
@@ -1009,6 +1077,21 @@ void ThreadState::FreePersistentNode(PersistentRegion* persistent_region,
DCHECK(!static_persistents_.Contains(persistent_node));
}
+void ThreadState::RegisterPreFinalizer(void* object,
+ PreFinalizerCallback callback) {
+#if DCHECK_IS_ON()
+ DCHECK(CheckThread());
+#endif
+ DCHECK(!SweepForbidden());
+
+ HeapObjectHeader* header = HeapObjectHeader::FromInnerAddress(object);
+ DCHECK(ordered_pre_finalizers_.end() ==
+ std::find(ordered_pre_finalizers_.begin(),
+ ordered_pre_finalizers_.end(),
+ PreFinalizer{header, object, callback}));
+ ordered_pre_finalizers_.push_back(PreFinalizer{header, object, callback});
+}
+
void ThreadState::InvokePreFinalizers() {
DCHECK(CheckThread());
DCHECK(!SweepForbidden());
@@ -1016,23 +1099,22 @@ void ThreadState::InvokePreFinalizers() {
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kInvokePreFinalizers);
SweepForbiddenScope sweep_forbidden(this);
- // Pre finalizers are forbidden from allocating objects
+ // Pre finalizers are forbidden from allocating objects.
NoAllocationScope no_allocation_scope(this);
// Call the prefinalizers in the opposite order to their registration.
- //
- // LinkedHashSet does not support modification during iteration, so
- // copy items first.
- //
- // The prefinalizer callback wrapper returns |true| when its associated
- // object is unreachable garbage and the prefinalizer callback has run.
- // The registered prefinalizer entry must then be removed and deleted.
Deque<PreFinalizer> remaining_ordered_pre_finalizers;
for (auto rit = ordered_pre_finalizers_.rbegin();
rit != ordered_pre_finalizers_.rend(); ++rit) {
const PreFinalizer& pre_finalizer = *rit;
- if (!(pre_finalizer.second)(pre_finalizer.first))
+ // Check if pre-finalizer should be executed.
+ if (pre_finalizer.header->IsMarked()) {
+ // Re-queue for checking in next garbage collection.
remaining_ordered_pre_finalizers.push_front(pre_finalizer);
+ } else {
+ // Execute pre-finalizer.
+ pre_finalizer.callback(pre_finalizer.object);
+ }
}
ordered_pre_finalizers_ = std::move(remaining_ordered_pre_finalizers);
@@ -1053,11 +1135,21 @@ void ThreadState::DisableIncrementalMarkingBarrier() {
SetIncrementalMarking(false);
}
+void ThreadState::IncrementalMarkingStartForTesting() {
+ // kIncrementalGCScheduled state requires sweeping to not be in progress.
+ CompleteSweep();
+ SetGCState(kIncrementalGCScheduled);
+ IncrementalMarkingStart(BlinkGC::GCReason::kForcedGCForTesting);
+}
+
void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
+ DCHECK(!IsGCForbidden());
+ DCHECK_EQ(kIncrementalGCScheduled, GetGCState());
+
VLOG(2) << "[state:" << this << "] "
<< "IncrementalMarking: Start";
DCHECK(!IsMarkingInProgress());
- CompleteSweep();
+ // Sweeping is performed in driver functions.
DCHECK(!IsSweepingInProgress());
Heap().stats_collector()->NotifyMarkingStarted(reason);
{
@@ -1067,9 +1159,6 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
BlinkGC::ToString(reason));
AtomicPauseScope atomic_pause_scope(this);
ScriptForbiddenScope script_forbidden_scope;
- next_incremental_marking_step_duration_ =
- kDefaultIncrementalMarkingStepDuration;
- previous_incremental_marking_time_left_ = base::TimeDelta::Max();
MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack,
BlinkGC::kIncrementalAndConcurrentMarking, reason);
{
@@ -1084,15 +1173,29 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
// concurrently_marked_bytes_ without a lock.
concurrently_marked_bytes_ = 0;
current_gc_data_.visitor->FlushMarkingWorklist();
+ // Check that the marking worklist has enough private segments for all
+ // concurrent marking tasks.
+ const uint8_t max_concurrent_task_id =
+ WorklistTaskId::ConcurrentThreadBase +
+ kNumberOfConcurrentMarkingTasks;
+ DCHECK_LE(max_concurrent_task_id,
+ Heap().GetMarkingWorklist()->num_tasks());
+ // Initialize concurrent marking task ids.
+ for (uint8_t i = WorklistTaskId::ConcurrentThreadBase;
+ i < max_concurrent_task_id; ++i) {
+ available_concurrent_marking_task_ids_.push_back(i);
+ }
ScheduleConcurrentMarking();
}
- ScheduleIncrementalMarkingStep();
+ SetGCState(kIncrementalMarkingStepScheduled);
DCHECK(IsMarkingInProgress());
}
}
-void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
+void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state,
+ base::TimeDelta duration) {
DCHECK(IsMarkingInProgress());
+ DCHECK_EQ(kIncrementalMarkingStepScheduled, GetGCState());
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
@@ -1106,8 +1209,12 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
Heap().FlushNotFullyConstructedObjects();
}
- bool complete = MarkPhaseAdvanceMarking(
- base::TimeTicks::Now() + next_incremental_marking_step_duration_);
+ bool complete = true;
+ // If duration is 0, should skip incremental marking.
+ if (!duration.is_zero()) {
+ complete =
+ complete && MarkPhaseAdvanceMarking(base::TimeTicks::Now() + duration);
+ }
if (base::FeatureList::IsEnabled(
blink::features::kBlinkHeapConcurrentMarking)) {
@@ -1123,10 +1230,10 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
DCHECK(IsUnifiedGCMarkingInProgress());
SetGCState(kIncrementalMarkingStepPaused);
} else {
- ScheduleIncrementalMarkingFinalize();
+ SetGCState(kIncrementalMarkingFinalizeScheduled);
}
} else {
- ScheduleIncrementalMarkingStep();
+ SetGCState(kIncrementalMarkingStepScheduled);
}
DCHECK(IsMarkingInProgress());
}
@@ -1137,13 +1244,14 @@ bool ThreadState::ConcurrentMarkingStep() {
ScheduleConcurrentMarking();
return false;
}
- base::AutoLock lock(active_concurrent_markers_lock_);
+ base::AutoLock lock(concurrent_marker_bootstrapping_lock_);
return active_markers_ == 0;
}
void ThreadState::IncrementalMarkingFinalize() {
DCHECK(IsMarkingInProgress());
DCHECK(!IsUnifiedGCMarkingInProgress());
+ DCHECK_EQ(kIncrementalMarkingFinalizeScheduled, GetGCState());
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
@@ -1268,8 +1376,9 @@ void ThreadState::AtomicPauseMarkEpilogue(BlinkGC::MarkingType marking_type) {
ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue, "epoch", gc_age_,
"forced", IsForcedGC(current_gc_data_.reason));
MarkPhaseEpilogue(marking_type);
- LeaveAtomicPause();
LeaveGCForbiddenScope();
+ LeaveNoAllocationScope();
+ LeaveAtomicPause();
static_cast<MutexBase&>(ProcessHeap::CrossThreadPersistentMutex()).unlock();
}
@@ -1537,7 +1646,6 @@ void ThreadState::MarkPhaseVisitRoots() {
if (current_gc_data_.stack_state == BlinkGC::kHeapPointersOnStack) {
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
- AddressCache::EnabledScope address_cache_scope(Heap().address_cache());
PushRegistersAndVisitStack();
}
}
@@ -1571,6 +1679,8 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
}
Heap().DestroyMarkingWorklists(current_gc_data_.stack_state);
+ incremental_marking_scheduler_->Cancel();
+
size_t marked_bytes = concurrently_marked_bytes_;
current_gc_data_.visitor->FlushCompactionWorklists();
@@ -1615,57 +1725,34 @@ void ThreadState::EnableCompactionForNextGCForTesting() {
Heap().Compaction()->EnableCompactionForNextGCForTesting();
}
-void ThreadState::UpdateIncrementalMarkingStepDuration() {
- if (!IsIncrementalMarking())
- return;
- base::TimeDelta time_left =
- Heap().stats_collector()->estimated_marking_time() -
- Heap().stats_collector()->marking_time_so_far();
- // Increase step size if estimated time left is increasing.
- if (previous_incremental_marking_time_left_ < time_left) {
- constexpr double ratio = 2.0;
- next_incremental_marking_step_duration_ *= ratio;
- }
- previous_incremental_marking_time_left_ = time_left;
-}
-
void ThreadState::ScheduleConcurrentMarking() {
- base::AutoLock lock(active_concurrent_markers_lock_);
-
- if (active_markers_ > 0) {
- // Concurrent markers are already running, should not run them again
- return;
- }
+ base::AutoLock lock(concurrent_marker_bootstrapping_lock_);
DCHECK(base::FeatureList::IsEnabled(
blink::features::kBlinkHeapConcurrentMarking));
- // Number of concurrent marking tasks to start. The check below verifies
- // that the marking worklist has enough private segments for all tasks.
- //
- // TODO(omerkatz): kNumberOfMarkingTasks should be set heuristically instead
- // of a constant.
- static constexpr int kNumberOfConcurrentMarkingTasks = 1u;
- DCHECK_LT(kNumberOfConcurrentMarkingTasks,
- Heap().GetMarkingWorklist()->num_tasks());
+ for (uint8_t i = active_markers_; i < kNumberOfConcurrentMarkingTasks; ++i) {
+ marker_scheduler_->ScheduleTask(WTF::CrossThreadBindOnce(
+ &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this)));
+ }
active_markers_ = kNumberOfConcurrentMarkingTasks;
-
- for (int i = 0; i < kNumberOfConcurrentMarkingTasks; ++i) {
- marker_scheduler_->ScheduleTask(
- WTF::CrossThreadBindOnce(&ThreadState::PerformConcurrentMark,
- WTF::CrossThreadUnretained(this), i));
- }
}
-void ThreadState::PerformConcurrentMark(int concurrent_marker_id) {
+void ThreadState::PerformConcurrentMark() {
VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] "
<< "ConcurrentMark";
ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kConcurrentMark);
- const int task_id =
- WorklistTaskId::ConcurrentThreadBase + concurrent_marker_id;
+ uint8_t task_id;
+ {
+ base::AutoLock lock(concurrent_marker_bootstrapping_lock_);
+ DCHECK(!available_concurrent_marking_task_ids_.IsEmpty());
+ task_id = available_concurrent_marking_task_ids_.back();
+ available_concurrent_marking_task_ids_.pop_back();
+ }
+
std::unique_ptr<ConcurrentMarkingVisitor> concurrent_visitor =
IsUnifiedGCMarkingInProgress()
? std::make_unique<ConcurrentUnifiedHeapMarkingVisitor>(
@@ -1681,10 +1768,11 @@ void ThreadState::PerformConcurrentMark(int concurrent_marker_id) {
concurrent_visitor->FlushWorklists();
{
- base::AutoLock lock(active_concurrent_markers_lock_);
+ base::AutoLock lock(concurrent_marker_bootstrapping_lock_);
// When marking is done, flush visitor worklists and decrement number of
// active markers so we know how many markers are left
concurrently_marked_bytes_ += concurrent_visitor->marked_bytes();
+ available_concurrent_marking_task_ids_.push_back(task_id);
if (finished) {
--active_markers_;
return;
@@ -1693,8 +1781,7 @@ void ThreadState::PerformConcurrentMark(int concurrent_marker_id) {
// Reschedule this marker
marker_scheduler_->ScheduleTask(WTF::CrossThreadBindOnce(
- &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this),
- concurrent_marker_id));
+ &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this)));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.h b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
index 7fbff6794bc..42b55d95df5 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace v8 {
class EmbedderGraph;
@@ -61,6 +62,7 @@ class IncrementalMarkingScope;
} // namespace incremental_marking_test
class CancelableTaskScheduler;
+class HeapObjectHeader;
class MarkingVisitor;
class PersistentNode;
class PersistentRegion;
@@ -92,17 +94,13 @@ class Visitor;
// Member<Bar> bar_;
// };
#define USING_PRE_FINALIZER(Class, preFinalizer) \
- public: \
- static bool InvokePreFinalizer(void* object) { \
- Class* self = reinterpret_cast<Class*>(object); \
- if (ThreadHeap::IsHeapObjectAlive(self)) \
- return false; \
- self->Class::preFinalizer(); \
- return true; \
+ private: \
+ static void PreFinalizerDispatch(void* object) { \
+ reinterpret_cast<Class*>(object)->Class::preFinalizer(); \
} \
\
- private: \
- ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this}; \
+ friend class ThreadState::PreFinalizerRegistration<Class>; \
+ ThreadState::PreFinalizerRegistration<Class> prefinalizer_dummy_{this}; \
using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
class PLATFORM_EXPORT BlinkGCObserver {
@@ -132,24 +130,16 @@ class PLATFORM_EXPORT ThreadState final {
// Register the pre-finalizer for the |self| object. The class T be using
// USING_PRE_FINALIZER() macro.
template <typename T>
- class PrefinalizerRegistration final {
+ class PreFinalizerRegistration final {
DISALLOW_NEW();
public:
- PrefinalizerRegistration(T* self) {
- static_assert(sizeof(&T::InvokePreFinalizer) > 0,
+ PreFinalizerRegistration(T* self) {
+ static_assert(sizeof(&T::PreFinalizerDispatch) > 0,
"USING_PRE_FINALIZER(T) must be defined.");
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-#if DCHECK_IS_ON()
- DCHECK(state->CheckThread());
-#endif
- DCHECK(!state->SweepForbidden());
- DCHECK(std::find(state->ordered_pre_finalizers_.begin(),
- state->ordered_pre_finalizers_.end(),
- PreFinalizer(self, T::InvokePreFinalizer)) ==
- state->ordered_pre_finalizers_.end());
- state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer);
+ state->RegisterPreFinalizer(self, T::PreFinalizerDispatch);
}
};
@@ -253,7 +243,6 @@ class PLATFORM_EXPORT ThreadState final {
void PerformConcurrentSweep();
void SchedulePreciseGC();
- void ScheduleIncrementalGC(BlinkGC::GCReason);
void ScheduleForcedGCForTesting();
void ScheduleGCIfNeeded();
void WillStartV8GC(BlinkGC::V8GCType);
@@ -261,6 +250,10 @@ class PLATFORM_EXPORT ThreadState final {
GCState GetGCState() const { return gc_state_; }
void SetGCPhase(GCPhase);
+ // Immediately starts incremental marking and schedules further steps if
+ // necessary.
+ void StartIncrementalMarking(BlinkGC::GCReason);
+
// Returns true if marking is in progress.
bool IsMarkingInProgress() const { return gc_phase_ == GCPhase::kMarking; }
@@ -286,9 +279,6 @@ class PLATFORM_EXPORT ThreadState final {
void EnableCompactionForNextGCForTesting();
- void IncrementalMarkingStart(BlinkGC::GCReason);
- void IncrementalMarkingStep(BlinkGC::StackState);
- void IncrementalMarkingFinalize();
bool FinishIncrementalMarkingIfRunning(BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::SweepingType,
@@ -297,15 +287,7 @@ class PLATFORM_EXPORT ThreadState final {
void EnableIncrementalMarkingBarrier();
void DisableIncrementalMarkingBarrier();
- // Returns true if concurrent marking is finished (i.e. all current threads
- // terminated and the worklist is empty)
- bool ConcurrentMarkingStep();
- void ScheduleConcurrentMarking();
- void PerformConcurrentMark(int);
-
void CompleteSweep();
- void NotifySweepDone();
- void PostSweep();
// Returns whether it is currently allowed to allocate an object. Mainly used
// for sanity checks asserts.
@@ -382,6 +364,24 @@ class PLATFORM_EXPORT ThreadState final {
bool IsVerifyMarkingEnabled() const;
private:
+ class IncrementalMarkingScheduler;
+
+ using PreFinalizerCallback = void (*)(void*);
+ struct PreFinalizer {
+ HeapObjectHeader* header;
+ void* object;
+ PreFinalizerCallback callback;
+
+ bool operator==(const PreFinalizer& other) const {
+ return object == other.object && callback == other.callback;
+ }
+ };
+
+ // Duration of one incremental marking step. Should be short enough that it
+ // doesn't cause jank even though it is scheduled as a normal task.
+ static constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
+ base::TimeDelta::FromMilliseconds(2);
+
// Stores whether some ThreadState is currently in incremental marking.
static AtomicEntryFlag incremental_marking_flag_;
@@ -482,21 +482,38 @@ class PLATFORM_EXPORT ThreadState final {
// Visit all DOM wrappers allocatd on this thread.
void VisitDOMWrappers(Visitor*);
+ // Incremental marking implementation functions.
+ void IncrementalMarkingStartForTesting();
+ void IncrementalMarkingStart(BlinkGC::GCReason);
+ // Incremental marking step advance marking on the mutator thread. This method
+ // also reschedules concurrent marking tasks if needed. The duration parameter
+ // applies only to incremental marking steps on the mutator thread.
+ void IncrementalMarkingStep(
+ BlinkGC::StackState,
+ base::TimeDelta duration = kDefaultIncrementalMarkingStepDuration);
+ void IncrementalMarkingFinalize();
+
+ // Returns true if concurrent marking is finished (i.e. all current threads
+ // terminated and the worklist is empty)
+ bool ConcurrentMarkingStep();
+ void ScheduleConcurrentMarking();
+ void PerformConcurrentMark();
+
// Schedule helpers.
- void ScheduleIncrementalMarkingStep();
- void ScheduleIncrementalMarkingFinalize();
void ScheduleIdleLazySweep();
void ScheduleConcurrentAndLazySweep();
+ void NotifySweepDone();
+ void PostSweep();
+
// See |DetachCurrentThread|.
void RunTerminationGC();
void RunScheduledGC(BlinkGC::StackState);
- void UpdateIncrementalMarkingStepDuration();
-
void SynchronizeAndFinishConcurrentSweeping();
+ void RegisterPreFinalizer(void*, PreFinalizerCallback);
void InvokePreFinalizers();
// Adds the given observer to the ThreadState's observer list. This doesn't
@@ -540,17 +557,11 @@ class PLATFORM_EXPORT ThreadState final {
size_t gc_forbidden_count_ = 0;
size_t static_persistent_registration_disabled_count_ = 0;
- base::TimeDelta next_incremental_marking_step_duration_;
- base::TimeDelta previous_incremental_marking_time_left_;
-
GCState gc_state_ = GCState::kNoGCScheduled;
GCPhase gc_phase_ = GCPhase::kNone;
BlinkGC::GCReason reason_for_scheduled_gc_ =
BlinkGC::GCReason::kForcedGCForTesting;
- using PreFinalizerCallback = bool (*)(void*);
- using PreFinalizer = std::pair<void*, PreFinalizerCallback>;
-
// Pre-finalizers are called in the reverse order in which they are
// registered by the constructors (including constructors of Mixin objects)
// for an object, by processing the ordered_pre_finalizers_ back-to-front.
@@ -583,9 +594,12 @@ class PLATFORM_EXPORT ThreadState final {
};
GCData current_gc_data_;
+ std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_;
+
std::unique_ptr<CancelableTaskScheduler> marker_scheduler_;
+ Vector<uint8_t> available_concurrent_marking_task_ids_;
uint8_t active_markers_ = 0;
- base::Lock active_concurrent_markers_lock_;
+ base::Lock concurrent_marker_bootstrapping_lock_;
size_t concurrently_marked_bytes_ = 0;
std::unique_ptr<CancelableTaskScheduler> sweeper_scheduler_;
@@ -595,8 +609,9 @@ class PLATFORM_EXPORT ThreadState final {
friend class IncrementalMarkingTestDriver;
friend class HeapAllocator;
template <typename T>
- friend class PrefinalizerRegistration;
+ friend class PreFinalizerRegistration;
friend class TestGCScope;
+ friend class TestSupportingGC;
friend class ThreadStateSchedulingTest;
friend class UnifiedHeapController;
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc b/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc
index c8958ad6bd6..2b2bf3606eb 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc
@@ -2,15 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
+namespace {
+
+void RunLoop() {
+ base::RunLoop rl;
+ // Push quit task.
+ ThreadScheduler::Current()->V8TaskRunner()->PostNonNestableTask(
+ FROM_HERE, WTF::Bind(rl.QuitWhenIdleClosure()));
+ rl.Run();
+}
+
+} // namespace
+
class ThreadStateSchedulingTest : public TestSupportingGC {
public:
void SetUp() override {
@@ -26,13 +41,8 @@ class ThreadStateSchedulingTest : public TestSupportingGC {
EXPECT_FALSE(state_->IsSweepingInProgress());
}
- void StartIncrementalMarking() {
- EXPECT_EQ(ThreadState::kNoGCScheduled, state_->GetGCState());
- state_->ScheduleIncrementalGC(BlinkGC::GCReason::kForcedGCForTesting);
- state_->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack);
- EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
- state_->GetGCState());
- EXPECT_TRUE(state_->IsMarkingInProgress());
+ BlinkGC::GCReason LastReason() const {
+ return state_->reason_for_scheduled_gc_;
}
void StartLazySweepingForPreciseGC() {
@@ -58,21 +68,17 @@ class ThreadStateSchedulingTest : public TestSupportingGC {
int initial_gc_age_;
};
-TEST_F(ThreadStateSchedulingTest, ScheduleIncrementalV8FollowupGCAgain) {
+TEST_F(ThreadStateSchedulingTest, RunIncrementalGCForTesting) {
ThreadStateSchedulingTest* test = this;
EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
-
- // Calling ScheduleIncrementalV8FollowupGC() while one is already scheduled
- // will do nothing.
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
+ test->state()->StartIncrementalMarking(
+ BlinkGC::GCReason::kForcedGCForTesting);
+ EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
+ test->state()->GetGCState());
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
- EXPECT_EQ(0, test->GCCount());
+ RunLoop();
+ EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
}
TEST_F(ThreadStateSchedulingTest, SchedulePreciseGCWhileLazySweeping) {
@@ -87,27 +93,13 @@ TEST_F(ThreadStateSchedulingTest, SchedulePreciseGCWhileLazySweeping) {
EXPECT_EQ(ThreadState::kPreciseGCScheduled, test->state()->GetGCState());
}
-TEST_F(ThreadStateSchedulingTest,
- ScheduleIncrementalV8FollowupGCWhileLazySweeping) {
- ThreadStateSchedulingTest* test = this;
-
- test->StartLazySweepingForPreciseGC();
-
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
-
- // Scheduling a IncrementalV8FollowupGC should finish lazy sweeping.
- EXPECT_FALSE(test->state()->IsSweepingInProgress());
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
-}
-
TEST_F(ThreadStateSchedulingTest, SchedulePreciseGCWhileIncrementalMarking) {
ThreadStateSchedulingTest* test = this;
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
blink::features::kBlinkHeapIncrementalMarking);
-
- test->StartIncrementalMarking();
+ test->state()->StartIncrementalMarking(
+ BlinkGC::GCReason::kForcedGCForTesting);
test->state()->SchedulePreciseGC();
// Scheduling a precise GC should cancel incremental marking tasks.
EXPECT_EQ(ThreadState::kPreciseGCScheduled, test->state()->GetGCState());
@@ -122,54 +114,10 @@ TEST_F(ThreadStateSchedulingTest, SchedulePreciseGCWhileIncrementalMarking) {
EXPECT_EQ(0, test->GCCount());
test->state()->CompleteSweep();
EXPECT_EQ(1, test->GCCount());
-}
-
-TEST_F(ThreadStateSchedulingTest,
- ScheduleIncrementalV8FollowupGCWhileIncrementalMarking) {
- ThreadStateSchedulingTest* test = this;
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- blink::features::kBlinkHeapIncrementalMarking);
-
- test->StartIncrementalMarking();
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
- // Scheduling another incremental GC should not cancel incremental marking
- // tasks.
- EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
- test->state()->GetGCState());
-}
-
-TEST_F(ThreadStateSchedulingTest,
- ScheduleIncrementalV8FollowupGCWhileGCForbidden) {
- ThreadStateSchedulingTest* test = this;
-
- EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
-
- ThreadState::GCForbiddenScope gc_forbidden_scope(test->state());
- test->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack);
- // Starting an IncrementalV8FollowupGC while GC is forbidden should do
- // nothing.
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
- EXPECT_EQ(0, GCCount());
-}
-
-TEST_F(ThreadStateSchedulingTest, RunIncrementalV8FollowupGC) {
- ThreadStateSchedulingTest* test = this;
-
- EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
- test->state()->ScheduleIncrementalGC(
- BlinkGC::GCReason::kIncrementalV8FollowupGC);
- EXPECT_EQ(ThreadState::kIncrementalGCScheduled, test->state()->GetGCState());
-
- test->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack);
-
- EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
- test->state()->GetGCState());
+ // Check that incremental GC hasn't been run.
+ RunLoop();
+ EXPECT_EQ(1, test->GCCount());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h b/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
index 8596d3c887d..3c5579ff1f7 100644
--- a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
@@ -16,9 +16,6 @@
namespace blink {
-template <typename T>
-class SameThreadCheckedMember;
-
// ThreadAffinity indicates which threads objects can be used on. We
// distinguish between objects that can be used on the main thread
// only and objects that can be used on any thread.
@@ -84,12 +81,6 @@ struct ThreadingTrait<Member<T>> {
};
template <typename T>
-struct ThreadingTrait<SameThreadCheckedMember<T>> {
- STATIC_ONLY(ThreadingTrait);
- static const ThreadAffinity kAffinity = ThreadingTrait<T>::Affinity;
-};
-
-template <typename T>
struct ThreadingTrait<WeakMember<T>> {
STATIC_ONLY(ThreadingTrait);
static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
diff --git a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
index cfbd628a60c..583aa7f78d3 100644
--- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
@@ -24,74 +24,59 @@ namespace blink {
template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator;
template <typename T>
-class TraceTrait;
+struct TraceTrait;
template <typename T>
class WeakMember;
template <typename T, bool = NeedsAdjustPointer<T>::value>
-class AdjustPointerTrait;
+struct AdjustPointerTrait;
template <typename T>
-class AdjustPointerTrait<T, false> {
+struct AdjustPointerTrait<T, false> {
STATIC_ONLY(AdjustPointerTrait);
- public:
static TraceDescriptor GetTraceDescriptor(void* self) {
return {self, TraceTrait<T>::Trace};
}
static HeapObjectHeader* GetHeapObjectHeader(void* self) {
-#if DCHECK_IS_ON()
- HeapObjectHeader::CheckFromPayload(self);
-#endif
return HeapObjectHeader::FromPayload(self);
}
};
template <typename T>
-class AdjustPointerTrait<T, true> {
+struct AdjustPointerTrait<T, true> {
STATIC_ONLY(AdjustPointerTrait);
- public:
- static TraceDescriptor GetTraceDescriptor(const T* self) {
- DCHECK(self);
- return self->GetTraceDescriptor();
+ static TraceDescriptor GetTraceDescriptor(void* self) {
+ return static_cast<T*>(self)->GetTraceDescriptor();
}
- static HeapObjectHeader* GetHeapObjectHeader(const T* self) {
- DCHECK(self);
- return self->GetHeapObjectHeader();
+ static HeapObjectHeader* GetHeapObjectHeader(void* self) {
+ return static_cast<T*>(self)->GetHeapObjectHeader();
}
};
-template <typename T, bool isTraceable>
-struct TraceIfEnabled;
+template <typename T, bool = WTF::IsTraceable<T>::value>
+struct TraceIfNeeded;
template <typename T>
-struct TraceIfEnabled<T, false> {
- STATIC_ONLY(TraceIfEnabled);
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher, T&) {
- static_assert(!WTF::IsTraceable<T>::value, "T should not be traced");
- }
+struct TraceIfNeeded<T, false> {
+ STATIC_ONLY(TraceIfNeeded);
+ static void Trace(blink::Visitor*, T&) {}
};
template <typename T>
-struct TraceIfEnabled<T, true> {
- STATIC_ONLY(TraceIfEnabled);
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher visitor, T& t) {
- static_assert(WTF::IsTraceable<T>::value, "T should not be traced");
- visitor->Trace(t);
- }
+struct TraceIfNeeded<T, true> {
+ STATIC_ONLY(TraceIfNeeded);
+ static void Trace(blink::Visitor* visitor, T& t) { visitor->Trace(t); }
};
template <WTF::WeakHandlingFlag weakness,
typename T,
typename Traits,
- bool isTraceableInCollection =
- WTF::IsTraceableInCollectionTrait<Traits>::value,
- WTF::WeakHandlingFlag traitWeakHandling = Traits::kWeakHandlingFlag>
+ bool = WTF::IsTraceableInCollectionTrait<Traits>::value,
+ WTF::WeakHandlingFlag = WTF::WeakHandlingTrait<T>::value>
struct TraceCollectionIfEnabled;
template <WTF::WeakHandlingFlag weakness, typename T, typename Traits>
@@ -104,8 +89,7 @@ struct TraceCollectionIfEnabled<weakness,
static bool IsAlive(T&) { return true; }
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher, T&) {
+ static bool Trace(blink::Visitor*, void*) {
static_assert(!WTF::IsTraceableInCollectionTrait<Traits>::value,
"T should not be traced");
return false;
@@ -119,18 +103,18 @@ struct TraceCollectionIfEnabled<WTF::kNoWeakHandling,
false,
WTF::kWeakHandling> {
STATIC_ONLY(TraceCollectionIfEnabled);
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
+
+ static bool Trace(blink::Visitor* visitor, void* t) {
return WTF::TraceInCollectionTrait<WTF::kNoWeakHandling, T, Traits>::Trace(
- visitor, t);
+ visitor, *reinterpret_cast<T*>(t));
}
};
template <WTF::WeakHandlingFlag weakness,
typename T,
typename Traits,
- bool isTraceableInCollection,
- WTF::WeakHandlingFlag traitWeakHandling>
+ bool,
+ WTF::WeakHandlingFlag>
struct TraceCollectionIfEnabled {
STATIC_ONLY(TraceCollectionIfEnabled);
@@ -138,12 +122,12 @@ struct TraceCollectionIfEnabled {
return WTF::TraceInCollectionTrait<weakness, T, Traits>::IsAlive(traceable);
}
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
+ static bool Trace(blink::Visitor* visitor, void* t) {
static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
weakness == WTF::kWeakHandling,
"Traits should be traced");
- return WTF::TraceInCollectionTrait<weakness, T, Traits>::Trace(visitor, t);
+ return WTF::TraceInCollectionTrait<weakness, T, Traits>::Trace(
+ visitor, *reinterpret_cast<T*>(t));
}
};
@@ -160,7 +144,7 @@ struct TraceCollectionIfEnabled {
// to the start of the object in the Blink garbage-collected heap. In
// that case the pointer has to be adjusted before marking.
template <typename T>
-class TraceTrait {
+struct TraceTrait {
STATIC_ONLY(TraceTrait);
public:
@@ -168,6 +152,10 @@ class TraceTrait {
return AdjustPointerTrait<T>::GetTraceDescriptor(static_cast<T*>(self));
}
+ static TraceDescriptor GetWeakTraceDescriptor(void* self) {
+ return {self, nullptr};
+ }
+
static HeapObjectHeader* GetHeapObjectHeader(void* self) {
return AdjustPointerTrait<T>::GetHeapObjectHeader(static_cast<T*>(self));
}
@@ -176,7 +164,7 @@ class TraceTrait {
};
template <typename T>
-class TraceTrait<const T> : public TraceTrait<T> {};
+struct TraceTrait<const T> : public TraceTrait<T> {};
template <typename T>
void TraceTrait<T>::Trace(Visitor* visitor, void* self) {
@@ -189,12 +177,12 @@ struct TraceTrait<HeapVectorBacking<T, Traits>> {
STATIC_ONLY(TraceTrait);
using Backing = HeapVectorBacking<T, Traits>;
+ public:
static TraceDescriptor GetTraceDescriptor(void* self) {
return {self, TraceTrait<Backing>::Trace};
}
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher visitor, void* self) {
+ static void Trace(blink::Visitor* visitor, void* self) {
static_assert(!WTF::IsWeak<T>::value,
"Weakness is not supported in HeapVector and HeapDeque");
if (WTF::IsTraceableInCollectionTrait<Traits>::value) {
@@ -206,45 +194,85 @@ struct TraceTrait<HeapVectorBacking<T, Traits>> {
};
// The trace trait for the heap hashtable backing is used when we find a
-// direct pointer to the backing from the conservative stack scanner. This
+// direct pointer to the backing from the conservative stack scanner. This
// normally indicates that there is an ongoing iteration over the table, and so
-// we disable weak processing of table entries. When the backing is found
+// we disable weak processing of table entries. When the backing is found
// through the owning hash table we mark differently, in order to do weak
// processing.
template <typename Table>
struct TraceTrait<HeapHashTableBacking<Table>> {
STATIC_ONLY(TraceTrait);
using Backing = HeapHashTableBacking<Table>;
+ using ValueType = typename Table::ValueTraits::TraitType;
using Traits = typename Table::ValueTraits;
+ public:
static TraceDescriptor GetTraceDescriptor(void* self) {
- return {self, TraceTrait<Backing>::Trace};
+ return {self, Trace<WTF::kNoWeakHandling>};
}
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher visitor, void* self) {
- if (WTF::IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kWeakHandlingFlag == WTF::kWeakHandling) {
- WTF::TraceInCollectionTrait<WTF::kNoWeakHandling, Backing, void>::Trace(
- visitor, self);
- }
+ static TraceDescriptor GetWeakTraceDescriptor(void* self) {
+ return GetWeakTraceDescriptorImpl<ValueType>::GetWeakTraceDescriptor(self);
}
+
+ template <WTF::WeakHandlingFlag WeakHandling = WTF::kNoWeakHandling>
+ static void Trace(Visitor* visitor, void* self) {
+ static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
+ WTF::IsWeak<ValueType>::value,
+ "T should not be traced");
+ WTF::TraceInCollectionTrait<WeakHandling, Backing, void>::Trace(visitor,
+ self);
+ }
+
+ private:
+ template <typename ValueType>
+ struct GetWeakTraceDescriptorImpl {
+ static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
+ return {backing, nullptr};
+ }
+ };
+
+ template <typename K, typename V>
+ struct GetWeakTraceDescriptorImpl<WTF::KeyValuePair<K, V>> {
+ static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
+ return GetWeakTraceDescriptorKVPImpl<K, V>::GetWeakTraceDescriptor(
+ backing);
+ }
+
+ template <typename KeyType,
+ typename ValueType,
+ bool ephemeron_semantics = (WTF::IsWeak<KeyType>::value &&
+ !WTF::IsWeak<ValueType>::value &&
+ WTF::IsTraceable<ValueType>::value) ||
+ (WTF::IsWeak<ValueType>::value &&
+ !WTF::IsWeak<KeyType>::value &&
+ WTF::IsTraceable<KeyType>::value)>
+ struct GetWeakTraceDescriptorKVPImpl {
+ static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
+ return {backing, nullptr};
+ }
+ };
+
+ template <typename KeyType, typename ValueType>
+ struct GetWeakTraceDescriptorKVPImpl<KeyType, ValueType, true> {
+ static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
+ return {backing, Trace<WTF::kWeakHandling>};
+ }
+ };
+ };
};
// This trace trait for std::pair will null weak members if their referent is
// collected. If you have a collection that contain weakness it does not remove
// entries from the collection that contain nulled weak members.
template <typename T, typename U>
-class TraceTrait<std::pair<T, U>> {
+struct TraceTrait<std::pair<T, U>> {
STATIC_ONLY(TraceTrait);
public:
- static const bool kFirstIsTraceable = WTF::IsTraceable<T>::value;
- static const bool kSecondIsTraceable = WTF::IsTraceable<U>::value;
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher visitor, std::pair<T, U>* pair) {
- TraceIfEnabled<T, kFirstIsTraceable>::Trace(visitor, pair->first);
- TraceIfEnabled<U, kSecondIsTraceable>::Trace(visitor, pair->second);
+ static void Trace(blink::Visitor* visitor, std::pair<T, U>* pair) {
+ TraceIfNeeded<T>::Trace(visitor, pair->first);
+ TraceIfNeeded<U>::Trace(visitor, pair->second);
}
};
@@ -253,55 +281,59 @@ class TraceTrait<std::pair<T, U>> {
// garbage-collected containers such as HeapVector are allowed and need to be
// traced.
template <typename T>
-class TraceTrait<base::Optional<T>> {
+struct TraceTrait<base::Optional<T>> {
STATIC_ONLY(TraceTrait);
public:
- template <typename VisitorDispatcher>
- static void Trace(VisitorDispatcher visitor, base::Optional<T>* optional) {
+ static void Trace(blink::Visitor* visitor, base::Optional<T>* optional) {
if (*optional != base::nullopt) {
- TraceIfEnabled<T, WTF::IsTraceable<T>::value>::Trace(visitor,
- optional->value());
+ TraceIfNeeded<T>::Trace(visitor, optional->value());
}
}
};
-template <typename T>
-struct TraceIfNeeded : public TraceIfEnabled<T, WTF::IsTraceable<T>::value> {
- STATIC_ONLY(TraceIfNeeded);
+// Reorders parameters for use in blink::Visitor::VisitEphemeronKeyValuePair.
+template <typename _KeyType,
+ typename _ValueType,
+ typename _KeyTraits,
+ typename _ValueTraits,
+ bool = WTF::IsWeak<_ValueType>::value>
+struct EphemeronKeyValuePair {
+ using KeyType = _KeyType;
+ using ValueType = _ValueType;
+ using KeyTraits = _KeyTraits;
+ using ValueTraits = _ValueTraits;
+
+ EphemeronKeyValuePair(KeyType* k, ValueType* v) : key(k), value(v) {}
+ KeyType* key;
+ ValueType* value;
+};
+
+template <typename _KeyType,
+ typename _ValueType,
+ typename _KeyTraits,
+ typename _ValueTraits>
+struct EphemeronKeyValuePair<_KeyType,
+ _ValueType,
+ _KeyTraits,
+ _ValueTraits,
+ true> : EphemeronKeyValuePair<_ValueType,
+ _KeyType,
+ _ValueTraits,
+ _KeyTraits,
+ false> {
+ EphemeronKeyValuePair(_KeyType* k, _ValueType* v)
+ : EphemeronKeyValuePair<_ValueType,
+ _KeyType,
+ _ValueTraits,
+ _KeyTraits,
+ false>(v, k) {}
};
} // namespace blink
namespace WTF {
-// Helper used for tracing without weak handling in collections that support
-// weak handling. It dispatches to |TraceInCollection| if the provided trait
-// supports weak handling, and to |Trace| otherwise.
-template <typename T,
- typename Traits,
- WTF::WeakHandlingFlag traitsWeakness = Traits::kWeakHandlingFlag>
-struct TraceNoWeakHandlingInCollectionHelper;
-
-template <typename T, typename Traits>
-struct TraceNoWeakHandlingInCollectionHelper<T, Traits, kWeakHandling> {
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
- return Traits::TraceInCollection(visitor, t, kNoWeakHandling);
- }
-};
-
-template <typename T, typename Traits>
-struct TraceNoWeakHandlingInCollectionHelper<T, Traits, kNoWeakHandling> {
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
- static_assert(IsTraceableInCollectionTrait<Traits>::value,
- "T should not be traced");
- visitor->Trace(t);
- return false;
- }
-};
-
// Catch-all for types that have a way to trace that don't have special
// handling for weakness in collections. This means that if this type
// contains WeakMember fields, they will simply be zeroed, but the entry
@@ -312,20 +344,36 @@ template <typename T, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling, T, Traits> {
static bool IsAlive(T& t) { return true; }
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
- return TraceNoWeakHandlingInCollectionHelper<T, Traits>::Trace(visitor, t);
+ static bool Trace(blink::Visitor* visitor, T& t) {
+ static_assert(IsTraceableInCollectionTrait<Traits>::value,
+ "T should not be traced");
+ visitor->Trace(t);
+ return false;
+ }
+};
+
+template <typename T, typename Traits>
+struct TraceInCollectionTrait<kNoWeakHandling, blink::WeakMember<T>, Traits> {
+ static bool Trace(blink::Visitor* visitor, blink::WeakMember<T>& t) {
+ // Extract raw pointer to avoid using the WeakMember<> overload in Visitor.
+ visitor->Trace(t.Get());
+ return false;
}
};
// Catch-all for types that have HashTrait support for tracing with weakness.
+// Empty to enforce specialization.
template <typename T, typename Traits>
-struct TraceInCollectionTrait<kWeakHandling, T, Traits> {
- static bool IsAlive(T& value) { return Traits::IsAlive(value); }
+struct TraceInCollectionTrait<kWeakHandling, T, Traits> {};
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, T& t) {
- return Traits::TraceInCollection(visitor, t, kWeakHandling);
+template <typename T, typename Traits>
+struct TraceInCollectionTrait<kWeakHandling, blink::WeakMember<T>, Traits> {
+ static bool IsAlive(blink::WeakMember<T>& value) {
+ return blink::ThreadHeap::IsHeapObjectAlive(value);
+ }
+
+ static bool Trace(blink::Visitor* visitor, blink::WeakMember<T>& value) {
+ return !blink::ThreadHeap::IsHeapObjectAlive(value);
}
};
@@ -335,8 +383,7 @@ template <typename T, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling,
blink::HeapVectorBacking<T, Traits>,
void> {
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, void* self) {
+ static bool Trace(blink::Visitor* visitor, void* self) {
// HeapVectorBacking does not know the exact size of the vector
// and just knows the capacity of the vector. Due to the constraint,
// HeapVectorBacking can support only the following objects:
@@ -380,13 +427,13 @@ struct TraceInCollectionTrait<kNoWeakHandling,
for (unsigned i = 0; i < length; ++i) {
char* element = pointer + i * sizeof(T);
if (blink::VTableInitialized(element))
- blink::TraceIfEnabled<
+ blink::TraceIfNeeded<
T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
array[i]);
}
} else {
for (size_t i = 0; i < length; ++i)
- blink::TraceIfEnabled<
+ blink::TraceIfNeeded<
T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
array[i]);
}
@@ -394,19 +441,18 @@ struct TraceInCollectionTrait<kNoWeakHandling,
}
};
-// This trace method is used only for on-stack HeapHashTables found in
-// conservative scanning. On-heap HeapHashTables are traced by HashTable::trace.
-template <typename Table>
-struct TraceInCollectionTrait<kNoWeakHandling,
- blink::HeapHashTableBacking<Table>,
- void> {
+// This trace method is for tracing a HashTableBacking either through regular
+// tracing (via the relevant TraceTraits) or when finding a HashTableBacking
+// through conservative stack scanning (which will treat all references in the
+// backing strongly).
+template <WTF::WeakHandlingFlag WeakHandling, typename Table>
+struct TraceHashTableBackingInCollectionTrait {
using Value = typename Table::ValueType;
using Traits = typename Table::ValueTraits;
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, void* self) {
+ static bool Trace(blink::Visitor* visitor, void* self) {
static_assert(IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kWeakHandlingFlag == kWeakHandling,
+ WTF::IsWeak<Value>::value,
"Table should not be traced");
Value* array = reinterpret_cast<Value*>(self);
blink::HeapObjectHeader* header =
@@ -418,14 +464,34 @@ struct TraceInCollectionTrait<kNoWeakHandling,
if (!HashTableHelper<Value, typename Table::ExtractorType,
typename Table::KeyTraitsType>::
IsEmptyOrDeletedBucket(array[i])) {
- blink::TraceCollectionIfEnabled<kNoWeakHandling, Value, Traits>::Trace(
- visitor, array[i]);
+ blink::TraceCollectionIfEnabled<WeakHandling, Value, Traits>::Trace(
+ visitor, &array[i]);
}
}
return false;
}
};
+template <typename Table>
+struct TraceInCollectionTrait<kNoWeakHandling,
+ blink::HeapHashTableBacking<Table>,
+ void> {
+ static bool Trace(blink::Visitor* visitor, void* self) {
+ return TraceHashTableBackingInCollectionTrait<kNoWeakHandling,
+ Table>::Trace(visitor, self);
+ }
+};
+
+template <typename Table>
+struct TraceInCollectionTrait<kWeakHandling,
+ blink::HeapHashTableBacking<Table>,
+ void> {
+ static bool Trace(blink::Visitor* visitor, void* self) {
+ return TraceHashTableBackingInCollectionTrait<kWeakHandling, Table>::Trace(
+ visitor, self);
+ }
+};
+
// This specialization of TraceInCollectionTrait is for the backing of
// HeapListHashSet. This is for the case that we find a reference to the
// backing from the stack. That probably means we have a GC while we are in a
@@ -456,8 +522,7 @@ struct TraceInCollectionTrait<
blink::HeapListHashSetAllocator<T, inlineCapacity>>;
using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>;
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, void* self) {
+ static bool Trace(blink::Visitor* visitor, void* self) {
Node** array = reinterpret_cast<Node**>(self);
blink::HeapObjectHeader* header =
blink::HeapObjectHeader::FromPayload(self);
@@ -480,101 +545,70 @@ template <typename Key, typename Value, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling,
KeyValuePair<Key, Value>,
Traits> {
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) {
- static_assert(IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kWeakHandlingFlag == WTF::kWeakHandling,
- "T should not be traced");
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, Key, typename Traits::KeyTraits>::Trace(visitor,
- self.key);
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, Value,
- typename Traits::ValueTraits>::Trace(visitor, self.value);
+ using EphemeronHelper =
+ blink::EphemeronKeyValuePair<Key,
+ Value,
+ typename Traits::KeyTraits,
+ typename Traits::ValueTraits>;
+
+ static bool Trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) {
+ if (WTF::IsWeak<Key>::value != WTF::IsWeak<Value>::value) {
+ // Strongification of Weak/Strong and Strong/Weak.
+ EphemeronHelper helper(&self.key, &self.value);
+ visitor->VisitEphemeronKeyValuePair(
+ helper.key, helper.value,
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::KeyType,
+ typename EphemeronHelper::KeyTraits>::Trace,
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::ValueType,
+ typename EphemeronHelper::ValueTraits>::Trace);
+ } else {
+ // Strongification of Strong/Strong or Weak/Weak. Order does not matter
+ // here.
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, Key, typename Traits::KeyTraits>::Trace(visitor,
+ &self.key);
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, Value,
+ typename Traits::ValueTraits>::Trace(visitor, &self.value);
+ }
return false;
}
};
template <typename Key, typename Value, typename Traits>
struct TraceInCollectionTrait<kWeakHandling, KeyValuePair<Key, Value>, Traits> {
- static constexpr bool kKeyIsWeak =
- Traits::KeyTraits::kWeakHandlingFlag == kWeakHandling;
- static constexpr bool kValueIsWeak =
- Traits::ValueTraits::kWeakHandlingFlag == kWeakHandling;
- static const bool kKeyHasStrongRefs =
- IsTraceableInCollectionTrait<typename Traits::KeyTraits>::value;
- static const bool kValueHasStrongRefs =
- IsTraceableInCollectionTrait<typename Traits::ValueTraits>::value;
+ using EphemeronHelper =
+ blink::EphemeronKeyValuePair<Key,
+ Value,
+ typename Traits::KeyTraits,
+ typename Traits::ValueTraits>;
static bool IsAlive(KeyValuePair<Key, Value>& self) {
- static_assert(!kKeyIsWeak || !kValueIsWeak || !kKeyHasStrongRefs ||
- !kValueHasStrongRefs,
- "this configuration is disallowed to avoid unexpected leaks");
- if ((kValueIsWeak && !kKeyIsWeak) ||
- (kValueIsWeak && kKeyIsWeak && !kValueHasStrongRefs)) {
- // Check value first.
- bool value_side_alive = blink::TraceCollectionIfEnabled<
- Traits::ValueTraits::kWeakHandlingFlag, Value,
- typename Traits::ValueTraits>::IsAlive(self.value);
- if (!value_side_alive)
- return false;
- return blink::TraceCollectionIfEnabled<
- Traits::KeyTraits::kWeakHandlingFlag, Key,
- typename Traits::KeyTraits>::IsAlive(self.key);
- }
- // Check key first.
- bool key_side_alive = blink::TraceCollectionIfEnabled<
- Traits::KeyTraits::kWeakHandlingFlag, Key,
- typename Traits::KeyTraits>::IsAlive(self.key);
- if (!key_side_alive)
- return false;
+ // Needed for Weak/Weak, Strong/Weak (reverse ephemeron), and Weak/Strong
+ // (ephemeron). Order of invocation does not matter as tracing weak key or
+ // value does not have any side effects.
return blink::TraceCollectionIfEnabled<
- Traits::ValueTraits::kWeakHandlingFlag, Value,
- typename Traits::ValueTraits>::IsAlive(self.value);
- }
-
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) {
- // This is the core of the ephemeron-like functionality. If there is
- // weakness on the key side then we first check whether there are
- // dead weak pointers on that side, and if there are we don't mark the
- // value side (yet). Conversely if there is weakness on the value side
- // we check that first and don't mark the key side yet if we find dead
- // weak pointers.
- // Corner case: If there is weakness on both the key and value side,
- // and there are also strong pointers on the both sides then we could
- // unexpectedly leak. The scenario is that the weak pointer on the key
- // side is alive, which causes the strong pointer on the key side to be
- // marked. If that then results in the object pointed to by the weak
- // pointer on the value side being marked live, then the whole
- // key-value entry is leaked. To avoid unexpected leaking, we disallow
- // this case, but if you run into this assert, please reach out to Blink
- // reviewers, and we may relax it.
- static_assert(!kKeyIsWeak || !kValueIsWeak || !kKeyHasStrongRefs ||
- !kValueHasStrongRefs,
- "this configuration is disallowed to avoid unexpected leaks");
- if ((kValueIsWeak && !kKeyIsWeak) ||
- (kValueIsWeak && kKeyIsWeak && !kValueHasStrongRefs)) {
- // Check value first.
- bool dead_weak_objects_found_on_value_side =
- blink::TraceCollectionIfEnabled<
- Traits::ValueTraits::kWeakHandlingFlag, Value,
- typename Traits::ValueTraits>::Trace(visitor, self.value);
- if (dead_weak_objects_found_on_value_side)
- return true;
- return blink::TraceCollectionIfEnabled<
- Traits::KeyTraits::kWeakHandlingFlag, Key,
- typename Traits::KeyTraits>::Trace(visitor, self.key);
- }
- // Check key first.
- bool dead_weak_objects_found_on_key_side = blink::TraceCollectionIfEnabled<
- Traits::KeyTraits::kWeakHandlingFlag, Key,
- typename Traits::KeyTraits>::Trace(visitor, self.key);
- if (dead_weak_objects_found_on_key_side)
- return true;
- return blink::TraceCollectionIfEnabled<
- Traits::ValueTraits::kWeakHandlingFlag, Value,
- typename Traits::ValueTraits>::Trace(visitor, self.value);
+ WeakHandlingTrait<Key>::value, Key,
+ typename Traits::KeyTraits>::IsAlive(self.key) &&
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<Value>::value, Value,
+ typename Traits::ValueTraits>::IsAlive(self.value);
+ }
+
+ static bool Trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) {
+ EphemeronHelper helper(&self.key, &self.value);
+ return visitor->VisitEphemeronKeyValuePair(
+ helper.key, helper.value,
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<typename EphemeronHelper::KeyType>::value,
+ typename EphemeronHelper::KeyType,
+ typename EphemeronHelper::KeyTraits>::Trace,
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<typename EphemeronHelper::ValueType>::value,
+ typename EphemeronHelper::ValueType,
+ typename EphemeronHelper::ValueTraits>::Trace);
}
};
@@ -590,11 +624,10 @@ struct TraceInCollectionTrait<kNoWeakHandling,
typename Traits::ValueTraits>::IsAlive(self.value_);
}
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, LinkedHashSetNode<Value>& self) {
- static_assert(IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kWeakHandlingFlag == WTF::kWeakHandling,
- "T should not be traced");
+ static bool Trace(blink::Visitor* visitor, LinkedHashSetNode<Value>& self) {
+ static_assert(
+ IsTraceableInCollectionTrait<Traits>::value || IsWeak<Value>::value,
+ "T should not be traced");
return TraceInCollectionTrait<
kNoWeakHandling, Value,
typename Traits::ValueTraits>::Trace(visitor, self.value_);
@@ -609,8 +642,7 @@ struct TraceInCollectionTrait<kWeakHandling, LinkedHashSetNode<Value>, Traits> {
typename Traits::ValueTraits>::IsAlive(self.value_);
}
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, LinkedHashSetNode<Value>& self) {
+ static bool Trace(blink::Visitor* visitor, LinkedHashSetNode<Value>& self) {
return TraceInCollectionTrait<
kWeakHandling, Value, typename Traits::ValueTraits>::Trace(visitor,
self.value_);
@@ -629,10 +661,10 @@ struct TraceInCollectionTrait<
ListHashSetNode<Value,
blink::HeapListHashSetAllocator<Value, inlineCapacity>>;
- template <typename VisitorDispatcher>
- static bool Trace(VisitorDispatcher visitor, Node* node) {
- static_assert(IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kWeakHandlingFlag == WTF::kWeakHandling,
+ static bool Trace(blink::Visitor* visitor, Node* node) {
+ static_assert(!IsWeak<Node>::value,
+ "ListHashSet does not support weakness");
+ static_assert(IsTraceableInCollectionTrait<Traits>::value,
"T should not be traced");
visitor->Trace(node);
return false;
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
index 9df99b39c66..d618263c29e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
@@ -50,13 +50,12 @@ void UnifiedHeapController::TracePrologue(
BlinkGC::kConcurrentAndLazySweeping,
thread_state_->current_gc_data_.reason);
- // Reset any previously scheduled garbage collections.
thread_state_->SetGCState(ThreadState::kNoGCScheduled);
BlinkGC::GCReason gc_reason =
(v8_flags & v8::EmbedderHeapTracer::TraceFlags::kReduceMemory)
? BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC
: BlinkGC::GCReason::kUnifiedHeapGC;
- thread_state_->IncrementalMarkingStart(gc_reason);
+ thread_state_->StartIncrementalMarking(gc_reason);
is_tracing_done_ = false;
}
@@ -147,6 +146,11 @@ bool UnifiedHeapController::IsTracingDone() {
bool UnifiedHeapController::IsRootForNonTracingGC(
const v8::TracedReference<v8::Value>& handle) {
+ if (thread_state()->IsIncrementalMarking()) {
+ // We have a non-tracing GC while unified GC is in progress. Treat all
+ // objects as roots to avoid stale pointers in the marking worklists.
+ return true;
+ }
const uint16_t class_id = handle.WrapperClassId();
// Stand-alone reference or kCustomWrappableId. Keep as root as
// we don't know better.
@@ -177,6 +181,12 @@ void UnifiedHeapController::ResetHandleInNonTracingGC(
class_id != WrapperTypeInfo::kObjectClassId)
return;
+ // We should not reset any handles during an already running tracing
+ // collection. Resetting a handle could re-allocate a backing or trigger
+ // potential in place rehashing. Both operations may trigger write barriers by
+ // moving references. Such references may already be dead but not yet cleared
+ // which would result in reporting dead objects to V8.
+ DCHECK(!thread_state()->IsIncrementalMarking());
// Clearing the wrapper below adjusts the DOM wrapper store which may
// re-allocate its backing. We have to avoid report memory to V8 as that may
// trigger GC during GC.
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
index 69523852e26..ce94f8becfd 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
@@ -40,7 +40,8 @@ void UnifiedHeapMarkingVisitorBase::VisitImpl(
v8_references_worklist_.Push(&v8_reference);
return;
}
- controller_->RegisterEmbedderReference(v8_reference.Get());
+ controller_->RegisterEmbedderReference(
+ v8_reference.template Cast<v8::Data>().Get());
}
UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state,
@@ -51,6 +52,7 @@ UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state,
isolate,
WorklistTaskId::MutatorThread) {}
+// static
void UnifiedHeapMarkingVisitor::WriteBarrier(
const TraceWrapperV8Reference<v8::Value>& object) {
if (object.IsEmpty() || !ThreadState::IsAnyIncrementalMarking())
@@ -63,6 +65,7 @@ void UnifiedHeapMarkingVisitor::WriteBarrier(
thread_state->CurrentVisitor()->Trace(object);
}
+// static
void UnifiedHeapMarkingVisitor::WriteBarrier(
v8::Isolate* isolate,
const WrapperTypeInfo* wrapper_type_info,
@@ -79,6 +82,11 @@ void UnifiedHeapMarkingVisitor::WriteBarrier(
wrapper_type_info->Trace(thread_state->CurrentVisitor(), object);
}
+void UnifiedHeapMarkingVisitor::Visit(
+ const TraceWrapperV8Reference<v8::Value>& v) {
+ VisitImpl(v);
+}
+
ConcurrentUnifiedHeapMarkingVisitor::ConcurrentUnifiedHeapMarkingVisitor(
ThreadState* thread_state,
MarkingMode mode,
@@ -92,4 +100,9 @@ void ConcurrentUnifiedHeapMarkingVisitor::FlushWorklists() {
v8_references_worklist_.FlushToGlobal();
}
+void ConcurrentUnifiedHeapMarkingVisitor::Visit(
+ const TraceWrapperV8Reference<v8::Value>& v) {
+ VisitImpl(v);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
index d0bb85ce74c..b396d3c59c1 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -47,16 +47,14 @@ class PLATFORM_EXPORT UnifiedHeapMarkingVisitor
: public MarkingVisitor,
public UnifiedHeapMarkingVisitorBase {
public:
- UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
- ~UnifiedHeapMarkingVisitor() override = default;
-
// Write barriers for annotating a write during incremental marking.
static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, void*);
- void Visit(const TraceWrapperV8Reference<v8::Value>& v) final {
- VisitImpl(v);
- }
+ UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
+ ~UnifiedHeapMarkingVisitor() override = default;
+
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
private:
DISALLOW_COPY_AND_ASSIGN(UnifiedHeapMarkingVisitor);
@@ -74,9 +72,7 @@ class PLATFORM_EXPORT ConcurrentUnifiedHeapMarkingVisitor
int task_id);
~ConcurrentUnifiedHeapMarkingVisitor() override = default;
- void Visit(const TraceWrapperV8Reference<v8::Value>& v) final {
- VisitImpl(v);
- }
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
void FlushWorklists() override;
diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h
index e5f4c49e8eb..67e195fe821 100644
--- a/chromium/third_party/blink/renderer/platform/heap/visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h
@@ -52,13 +52,12 @@ namespace blink {
template <typename T>
class GarbageCollected;
+class WeakCallbackInfo;
template <typename T>
-class TraceTrait;
+struct TraceTrait;
class ThreadState;
class Visitor;
template <typename T>
-class SameThreadCheckedMember;
-template <typename T>
class TraceWrapperV8Reference;
// The TraceMethodDelegate is used to convert a trace method for type T to a
@@ -78,6 +77,14 @@ struct TraceMethodDelegate {
}
};
+template <typename T, void (T::*method)(const WeakCallbackInfo&)>
+struct WeakCallbackMethodDelegate {
+ STATIC_ONLY(WeakCallbackMethodDelegate);
+ static void Trampoline(const WeakCallbackInfo& info, void* self) {
+ (reinterpret_cast<T*>(self)->*method)(info);
+ }
+};
+
// Visitor is used to traverse Oilpan's object graph.
class PLATFORM_EXPORT Visitor {
USING_FAST_MALLOC(Visitor);
@@ -98,22 +105,15 @@ class PLATFORM_EXPORT Visitor {
"T needs to be a garbage collected object");
if (!t)
return;
- VisitRoot(const_cast<void*>(reinterpret_cast<const void*>(t)),
- TraceDescriptorFor(t), location);
+ VisitRoot(const_cast<T*>(t), TraceDescriptorFor(t), location);
}
- // Member version of the one-argument templated trace method.
template <typename T>
void Trace(const Member<T>& t) {
DCHECK(!t.IsHashTableDeletedValueSafe());
Trace(t.GetSafe());
}
- template <typename T>
- void Trace(const SameThreadCheckedMember<T>& t) {
- Trace(*(static_cast<const Member<T>*>(&t)));
- }
-
// Fallback methods used only when we need to trace raw pointers of T. This is
// the case when a member is a union where we do not support members.
template <typename T>
@@ -128,8 +128,7 @@ class PLATFORM_EXPORT Visitor {
"T needs to be a garbage collected object");
if (!t)
return;
- Visit(const_cast<void*>(reinterpret_cast<const void*>(t)),
- TraceDescriptorFor(t));
+ Visit(t, TraceDescriptorFor(t));
}
template <typename T>
@@ -138,25 +137,25 @@ class PLATFORM_EXPORT Visitor {
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store),
+ VisitBackingStoreStrongly(backing_store,
reinterpret_cast<void**>(backing_store_slot),
TraceDescriptorFor(backing_store));
}
- template <typename T>
+ template <typename HashTable, typename T>
void TraceBackingStoreWeakly(T* backing_store,
T** backing_store_slot,
- WeakCallback callback,
- void* parameter) {
+ WeakCallback weak_callback,
+ void* weak_callback_parameter) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreWeakly(reinterpret_cast<void*>(backing_store),
+ VisitBackingStoreWeakly(backing_store,
reinterpret_cast<void**>(backing_store_slot),
- TraceTrait<T>::GetTraceDescriptor(
- reinterpret_cast<void*>(backing_store)),
- callback, parameter);
+ TraceDescriptorFor(backing_store),
+ WeakTraceDescriptorFor(backing_store),
+ weak_callback, weak_callback_parameter);
}
template <typename T>
@@ -165,7 +164,7 @@ class PLATFORM_EXPORT Visitor {
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreOnly(reinterpret_cast<void*>(backing_store),
+ VisitBackingStoreOnly(backing_store,
reinterpret_cast<void**>(backing_store_slot));
}
@@ -176,21 +175,20 @@ class PLATFORM_EXPORT Visitor {
// picking the correct overload, so all these trace methods have to have
// the same constness on their argument to allow the type to decide.
template <typename T>
- void Trace(const WeakMember<T>& t) {
+ void Trace(const WeakMember<T>& const_weak_member) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- T* weak_member = t.GetSafe();
+ WeakMember<T>& weak_member = const_cast<WeakMember<T>&>(const_weak_member);
+ std::remove_const_t<T>* value =
+ const_cast<std::remove_const_t<T>*>(weak_member.GetSafe());
- if (!weak_member)
+ if (!value)
return;
- DCHECK(!t.IsHashTableDeletedValueSafe());
- VisitWeak(const_cast<void*>(reinterpret_cast<const void*>(weak_member)),
- reinterpret_cast<void*>(const_cast<WeakMember<T>*>(&t)),
- TraceTrait<T>::GetTraceDescriptor(const_cast<void*>(
- reinterpret_cast<const void*>(weak_member))),
+ DCHECK(!weak_member.IsHashTableDeletedValueSafe());
+ VisitWeak(value, &weak_member, TraceDescriptorFor(value),
&HandleWeakCell<T>);
}
@@ -213,11 +211,12 @@ class PLATFORM_EXPORT Visitor {
TraceTrait<T>::Trace(this, &const_cast<T&>(t));
}
- // Registers a callback for custom weakness.
- template <typename T, void (T::*method)(Visitor*)>
- void RegisterWeakMembers(const T* obj) {
- RegisterWeakCallback(const_cast<T*>(obj),
- &TraceMethodDelegate<T, method>::Trampoline);
+ // Registers an instance method using |RegisterWeakCallback|. See description
+ // below.
+ template <typename T, void (T::*method)(const WeakCallbackInfo&)>
+ void RegisterWeakCallbackMethod(const T* obj) {
+ RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>::Trampoline,
+ const_cast<T*>(obj));
}
// Cross-component tracing interface.
@@ -244,10 +243,22 @@ class PLATFORM_EXPORT Visitor {
virtual void VisitBackingStoreWeakly(void*,
void**,
TraceDescriptor,
+ TraceDescriptor,
WeakCallback,
void*) = 0;
virtual void VisitBackingStoreOnly(void*, void**) = 0;
+ // Visits ephemeron pairs which are a combination of weak and strong keys and
+ // values.
+ using EphemeronTracingCallback = bool (*)(Visitor*, void*);
+ virtual bool VisitEphemeronKeyValuePair(
+ void* key,
+ void* value,
+ EphemeronTracingCallback key_trace_callback,
+ EphemeronTracingCallback value_trace_callback) {
+ return true;
+ }
+
// Visits cross-component references to V8.
virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) = 0;
@@ -257,21 +268,19 @@ class PLATFORM_EXPORT Visitor {
virtual void RegisterBackingStoreCallback(void* backing,
MovingObjectCallback) = 0;
- // Used to register ephemeron callbacks.
- virtual bool RegisterWeakTable(const void* closure,
- EphemeronCallback iteration_callback) {
- return false;
- }
-
- // |WeakCallback| will usually use |ObjectAliveTrait| to figure out liveness
- // of any children of |closure|. Upon return from the callback all references
- // to dead objects must have been purged. Any operation that extends the
- // object graph, including allocation or reviving objects, is prohibited.
- // Clearing out additional pointers is allowed. Note that removing elements
- // from heap collections such as HeapHashSet can cause an allocation if the
- // backing store requires resizing. These collections know how to deal with
- // WeakMember elements though.
- virtual void RegisterWeakCallback(void* closure, WeakCallback) = 0;
+ // Adds a |callback| that is invoked with |parameter| after liveness has been
+ // computed on the whole object graph. The |callback| may use the provided
+ // |WeakCallbackInfo| to determine whether an object is considered alive or
+ // dead.
+ //
+ // - Upon returning from the callback all references to dead objects must have
+ // been cleared.
+ // - Any operation that extends the object graph, including allocation
+ // or reviving objects, is prohibited.
+ // - Clearing out pointers is allowed.
+ // - Removing elements from heap collections is allowed as these collections
+ // are aware of custom weakness and won't resize their backings.
+ virtual void RegisterWeakCallback(WeakCallback callback, void* parameter) = 0;
protected:
template <typename T>
@@ -279,9 +288,14 @@ class PLATFORM_EXPORT Visitor {
return TraceTrait<T>::GetTraceDescriptor(const_cast<T*>(traceable));
}
+ template <typename T>
+ static inline TraceDescriptor WeakTraceDescriptorFor(const T* traceable) {
+ return TraceTrait<T>::GetWeakTraceDescriptor(const_cast<T*>(traceable));
+ }
+
private:
template <typename T>
- static void HandleWeakCell(Visitor* self, void*);
+ static void HandleWeakCell(const WeakCallbackInfo&, void*);
ThreadState* const state_;
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
new file mode 100644
index 00000000000..2a8869b664c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
@@ -0,0 +1,203 @@
+// 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 <atomic>
+#include <iostream>
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+
+namespace blink {
+
+namespace {
+
+class WeaknessMarkingTest : public TestSupportingGC {};
+
+} // namespace
+
+enum class ObjectLiveness { Alive = 0, Dead };
+
+template <typename Map,
+ template <typename T>
+ class KeyHolder,
+ template <typename T>
+ class ValueHolder>
+void TestMapImpl(ObjectLiveness expected_key_liveness,
+ ObjectLiveness expected_value_liveness) {
+ Persistent<Map> map = MakeGarbageCollected<Map>();
+ KeyHolder<IntegerObject> int_key = MakeGarbageCollected<IntegerObject>(1);
+ ValueHolder<IntegerObject> int_value = MakeGarbageCollected<IntegerObject>(2);
+ map->insert(int_key.Get(), int_value.Get());
+ TestSupportingGC::PreciselyCollectGarbage();
+ if (expected_key_liveness == ObjectLiveness::Alive) {
+ EXPECT_TRUE(int_key.Get());
+ } else {
+ EXPECT_FALSE(int_key.Get());
+ }
+ if (expected_value_liveness == ObjectLiveness::Alive) {
+ EXPECT_TRUE(int_value.Get());
+ } else {
+ EXPECT_FALSE(int_value.Get());
+ }
+ EXPECT_EQ(((expected_key_liveness == ObjectLiveness::Alive) &&
+ (expected_value_liveness == ObjectLiveness::Alive))
+ ? 1u
+ : 0u,
+ map->size());
+}
+
+TEST_F(WeaknessMarkingTest, WeakToWeakMap) {
+ using Map = HeapHashMap<WeakMember<IntegerObject>, WeakMember<IntegerObject>>;
+ TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Dead,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Dead);
+ TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
+ ObjectLiveness::Dead);
+}
+
+TEST_F(WeaknessMarkingTest, WeakToStrongMap) {
+ using Map = HeapHashMap<WeakMember<IntegerObject>, Member<IntegerObject>>;
+ TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Dead,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
+ ObjectLiveness::Dead);
+}
+
+TEST_F(WeaknessMarkingTest, StrongToWeakMap) {
+ using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
+ TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Dead);
+ TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
+ ObjectLiveness::Dead);
+}
+
+TEST_F(WeaknessMarkingTest, StrongToStrongMap) {
+ using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
+ TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+ TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Alive,
+ ObjectLiveness::Alive);
+}
+
+template <typename Set, template <typename T> class Type>
+void TestSetImpl(ObjectLiveness object_liveness) {
+ Persistent<Set> set = MakeGarbageCollected<Set>();
+ Type<IntegerObject> object = MakeGarbageCollected<IntegerObject>(1);
+ set->insert(object.Get());
+ TestSupportingGC::PreciselyCollectGarbage();
+ if (object_liveness == ObjectLiveness::Alive) {
+ EXPECT_TRUE(object.Get());
+ } else {
+ EXPECT_FALSE(object.Get());
+ }
+ EXPECT_EQ((object_liveness == ObjectLiveness::Alive) ? 1u : 0u, set->size());
+}
+
+TEST_F(WeaknessMarkingTest, WeakSet) {
+ using Set = HeapHashSet<WeakMember<IntegerObject>>;
+ TestSetImpl<Set, Persistent>(ObjectLiveness::Alive);
+ TestSetImpl<Set, WeakPersistent>(ObjectLiveness::Dead);
+}
+
+TEST_F(WeaknessMarkingTest, StrongSet) {
+ using Set = HeapHashSet<Member<IntegerObject>>;
+ TestSetImpl<Set, Persistent>(ObjectLiveness::Alive);
+ TestSetImpl<Set, WeakPersistent>(ObjectLiveness::Alive);
+}
+
+TEST_F(WeaknessMarkingTest, DeadValueInReverseEphemeron) {
+ using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
+ Persistent<Map> map = MakeGarbageCollected<Map>();
+ Persistent<IntegerObject> key = MakeGarbageCollected<IntegerObject>(1);
+ map->insert(key.Get(), MakeGarbageCollected<IntegerObject>(2));
+ EXPECT_EQ(1u, map->size());
+ TestSupportingGC::PreciselyCollectGarbage();
+ // Entries with dead values are removed.
+ EXPECT_EQ(0u, map->size());
+}
+
+TEST_F(WeaknessMarkingTest, NullValueInReverseEphemeron) {
+ using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
+ Persistent<Map> map = MakeGarbageCollected<Map>();
+ Persistent<IntegerObject> key = MakeGarbageCollected<IntegerObject>(1);
+ map->insert(key.Get(), nullptr);
+ EXPECT_EQ(1u, map->size());
+ TestSupportingGC::PreciselyCollectGarbage();
+ // Entries with null values are kept.
+ EXPECT_EQ(1u, map->size());
+}
+
+namespace weakness_marking_test {
+
+class EphemeronCallbacksCounter
+ : public GarbageCollected<EphemeronCallbacksCounter> {
+ public:
+ EphemeronCallbacksCounter(size_t* count_holder)
+ : count_holder_(count_holder) {}
+
+ void Trace(Visitor* visitor) {
+ visitor->RegisterWeakCallbackMethod<EphemeronCallbacksCounter,
+ &EphemeronCallbacksCounter::Callback>(
+ this);
+ }
+
+ void Callback(const WeakCallbackInfo& info) {
+ *count_holder_ = ThreadState::Current()->Heap().ephemeron_callbacks_.size();
+ }
+
+ private:
+ size_t* count_holder_;
+};
+
+TEST_F(WeaknessMarkingTest, UntracableEphemeronIsNotRegsitered) {
+ size_t ephemeron_count;
+ Persistent<EphemeronCallbacksCounter> ephemeron_callbacks_counter =
+ MakeGarbageCollected<EphemeronCallbacksCounter>(&ephemeron_count);
+ TestSupportingGC::PreciselyCollectGarbage();
+ size_t old_ephemeron_count = ephemeron_count;
+ using Map = HeapHashMap<WeakMember<IntegerObject>, int>;
+ Persistent<Map> map = MakeGarbageCollected<Map>();
+ map->insert(MakeGarbageCollected<IntegerObject>(1), 2);
+ TestSupportingGC::PreciselyCollectGarbage();
+ // Ephemeron value is not traceable, thus the map shouldn't be treated as an
+ // ephemeron.
+ EXPECT_EQ(old_ephemeron_count, ephemeron_count);
+}
+
+TEST_F(WeaknessMarkingTest, TracableEphemeronIsRegsitered) {
+ size_t ephemeron_count;
+ Persistent<EphemeronCallbacksCounter> ephemeron_callbacks_counter =
+ MakeGarbageCollected<EphemeronCallbacksCounter>(&ephemeron_count);
+ TestSupportingGC::PreciselyCollectGarbage();
+ size_t old_ephemeron_count = ephemeron_count;
+ using Map = HeapHashMap<WeakMember<IntegerObject>, Member<IntegerObject>>;
+ Persistent<Map> map = MakeGarbageCollected<Map>();
+ map->insert(MakeGarbageCollected<IntegerObject>(1),
+ MakeGarbageCollected<IntegerObject>(2));
+ TestSupportingGC::PreciselyCollectGarbage();
+ EXPECT_NE(old_ephemeron_count, ephemeron_count);
+}
+
+} // namespace weakness_marking_test
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/worklist.h b/chromium/third_party/blink/renderer/platform/heap/worklist.h
index 1e516113262..7664cacf6be 100644
--- a/chromium/third_party/blink/renderer/platform/heap/worklist.h
+++ b/chromium/third_party/blink/renderer/platform/heap/worklist.h
@@ -56,9 +56,15 @@ class Worklist {
// Returns true if the worklist is empty. Can only be used from the main
// thread without concurrent access.
- bool IsGlobalEmpty() { return worklist_->IsGlobalEmpty(); }
+ bool IsGlobalEmpty() const { return worklist_->IsGlobalEmpty(); }
- bool IsGlobalPoolEmpty() { return worklist_->IsGlobalPoolEmpty(); }
+ bool IsGlobalPoolEmpty() const { return worklist_->IsGlobalPoolEmpty(); }
+
+ // Returns true if the local portion and the global pool are empty (i.e.
+ // whether the current view cannot pop anymore).
+ bool IsLocalViewEmpty() const {
+ return worklist_->IsLocalViewEmpty(task_id_);
+ }
void FlushToGlobal() { worklist_->FlushToGlobal(task_id_); }
@@ -128,9 +134,9 @@ class Worklist {
private_push_segment(task_id)->IsEmpty();
}
- bool IsGlobalPoolEmpty() { return global_pool_.IsEmpty(); }
+ bool IsGlobalPoolEmpty() const { return global_pool_.IsEmpty(); }
- bool IsGlobalEmpty() {
+ bool IsGlobalEmpty() const {
for (int i = 0; i < num_tasks_; i++) {
if (!IsLocalEmpty(i))
return false;
@@ -138,6 +144,10 @@ class Worklist {
return global_pool_.IsEmpty();
}
+ bool IsLocalViewEmpty(int task_id) const {
+ return IsLocalEmpty(task_id) && IsGlobalPoolEmpty();
+ }
+
size_t LocalSize(int task_id) const {
return private_pop_segment(task_id)->Size() +
private_push_segment(task_id)->Size();
@@ -286,9 +296,9 @@ class Worklist {
return false;
}
- inline bool IsEmpty() {
+ inline bool IsEmpty() const {
return base::subtle::NoBarrier_Load(
- reinterpret_cast<base::subtle::AtomicWord*>(&top_)) == 0;
+ reinterpret_cast<const base::subtle::AtomicWord*>(&top_)) == 0;
}
void Clear() {
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc b/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
index c4f15b96021..598155882a0 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
@@ -528,7 +528,8 @@ bool BMPImageReader::DecodeAlternateFormat() {
if (info_header_.compression == JPEG) {
alternate_decoder_ = std::make_unique<JPEGImageDecoder>(
parent_->GetAlphaOption(), parent_->GetColorBehavior(),
- parent_->GetMaxDecodedBytes(), img_data_offset_);
+ parent_->GetMaxDecodedBytes(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDefault, img_data_offset_);
} else {
alternate_decoder_ = std::make_unique<PNGImageDecoder>(
parent_->GetAlphaOption(), ImageDecoder::kDefaultBitDepth,
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
index 0571d11a1c5..75b889d3a48 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
@@ -96,6 +96,7 @@ std::unique_ptr<ImageDecoder> ImageDecoder::Create(
AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
const ColorBehavior& color_behavior,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv,
const SkISize& desired_size) {
// At least kLongestSignatureLength bytes are needed to sniff the signature.
if (data->size() < kLongestSignatureLength)
@@ -129,8 +130,8 @@ std::unique_ptr<ImageDecoder> ImageDecoder::Create(
std::unique_ptr<ImageDecoder> decoder;
if (MatchesJPEGSignature(contents)) {
- decoder.reset(
- new JPEGImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+ decoder.reset(new JPEGImageDecoder(alpha_option, color_behavior,
+ max_decoded_bytes, allow_decode_to_yuv));
} else if (MatchesPNGSignature(contents)) {
decoder.reset(new PNGImageDecoder(alpha_option,
high_bit_depth_decoding_option,
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
index 274c73c966c..f99b89349df 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
@@ -142,6 +142,13 @@ class PLATFORM_EXPORT ImageDecoder {
kMaxValue = kWebPAnimationFormat,
};
+ // Enforces YUV decoding to be disallowed in the image decoder. The default
+ // value defers to the YUV decoding decision to the decoder.
+ enum class OverrideAllowDecodeToYuv {
+ kDefault,
+ kDeny,
+ };
+
virtual ~ImageDecoder() = default;
// Returns a caller-owned decoder of the appropriate type. Returns nullptr if
@@ -154,6 +161,8 @@ class PLATFORM_EXPORT ImageDecoder {
AlphaOption,
HighBitDepthDecodingOption,
const ColorBehavior&,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv =
+ OverrideAllowDecodeToYuv::kDefault,
const SkISize& desired_size = SkISize::MakeEmpty());
static std::unique_ptr<ImageDecoder> Create(
scoped_refptr<SharedBuffer> data,
@@ -161,10 +170,12 @@ class PLATFORM_EXPORT ImageDecoder {
AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
const ColorBehavior& color_behavior,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv =
+ OverrideAllowDecodeToYuv::kDefault,
const SkISize& desired_size = SkISize::MakeEmpty()) {
return Create(SegmentReader::CreateFromSharedBuffer(std::move(data)),
data_complete, alpha_option, high_bit_depth_decoding_option,
- color_behavior, desired_size);
+ color_behavior, allow_decode_to_yuv, desired_size);
}
virtual String FilenameExtension() const = 0;
@@ -364,7 +375,7 @@ class PLATFORM_EXPORT ImageDecoder {
frame_buffer_cache_[0].SetMemoryAllocator(allocator);
}
- virtual bool CanDecodeToYUV() { return allow_decode_to_yuv_; }
+ bool CanDecodeToYUV() { return allow_decode_to_yuv_; }
// Should only be called if CanDecodeToYuv() returns true, in which case
// the subclass of ImageDecoder must override this method.
virtual void DecodeToYUV() { NOTREACHED(); }
@@ -376,12 +387,13 @@ class PLATFORM_EXPORT ImageDecoder {
ImageDecoder(AlphaOption alpha_option,
HighBitDepthDecodingOption high_bit_depth_decoding_option,
const ColorBehavior& color_behavior,
- size_t max_decoded_bytes)
+ size_t max_decoded_bytes,
+ const bool allow_decode_to_yuv = false)
: premultiply_alpha_(alpha_option == kAlphaPremultiplied),
high_bit_depth_decoding_option_(high_bit_depth_decoding_option),
color_behavior_(color_behavior),
max_decoded_bytes_(max_decoded_bytes),
- allow_decode_to_yuv_(false),
+ allow_decode_to_yuv_(allow_decode_to_yuv),
purge_aggressively_(false) {}
// Calculates the most recent frame whose image data may be needed in
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
index 142bc4d5eac..7c01efc1273 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -37,13 +37,14 @@
#include "third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h"
+#include <limits>
#include <memory>
-#include "base/bits.h"
-#include "base/numerics/safe_conversions.h"
+#include "base/numerics/checked_math.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
extern "C" {
#include <stdio.h> // jpeglib.h needs stdio FILE.
@@ -158,6 +159,24 @@ blink::BitmapImageMetrics::JpegColorSpace ExtractUMAJpegColorSpace(
}
}
+// Rounds |size| to the smallest multiple of |alignment| that is greater than or
+// equal to |size|.
+// Note that base::bits::Align is not used here because the alignment is not
+// guaranteed to be a power of two.
+int Align(int size, int alignment) {
+ // Width and height are 16 bits for a JPEG (i.e. < 65536) and the maximum
+ // size of a JPEG MCU in either dimension is 8 * 4 == 32.
+ DCHECK_GE(size, 0);
+ DCHECK_LT(size, 1 << 16);
+ DCHECK_GT(alignment, 0);
+ DCHECK_LE(alignment, 32);
+
+ if (size % alignment == 0)
+ return size;
+
+ return ((size + alignment) / alignment) * alignment;
+}
+
} // namespace
namespace blink {
@@ -432,6 +451,31 @@ class JPEGImageReader final {
info_.image_height % mcu_height != 0;
}
+ // Whether or not the horizontal and vertical sample factors of all components
+ // hold valid values (i.e. 1, 2, 3, or 4). It also returns the maximal
+ // horizontal and vertical sample factors via |max_h| and |max_v|.
+ bool AreValidSampleFactorsAvailable(int* max_h, int* max_v) const {
+ if (!info_.num_components)
+ return false;
+
+ const jpeg_component_info* comp_info = info_.comp_info;
+ if (!comp_info)
+ return false;
+
+ *max_h = 0;
+ *max_v = 0;
+ for (int i = 0; i < info_.num_components; ++i) {
+ if (comp_info[i].h_samp_factor < 1 || comp_info[i].h_samp_factor > 4 ||
+ comp_info[i].v_samp_factor < 1 || comp_info[i].v_samp_factor > 4) {
+ return false;
+ }
+
+ *max_h = std::max(*max_h, comp_info[i].h_samp_factor);
+ *max_v = std::max(*max_v, comp_info[i].v_samp_factor);
+ }
+ return true;
+ }
+
// Decode the JPEG data. If |only_size| is specified, then only the size
// information will be decoded.
bool Decode(bool only_size) {
@@ -448,17 +492,13 @@ class JPEGImageReader final {
switch (info_.jpeg_color_space) {
case JCS_YCbCr:
- // libjpeg can convert YCbCr image pixels to RGB.
- // TODO(crbug.com/919627): is the info_.scale_denom <= 8 actually
- // needed?
- info_.out_color_space = rgbOutputColorSpace();
- if (decoder_->HasImagePlanes() && info_.scale_denom <= 8 &&
- (YuvSubsampling(info_) != cc::YUVSubsampling::kUnknown))
+ if (decoder_->CanDecodeToYUV() &&
+ YuvSubsampling(info_) == cc::YUVSubsampling::k420)
override_color_space = JCS_YCbCr;
- break;
+ FALLTHROUGH; // libjpeg can convert YCbCr image pixels to RGB.
case JCS_GRAYSCALE:
+ FALLTHROUGH; // libjpeg can convert GRAYSCALE image pixels to RGB.
case JCS_RGB:
- // libjpeg can convert GRAYSCALE image pixels to RGB.
info_.out_color_space = rgbOutputColorSpace();
break;
case JCS_CMYK:
@@ -596,6 +636,9 @@ class JPEGImageReader final {
}
FALLTHROUGH;
case JPEG_START_DECOMPRESS:
+ if (info_.out_color_space == JCS_YCbCr)
+ DCHECK(decoder_->HasImagePlanes());
+
// Set parameters for decompression.
// FIXME -- Should reset dct_method and dither mode for final pass
// of progressive JPEG.
@@ -820,14 +863,19 @@ void term_source(j_decompress_ptr jd) {
->Complete();
}
-JPEGImageDecoder::JPEGImageDecoder(AlphaOption alpha_option,
- const ColorBehavior& color_behavior,
- size_t max_decoded_bytes,
- size_t offset)
- : ImageDecoder(alpha_option,
- ImageDecoder::kDefaultBitDepth,
- color_behavior,
- max_decoded_bytes),
+JPEGImageDecoder::JPEGImageDecoder(
+ AlphaOption alpha_option,
+ const ColorBehavior& color_behavior,
+ size_t max_decoded_bytes,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv,
+ size_t offset)
+ : ImageDecoder(
+ alpha_option,
+ ImageDecoder::kDefaultBitDepth,
+ color_behavior,
+ max_decoded_bytes,
+ allow_decode_to_yuv == OverrideAllowDecodeToYuv::kDefault &&
+ RuntimeEnabledFeatures::DecodeJpeg420ImagesToYUVEnabled()),
offset_(offset) {}
JPEGImageDecoder::~JPEGImageDecoder() = default;
@@ -844,6 +892,17 @@ bool JPEGImageDecoder::SetSize(unsigned width, unsigned height) {
}
void JPEGImageDecoder::OnSetData(SegmentReader* data) {
+ // TODO(crbug.com/943519): Incremental YUV decoding is not currently
+ // supported.
+ if (IsAllDataReceived()) {
+ // TODO(crbug.com/919627): Right now |allow_decode_to_yuv_| is false by
+ // default and is set by the blink feature DecodeJpeg420ImagesToYUV.
+ //
+ // Calling IsSizeAvailable() ensures the reader is created and the output
+ // color space is set.
+ allow_decode_to_yuv_ &=
+ IsSizeAvailable() && reader_->Info()->out_color_space == JCS_YCbCr;
+ }
if (reader_)
reader_->SetData(data);
}
@@ -891,21 +950,6 @@ bool JPEGImageDecoder::ShouldGenerateAllSizes() const {
return supported_decode_sizes_.IsEmpty();
}
-bool JPEGImageDecoder::CanDecodeToYUV() {
- // TODO(crbug.com/919627): Right now |allow_decode_to_yuv_| is false by
- // default and is only set true for unit tests.
- //
- // Returning false here is a bit deceptive because the
- // JPEG decoder does support YUV. But the rest of the infrastructure at levels
- // above the decoder is not quite there yet to handle the resulting JPEG YUV
- // data, so for now we disable that path.
- //
- // Calling IsSizeAvailable() ensures the reader is created and the output
- // color space is set.
- return allow_decode_to_yuv_ && IsSizeAvailable() &&
- reader_->Info()->out_color_space == JCS_YCbCr;
-}
-
void JPEGImageDecoder::DecodeToYUV() {
DCHECK(HasImagePlanes());
DCHECK(CanDecodeToYUV());
@@ -933,24 +977,30 @@ Vector<SkISize> JPEGImageDecoder::GetSupportedDecodeSizes() const {
return supported_decode_sizes_;
}
+gfx::Size JPEGImageDecoder::GetImageCodedSize() const {
+ // We use the |max_{h,v}_samp_factor|s returned by
+ // AreValidSampleFactorsAvailable() since the ones available via
+ // Info()->max_{h,v}_samp_factor are not updated until the image is actually
+ // being decoded.
+ int max_h_samp_factor;
+ int max_v_samp_factor;
+ if (!reader_->AreValidSampleFactorsAvailable(&max_h_samp_factor,
+ &max_v_samp_factor)) {
+ return gfx::Size();
+ }
+
+ const int coded_width = Align(Size().Width(), max_h_samp_factor * 8);
+ const int coded_height = Align(Size().Height(), max_v_samp_factor * 8);
+
+ return gfx::Size(coded_width, coded_height);
+}
+
cc::ImageHeaderMetadata JPEGImageDecoder::MakeMetadataForDecodeAcceleration()
const {
cc::ImageHeaderMetadata image_metadata =
ImageDecoder::MakeMetadataForDecodeAcceleration();
image_metadata.jpeg_is_progressive = reader_->Info()->buffered_image;
-
- // Calculate the coded size of the image.
- const size_t mcu_width =
- base::checked_cast<size_t>(reader_->Info()->comp_info->h_samp_factor * 8);
- const size_t mcu_height =
- base::checked_cast<size_t>(reader_->Info()->comp_info->v_samp_factor * 8);
- const int coded_width = base::checked_cast<int>(base::bits::Align(
- base::checked_cast<size_t>(image_metadata.image_size.width()),
- mcu_width));
- const int coded_height = base::checked_cast<int>(base::bits::Align(
- base::checked_cast<size_t>(image_metadata.image_size.height()),
- mcu_height));
- image_metadata.coded_size = gfx::Size(coded_width, coded_height);
+ image_metadata.coded_size = GetImageCodedSize();
return image_metadata;
}
@@ -1029,6 +1079,8 @@ static bool OutputRawData(JPEGImageReader* reader, ImagePlanes* image_planes) {
JSAMPARRAY samples = reader->Samples();
jpeg_decompress_struct* info = reader->Info();
+ DCHECK_EQ(info->out_color_space, JCS_YCbCr);
+
JSAMPARRAY bufferraw[3];
JSAMPROW bufferraw2[32];
bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
index 68010342150..c2e6078e4df 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
@@ -39,6 +39,7 @@ class PLATFORM_EXPORT JPEGImageDecoder final : public ImageDecoder {
JPEGImageDecoder(AlphaOption,
const ColorBehavior&,
size_t max_decoded_bytes,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv,
size_t offset = 0);
~JPEGImageDecoder() override;
@@ -49,7 +50,6 @@ class PLATFORM_EXPORT JPEGImageDecoder final : public ImageDecoder {
bool SetSize(unsigned width, unsigned height) override;
IntSize DecodedYUVSize(int component) const override;
size_t DecodedYUVWidthBytes(int component) const override;
- bool CanDecodeToYUV() override;
void DecodeToYUV() override;
SkYUVColorSpace GetYUVColorSpace() const override;
Vector<SkISize> GetSupportedDecodeSizes() const override;
@@ -81,6 +81,10 @@ class PLATFORM_EXPORT JPEGImageDecoder final : public ImageDecoder {
cc::YUVSubsampling GetYUVSubsampling() const override;
cc::ImageHeaderMetadata MakeMetadataForDecodeAcceleration() const override;
+ // Attempts to calculate the coded size of the JPEG image. Returns a zero
+ // initialized gfx::Size upon failure.
+ gfx::Size GetImageCodedSize() const;
+
// Decodes the image. If |only_size| is true, stops decoding after
// calculating the image size. If decoding fails but there is no more
// data coming, sets the "decode failure" flag.
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
index 8d9c85f4c06..a82cb44e183 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
@@ -52,7 +52,7 @@ namespace {
std::unique_ptr<JPEGImageDecoder> CreateJPEGDecoder(size_t max_decoded_bytes) {
return std::make_unique<JPEGImageDecoder>(
ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::TransformToSRGB(),
- max_decoded_bytes);
+ max_decoded_bytes, ImageDecoder::OverrideAllowDecodeToYuv::kDefault);
}
std::unique_ptr<ImageDecoder> CreateJPEGDecoder() {
@@ -89,8 +89,8 @@ void ReadYUV(size_t max_decoded_bytes,
std::unique_ptr<JPEGImageDecoder> decoder =
CreateJPEGDecoder(max_decoded_bytes);
- decoder->SetData(data.get(), true);
decoder->SetDecodeToYuvForTesting(true);
+ decoder->SetData(data.get(), true);
// Setting a dummy ImagePlanes object signals to the decoder that we want to
// do YUV decoding.
@@ -275,8 +275,8 @@ TEST(JPEGImageDecoderTest, yuv) {
ASSERT_TRUE(data);
std::unique_ptr<JPEGImageDecoder> decoder = CreateJPEGDecoder(230 * 230 * 4);
- decoder->SetData(data.get(), true);
decoder->SetDecodeToYuvForTesting(true);
+ decoder->SetData(data.get(), true);
std::unique_ptr<ImagePlanes> image_planes = std::make_unique<ImagePlanes>();
decoder->SetImagePlanes(std::move(image_planes));
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h b/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
index 6a3443121a5..7ccf114c838 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
@@ -38,24 +38,33 @@
namespace blink {
-#define INSTANCE_COUNTERS_LIST(V) \
- V(AudioHandler) \
- V(Document) \
- V(Frame) \
- V(JSEventListener) \
- V(LayoutObject) \
- V(MediaKeySession) \
- V(MediaKeys) \
- V(Node) \
- V(Resource) \
- V(ContextLifecycleStateObserver) \
- V(V8PerContextData) \
- V(WorkerGlobalScope) \
- V(UACSSResource) \
- V(RTCPeerConnection) \
- V(ResourceFetcher) \
- V(AdSubframe) \
- V(DetachedScriptState)
+#define INSTANCE_COUNTERS_LIST(V) \
+ V(AudioHandler) \
+ V(Document) \
+ V(Frame) \
+ V(JSEventListener) \
+ V(LayoutObject) \
+ V(MediaKeySession) \
+ V(MediaKeys) \
+ V(Node) \
+ V(Resource) \
+ V(ContextLifecycleStateObserver) \
+ V(V8PerContextData) \
+ V(WorkerGlobalScope) \
+ V(UACSSResource) \
+ V(RTCPeerConnection) \
+ V(ResourceFetcher) \
+ V(AdSubframe) \
+ V(DetachedScriptState) \
+ V(V8CallInDetachedWindowByNavigation) \
+ V(V8CallInDetachedWindowByNavigationAfter10s) \
+ V(V8CallInDetachedWindowByNavigationAfter1min) \
+ V(V8CallInDetachedWindowByClosing) \
+ V(V8CallInDetachedWindowByClosingAfter10s) \
+ V(V8CallInDetachedWindowByClosingAfter1min) \
+ V(V8CallInDetachedWindowByOtherReason) \
+ V(V8CallInDetachedWindowByOtherReasonAfter10s) \
+ V(V8CallInDetachedWindowByOtherReasonAfter1min)
// Atomic counters of the number of instances of objects that exist.
//
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
index 29c7ca3b990..93e6ae85dba 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
@@ -7,7 +7,7 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -21,16 +21,16 @@ using performance_manager::mojom::InterventionPolicy;
// static
std::unique_ptr<DocumentResourceCoordinator>
DocumentResourceCoordinator::MaybeCreate(
- service_manager::InterfaceProvider* interface_provider) {
+ const BrowserInterfaceBrokerProxy& interface_broker) {
if (!RuntimeEnabledFeatures::PerformanceManagerInstrumentationEnabled())
return nullptr;
- return base::WrapUnique(new DocumentResourceCoordinator(interface_provider));
+ return base::WrapUnique(new DocumentResourceCoordinator(interface_broker));
}
DocumentResourceCoordinator::DocumentResourceCoordinator(
- service_manager::InterfaceProvider* interface_provider) {
- interface_provider->GetInterface(service_.BindNewPipeAndPassReceiver());
+ const BrowserInterfaceBrokerProxy& interface_broker) {
+ interface_broker.GetInterface(service_.BindNewPipeAndPassReceiver());
DCHECK(service_);
}
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
index 59217530e37..5d0ee9e07fd 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
@@ -13,19 +13,17 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-namespace service_manager {
-class InterfaceProvider;
-} // namespace service_manager
-
namespace blink {
+class BrowserInterfaceBrokerProxy;
+
class PLATFORM_EXPORT DocumentResourceCoordinator final {
USING_FAST_MALLOC(DocumentResourceCoordinator);
public:
// Returns nullptr if instrumentation is not enabled.
static std::unique_ptr<DocumentResourceCoordinator> MaybeCreate(
- service_manager::InterfaceProvider*);
+ const BrowserInterfaceBrokerProxy&);
~DocumentResourceCoordinator();
void SetNetworkAlmostIdle();
@@ -38,7 +36,7 @@ class PLATFORM_EXPORT DocumentResourceCoordinator final {
void OnNonPersistentNotificationCreated();
private:
- explicit DocumentResourceCoordinator(service_manager::InterfaceProvider*);
+ explicit DocumentResourceCoordinator(const BrowserInterfaceBrokerProxy&);
mojo::Remote<performance_manager::mojom::blink::DocumentCoordinationUnit>
service_;
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc
index 42437f60fba..45a6ccb78f4 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc
@@ -29,7 +29,7 @@ void RendererResourceCoordinator::MaybeInitialize() {
mojo::PendingRemote<
performance_manager::mojom::blink::ProcessCoordinationUnit>
remote;
- platform->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ platform->GetBrowserInterfaceBroker()->GetInterface(
remote.InitWithNewPipeAndPassReceiver());
g_renderer_resource_coordinator =
new RendererResourceCoordinator(std::move(remote));
diff --git a/chromium/third_party/blink/renderer/platform/json/json_values.cc b/chromium/third_party/blink/renderer/platform/json/json_values.cc
index 21e84cc2544..1d35618d262 100644
--- a/chromium/third_party/blink/renderer/platform/json/json_values.cc
+++ b/chromium/third_party/blink/renderer/platform/json/json_values.cc
@@ -87,9 +87,9 @@ void WriteIndent(int depth, StringBuilder* output) {
} // anonymous namespace
-const char* kJSONNullString = "null";
-const char* kJSONTrueString = "true";
-const char* kJSONFalseString = "false";
+const char kJSONNullString[] = "null";
+const char kJSONTrueString[] = "true";
+const char kJSONFalseString[] = "false";
void EscapeStringForJSON(const String& str, StringBuilder* dst) {
for (unsigned i = 0; i < str.length(); ++i) {
diff --git a/chromium/third_party/blink/renderer/platform/json/json_values.h b/chromium/third_party/blink/renderer/platform/json/json_values.h
index a3808a1ebb6..cd93b396ded 100644
--- a/chromium/third_party/blink/renderer/platform/json/json_values.h
+++ b/chromium/third_party/blink/renderer/platform/json/json_values.h
@@ -265,9 +265,9 @@ class PLATFORM_EXPORT JSONArray : public JSONValue {
Vector<std::unique_ptr<JSONValue>> data_;
};
-extern const char* kJSONNullString;
-extern const char* kJSONTrueString;
-extern const char* kJSONFalseString;
+extern const char kJSONNullString[];
+extern const char kJSONTrueString[];
+extern const char kJSONFalseString[];
PLATFORM_EXPORT void EscapeStringForJSON(const String&, StringBuilder*);
void DoubleQuoteStringForJSON(const String&, StringBuilder*);
diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc b/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc
index 3f45f763351..94a9886d12b 100644
--- a/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc
+++ b/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc
@@ -29,7 +29,9 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
#include "third_party/blink/renderer/platform/lifecycle_observer.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -149,8 +151,8 @@ TEST(LifecycleContextTest, ShouldNotHitCFICheckOnIncrementalMarking) {
{blink::features::kBlinkHeapIncrementalMarking},
{blink::features::kBlinkHeapConcurrentMarking,
blink::features::kBlinkHeapConcurrentSweeping});
- ThreadState* thread_state = ThreadState::Current();
- thread_state->IncrementalMarkingStart(BlinkGC::GCReason::kForcedGCForTesting);
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ driver.Start();
auto* context = MakeGarbageCollected<DummyContext>();
@@ -163,10 +165,7 @@ TEST(LifecycleContextTest, ShouldNotHitCFICheckOnIncrementalMarking) {
EXPECT_TRUE(observer->ContextDestroyedCalled());
context = nullptr;
- while (thread_state->GetGCState() ==
- ThreadState::kIncrementalMarkingStepScheduled)
- thread_state->IncrementalMarkingStep(BlinkGC::kNoHeapPointersOnStack);
- thread_state->IncrementalMarkingFinalize();
+ driver.FinishGC();
}
TEST(LifecycleContextTest, ForEachObserver) {
diff --git a/chromium/third_party/blink/renderer/platform/loader/README.md b/chromium/third_party/blink/renderer/platform/loader/README.md
index af6f194cd81..0b1c49a7b84 100644
--- a/chromium/third_party/blink/renderer/platform/loader/README.md
+++ b/chromium/third_party/blink/renderer/platform/loader/README.md
@@ -6,8 +6,8 @@ This document describes how files under `platform/loader/` are organized.
Contains Cross-Origin Resource Sharing (CORS) related files. Some functions
in this directory will be removed once CORS support is moved to
-//services/network. Please contact {kinuko,tyoshino,toyoshim}@chromium.org when
-you need to depend on this directory from new code.
+//services/network. Please contact {kinuko,toyoshim}@chromium.org when you need
+to depend on this directory from new code.
## fetch
diff --git a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc
index 927f24b470a..180d4f32735 100644
--- a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc
@@ -98,7 +98,8 @@ bool AllowMimeTypeAsScript(const String& mime_type,
if (mime_type_check_mode == MimeTypeCheck::kStrict) {
return false;
}
- DCHECK_EQ(mime_type_check_mode, MimeTypeCheck::kLax);
+ DCHECK(mime_type_check_mode == MimeTypeCheck::kLaxForWorker ||
+ mime_type_check_mode == MimeTypeCheck::kLaxForElement);
// Beyond this point we handle legacy MIME types, where it depends whether
// we still wish to accept them (or log them using UseCounter, or add a
@@ -131,17 +132,20 @@ bool AllowedByNosniff::MimeTypeAsScript(UseCounter& use_counter,
ConsoleLogger* console_logger,
const ResourceResponse& response,
MimeTypeCheck mime_type_check_mode) {
- // The content type is really only meaningful for the http:-family & data
- // schemes.
- bool is_http_family_or_data =
- response.CurrentRequestUrl().ProtocolIsInHTTPFamily() ||
- response.CurrentRequestUrl().ProtocolIsData();
- if (!is_http_family_or_data &&
+ // The content type is really only meaningful for `http:`-family schemes.
+ if (!response.CurrentRequestUrl().ProtocolIsInHTTPFamily() &&
(response.CurrentRequestUrl().LastPathComponent().EndsWith(".js") ||
response.CurrentRequestUrl().LastPathComponent().EndsWith(".mjs"))) {
return true;
}
+ // Exclude `data:`, `blob:` and `filesystem:` URLs from MIME checks.
+ if (response.CurrentRequestUrl().ProtocolIsData() ||
+ response.CurrentRequestUrl().ProtocolIs(url::kBlobScheme) ||
+ response.CurrentRequestUrl().ProtocolIs(url::kFileSystemScheme)) {
+ return true;
+ }
+
String mime_type = response.HttpContentType();
// Allowed by nosniff?
@@ -191,6 +195,11 @@ bool AllowedByNosniff::MimeTypeAsScript(UseCounter& use_counter,
"Refused to execute script from '" +
response.CurrentRequestUrl().ElidedString() +
"' because its MIME type ('" + mime_type + "') is not executable.");
+ } else if (mime_type_check_mode == MimeTypeCheck::kLaxForWorker) {
+ bool strict_allow = AllowMimeTypeAsScript(mime_type, same_origin,
+ MimeTypeCheck::kStrict, counter);
+ if (!strict_allow)
+ use_counter.CountUse(WebFeature::kStrictMimeTypeChecksWouldBlockWorker);
}
return allow;
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h
index 34cffd5c439..feec85ae187 100644
--- a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h
+++ b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h
@@ -15,7 +15,7 @@ class ResourceResponse;
class PLATFORM_EXPORT AllowedByNosniff final {
public:
- enum class MimeTypeCheck { kStrict, kLax };
+ enum class MimeTypeCheck { kStrict, kLaxForElement, kLaxForWorker };
static bool MimeTypeAsScript(UseCounter&,
ConsoleLogger*,
diff --git a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
index a676308244c..5f86099b1d8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
@@ -114,9 +114,17 @@ TEST_F(AllowedByNosniffTest, AllowedOrNot) {
EXPECT_CALL(*use_counter, CountUse(_)).Times(::testing::AnyNumber());
if (!testcase.allowed)
EXPECT_CALL(*logger, AddConsoleMessageImpl(_, _, _, _));
+ EXPECT_EQ(testcase.allowed, AllowedByNosniff::MimeTypeAsScript(
+ *use_counter, logger, response,
+ MimeTypeCheck::kLaxForElement));
+ ::testing::Mock::VerifyAndClear(use_counter);
+
+ EXPECT_CALL(*use_counter, CountUse(_)).Times(::testing::AnyNumber());
+ if (!testcase.allowed)
+ EXPECT_CALL(*logger, AddConsoleMessageImpl(_, _, _, _));
EXPECT_EQ(testcase.allowed,
AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
- MimeTypeCheck::kLax));
+ MimeTypeCheck::kLaxForWorker));
::testing::Mock::VerifyAndClear(use_counter);
EXPECT_CALL(*use_counter, CountUse(_)).Times(::testing::AnyNumber());
@@ -182,7 +190,24 @@ TEST_F(AllowedByNosniffTest, Counters) {
EXPECT_CALL(*use_counter, CountUse(::testing::Ne(testcase.expected)))
.Times(::testing::AnyNumber());
AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
- MimeTypeCheck::kLax);
+ MimeTypeCheck::kLaxForElement);
+ ::testing::Mock::VerifyAndClear(use_counter);
+
+ EXPECT_CALL(*use_counter, CountUse(testcase.expected));
+ EXPECT_CALL(*use_counter, CountUse(::testing::Ne(testcase.expected)))
+ .Times(::testing::AnyNumber());
+ AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
+ MimeTypeCheck::kLaxForWorker);
+ ::testing::Mock::VerifyAndClear(use_counter);
+
+ EXPECT_CALL(*use_counter,
+ CountUse(WebFeature::kStrictMimeTypeChecksWouldBlockWorker));
+ EXPECT_CALL(*use_counter,
+ CountUse(::testing::Ne(
+ WebFeature::kStrictMimeTypeChecksWouldBlockWorker)))
+ .Times(::testing::AnyNumber());
+ AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
+ MimeTypeCheck::kLaxForWorker);
::testing::Mock::VerifyAndClear(use_counter);
}
}
@@ -210,6 +235,12 @@ TEST_F(AllowedByNosniffTest, AllTheSchemes) {
{"file://home/potato.js", true},
{"file://home/potato.mjs", true},
{"chrome://dino/dino.mjs", true},
+
+ // `blob:` and `filesystem:` are excluded:
+ {"blob:https://example.com/bla.js", true},
+ {"blob:https://example.com/bla.txt", true},
+ {"filesystem:https://example.com/temporary/bla.js", true},
+ {"filesystem:https://example.com/temporary/bla.txt", true},
};
for (auto& testcase : data) {
@@ -225,7 +256,13 @@ TEST_F(AllowedByNosniffTest, AllTheSchemes) {
response.SetHttpHeaderField("X-Content-Type-Options", "nosniff");
EXPECT_EQ(testcase.allowed,
AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
- MimeTypeCheck::kLax));
+ MimeTypeCheck::kStrict));
+ EXPECT_EQ(testcase.allowed, AllowedByNosniff::MimeTypeAsScript(
+ *use_counter, logger, response,
+ MimeTypeCheck::kLaxForElement));
+ EXPECT_EQ(testcase.allowed,
+ AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response,
+ MimeTypeCheck::kLaxForWorker));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
index 8772922ab81..3ffd87b8aba 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
@@ -88,8 +88,6 @@ class PLATFORM_EXPORT FetchClientSettingsObject
virtual const InsecureNavigationsSet& GetUpgradeInsecureNavigationsSet()
const = 0;
- virtual bool GetMixedAutoUpgradeOptOut() const = 0;
-
virtual void Trace(Visitor*) {}
};
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
index a86ef0ddbbd..ad064d1dba4 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
@@ -20,8 +20,7 @@ FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
fetch_client_setting_object.MimeTypeCheckForClassicWorkerScript(),
fetch_client_setting_object.GetAddressSpace(),
fetch_client_setting_object.GetInsecureRequestsPolicy(),
- fetch_client_setting_object.GetUpgradeInsecureNavigationsSet(),
- fetch_client_setting_object.GetMixedAutoUpgradeOptOut()) {}
+ fetch_client_setting_object.GetUpgradeInsecureNavigationsSet()) {}
FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
std::unique_ptr<CrossThreadFetchClientSettingsObjectData> data)
@@ -35,8 +34,7 @@ FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
data->mime_type_check_for_classic_worker_script,
data->address_space,
data->insecure_requests_policy,
- data->insecure_navigations_set,
- data->mixed_autoupgrade_opt_out) {}
+ data->insecure_navigations_set) {}
FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
const KURL& global_object_url,
@@ -48,8 +46,7 @@ FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
AllowedByNosniff::MimeTypeCheck mime_type_check_for_classic_worker_script,
network::mojom::IPAddressSpace address_space,
WebInsecureRequestPolicy insecure_requests_policy,
- InsecureNavigationsSet insecure_navigations_set,
- bool mixed_autoupgrade_opt_out)
+ InsecureNavigationsSet insecure_navigations_set)
: global_object_url_(global_object_url),
base_url_(base_url),
security_origin_(std::move(security_origin)),
@@ -60,7 +57,6 @@ FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
mime_type_check_for_classic_worker_script),
address_space_(address_space),
insecure_requests_policy_(insecure_requests_policy),
- insecure_navigations_set_(std::move(insecure_navigations_set)),
- mixed_autoupgrade_opt_out_(mixed_autoupgrade_opt_out) {}
+ insecure_navigations_set_(std::move(insecure_navigations_set)) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
index f594c709c66..84a9a1b9cc1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
@@ -39,8 +39,7 @@ struct CrossThreadFetchClientSettingsObjectData {
network::mojom::IPAddressSpace address_space,
WebInsecureRequestPolicy insecure_requests_policy,
FetchClientSettingsObject::InsecureNavigationsSet
- insecure_navigations_set,
- bool mixed_autoupgrade_opt_out)
+ insecure_navigations_set)
: global_object_url(std::move(global_object_url)),
base_url(std::move(base_url)),
security_origin(std::move(security_origin)),
@@ -51,8 +50,7 @@ struct CrossThreadFetchClientSettingsObjectData {
mime_type_check_for_classic_worker_script),
address_space(address_space),
insecure_requests_policy(insecure_requests_policy),
- insecure_navigations_set(std::move(insecure_navigations_set)),
- mixed_autoupgrade_opt_out(mixed_autoupgrade_opt_out) {}
+ insecure_navigations_set(std::move(insecure_navigations_set)) {}
const KURL global_object_url;
const KURL base_url;
@@ -66,7 +64,6 @@ struct CrossThreadFetchClientSettingsObjectData {
const WebInsecureRequestPolicy insecure_requests_policy;
const FetchClientSettingsObject::InsecureNavigationsSet
insecure_navigations_set;
- const bool mixed_autoupgrade_opt_out;
private:
DISALLOW_COPY_AND_ASSIGN(CrossThreadFetchClientSettingsObjectData);
@@ -98,8 +95,7 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
AllowedByNosniff::MimeTypeCheck,
network::mojom::IPAddressSpace,
WebInsecureRequestPolicy,
- InsecureNavigationsSet,
- bool mixed_autoupgrade_opt_out);
+ InsecureNavigationsSet);
~FetchClientSettingsObjectSnapshot() override = default;
@@ -129,10 +125,6 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
return insecure_navigations_set_;
}
- bool GetMixedAutoUpgradeOptOut() const override {
- return mixed_autoupgrade_opt_out_;
- }
-
AllowedByNosniff::MimeTypeCheck MimeTypeCheckForClassicWorkerScript()
const override {
return mime_type_check_for_classic_worker_script_;
@@ -145,8 +137,7 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
security_origin_->IsolatedCopy(), referrer_policy_,
outgoing_referrer_.IsolatedCopy(), https_state_,
mime_type_check_for_classic_worker_script_, address_space_,
- insecure_requests_policy_, insecure_navigations_set_,
- mixed_autoupgrade_opt_out_);
+ insecure_requests_policy_, insecure_navigations_set_);
}
private:
@@ -162,7 +153,6 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
const WebInsecureRequestPolicy insecure_requests_policy_;
const InsecureNavigationsSet insecure_navigations_set_;
- const bool mixed_autoupgrade_opt_out_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
index 9565501195c..2b44f836099 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
@@ -57,4 +57,9 @@ void FetchContext::PopulateResourceRequest(
const FetchParameters::ResourceWidth&,
ResourceRequest&) {}
+mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+FetchContext::TakePendingWorkerTimingReceiver(int request_id) {
+ return mojo::NullReceiver();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
index aa2b09db435..cb44fc15e85 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
@@ -38,6 +38,7 @@
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink-forward.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
@@ -98,6 +99,12 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
WebScopedVirtualTimePauser& virtual_time_pauser,
ResourceType);
+ // WARNING: |info| can be modified by the implementation of this method
+ // despite the fact that it is given as const-ref. Namely, if
+ // |worker_timing_receiver_| is set implementations may take (move out) the
+ // field.
+ // TODO(shimazu): Fix this. Eventually ResourceTimingInfo should become a mojo
+ // struct and this should take a moved-value of it.
virtual void AddResourceTiming(const ResourceTimingInfo&);
virtual bool AllowImage(bool, const KURL&) const { return false; }
virtual base::Optional<ResourceRequestBlockedReason> CanRequest(
@@ -145,6 +152,11 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
return WebURLRequest::kPreviewsUnspecified;
}
+ // Returns a receiver corresponding to a request with |request_id|.
+ // Null if the request has not been intercepted by a service worker.
+ virtual mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+ TakePendingWorkerTimingReceiver(int request_id);
+
private:
DISALLOW_COPY_AND_ASSIGN(FetchContext);
};
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
index 0cb6e496324..eea543633a1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
@@ -49,6 +49,8 @@ FetchParameters::FetchParameters(const ResourceRequest& resource_request,
defer_(kNoDefer),
image_request_optimization_(kNone) {}
+FetchParameters::FetchParameters(FetchParameters&&) = default;
+
FetchParameters::~FetchParameters() = default;
void FetchParameters::SetCrossOriginAccessControl(
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
index 8cc76c6216d..de0d27f225b 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
@@ -73,6 +73,9 @@ class PLATFORM_EXPORT FetchParameters {
explicit FetchParameters(const ResourceRequest&);
FetchParameters(const ResourceRequest&, const ResourceLoaderOptions&);
+ FetchParameters(const FetchParameters&) = delete;
+ FetchParameters& operator=(const FetchParameters&) = delete;
+ FetchParameters(FetchParameters&&);
~FetchParameters();
ResourceRequest& MutableResourceRequest() { return resource_request_; }
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
index 41e030134c6..216c0f02ba1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -67,13 +67,12 @@ MemoryCache* ReplaceMemoryCacheForTesting(MemoryCache* cache) {
}
void MemoryCacheEntry::Trace(blink::Visitor* visitor) {
- visitor->template RegisterWeakMembers<MemoryCacheEntry,
- &MemoryCacheEntry::ClearResourceWeak>(
- this);
+ visitor->template RegisterWeakCallbackMethod<
+ MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this);
}
-void MemoryCacheEntry::ClearResourceWeak(Visitor* visitor) {
- if (!resource_ || ThreadHeap::IsHeapObjectAlive(resource_))
+void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& info) {
+ if (!resource_ || info.IsHeapObjectAlive(resource_))
return;
GetMemoryCache()->Remove(resource_.Get());
resource_.Clear();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
index b3000a9c3c3..bc8e09b6442 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
@@ -55,9 +55,9 @@ class MemoryCacheEntry final : public GarbageCollected<MemoryCacheEntry> {
Resource* GetResource() const { return resource_; }
private:
- void ClearResourceWeak(Visitor*);
+ void ClearResourceWeak(const WeakCallbackInfo&);
- WeakMember<Resource> resource_;
+ UntracedMember<Resource> resource_;
};
// This cache holds subresources used by Web pages: images, scripts,
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
index cc258880713..8a00bb48575 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
@@ -26,12 +26,15 @@ NullResourceFetcherProperties::NullResourceFetcherProperties()
AllowedByNosniff::MimeTypeCheck::kStrict,
network::mojom::IPAddressSpace::kPublic,
kLeaveInsecureRequestsAlone,
- FetchClientSettingsObject::InsecureNavigationsSet(),
- false /* mixed_autoupgrade_opt_out */)) {}
+ FetchClientSettingsObject::InsecureNavigationsSet())) {}
void NullResourceFetcherProperties::Trace(Visitor* visitor) {
visitor->Trace(fetch_client_settings_object_);
ResourceFetcherProperties::Trace(visitor);
}
+const KURL& NullResourceFetcherProperties::WebBundlePhysicalUrl() const {
+ return NullURL();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
index 2615a5e3725..e5d2d6f5863 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
@@ -43,6 +43,7 @@ class PLATFORM_EXPORT NullResourceFetcherProperties final
scheduler::FrameStatus GetFrameStatus() const override {
return scheduler::FrameStatus::kNone;
}
+ const KURL& WebBundlePhysicalUrl() const override;
private:
const Member<const FetchClientSettingsObject> fetch_client_settings_object_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index 13b03795a99..4d15c82e932 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -348,13 +348,6 @@ void RawResource::DidDownloadToBlob(scoped_refptr<BlobDataHandle> blob) {
c->DidDownloadToBlob(this, blob);
}
-void RawResource::ReportResourceTimingToClients(
- const ResourceTimingInfo& info) {
- ResourceClientWalker<RawResourceClient> w(Clients());
- while (RawResourceClient* c = w.Next())
- c->DidReceiveResourceTiming(this, info);
-}
-
bool RawResource::MatchPreload(const FetchParameters& params,
base::SingleThreadTaskRunner* task_runner) {
if (!Resource::MatchPreload(params, task_runner))
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
index 8dcb65ccdb9..11aa7531c9a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
@@ -128,7 +128,6 @@ class PLATFORM_EXPORT RawResource final : public Resource {
uint64_t total_bytes_to_be_sent) override;
void DidDownloadData(uint64_t) override;
void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) override;
- void ReportResourceTimingToClients(const ResourceTimingInfo&) override;
bool MatchPreload(const FetchParameters&,
base::SingleThreadTaskRunner*) override;
@@ -194,7 +193,6 @@ class PLATFORM_EXPORT RawResourceClient : public ResourceClient {
}
virtual void RedirectBlocked() {}
virtual void DataDownloaded(Resource*, uint64_t) {}
- virtual void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) {}
// Called for requests that had DownloadToBlob set to true. Can be called with
// null if creating the blob failed for some reason (but the download itself
// otherwise succeeded). Could also not be called at all if the downloaded
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
index d1e114bdc64..a94e9665eaf 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -831,7 +831,7 @@ Resource::MatchStatus Resource::CanReuse(const FetchParameters& params) const {
// Don't reuse an existing resource when the source origin is different.
- if (!existing_origin->IsSameSchemeHostPort(new_origin.get()))
+ if (!existing_origin->IsSameOriginWith(new_origin.get()))
return MatchStatus::kUnknownFailure;
// securityOrigin has more complicated checks which callers are responsible
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
index ea72b2936c8..9b83d433ec0 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -68,7 +68,6 @@ class FetchParameters;
class ResourceClient;
class ResourceFetcher;
class ResourceFinishObserver;
-class ResourceTimingInfo;
class ResourceLoader;
class ResponseBodyLoaderDrainableInterface;
class SecurityOrigin;
@@ -275,8 +274,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
void SetResponse(const ResourceResponse&);
const ResourceResponse& GetResponse() const { return response_; }
- virtual void ReportResourceTimingToClients(const ResourceTimingInfo&) {}
-
// Sets the serialized metadata retrieved from the platform's cache.
// Subclasses of Resource that support cached metadata should override this
// method with one that fills the current CachedMetadataHandler.
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 50929eb28a7..d55eaa3ac98 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -235,8 +235,7 @@ ResourceLoadPriority AdjustPriorityWithPriorityHint(
// out-of-viewport images already have priority set to kLow
// - Link preloads
// For this initial implementation we do a blanket demotion regardless
- // of `as` value/type. TODO(domfarolino): maybe discuss a more
- // granular approach with loading team
+ // of `as` value/type.
if (type == ResourceType::kImage ||
resource_request.GetRequestContext() ==
mojom::RequestContextType::FETCH ||
@@ -653,7 +652,8 @@ void ResourceFetcher::DidLoadResourceFromMemoryCache(
// Resources loaded from memory cache should be reported the first time
// they're used.
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
- resource->Options().initiator_info.name, base::TimeTicks::Now());
+ resource->Options().initiator_info.name, base::TimeTicks::Now(),
+ request.GetRequestContext());
// TODO(yoav): GetInitialUrlForResourceTiming() is only needed until
// Out-of-Blink CORS lands: https://crbug.com/736308
info->SetInitialURL(
@@ -987,20 +987,6 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
TRACE_EVENT1("blink", "ResourceFetcher::requestResource", "url",
params.Url().GetString().Utf8());
- // We need to attach an origin header when the request's method is neither
- // GET nor HEAD. For requests made by an extension content scripts, we want to
- // attach page's origin, whereas the request's origin is the content script's
- // origin. See https://crbug.com/944704 for details.
- // TODO(crbug.com/940068) Remove this.
- if (resource_request.HttpMethod() != http_names::kGET &&
- resource_request.HttpMethod() != http_names::kHEAD &&
- resource_request.RequestorOrigin() &&
- !resource_request.RequestorOrigin()->IsSameSchemeHostPort(
- properties_->GetFetchClientSettingsObject().GetSecurityOrigin())) {
- resource_request.SetHttpOriginIfNeeded(
- properties_->GetFetchClientSettingsObject().GetSecurityOrigin());
- }
-
// |resource_request|'s origin can be null here, corresponding to the "client"
// value in the spec. In that case client's origin is used.
if (!resource_request.RequestorOrigin()) {
@@ -1252,8 +1238,9 @@ void ResourceFetcher::StorePerformanceTimingInitiatorInformation(
if (fetch_initiator == fetch_initiator_type_names::kInternal)
return;
- scoped_refptr<ResourceTimingInfo> info =
- ResourceTimingInfo::Create(fetch_initiator, base::TimeTicks::Now());
+ scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
+ fetch_initiator, base::TimeTicks::Now(),
+ resource->GetResourceRequest().GetRequestContext());
resource_timing_info_map_.insert(resource, std::move(info));
}
@@ -1815,9 +1802,11 @@ void ResourceFetcher::HandleLoaderFinish(Resource* resource,
info->AddFinalTransferSize(
encoded_data_length == -1 ? 0 : encoded_data_length);
+ auto receiver = Context().TakePendingWorkerTimingReceiver(
+ resource->GetResponse().RequestId());
+ info->SetWorkerTimingReceiver(std::move(receiver));
if (resource->Options().request_initiator_context == kDocumentContext)
Context().AddResourceTiming(*info);
- resource->ReportResourceTimingToClients(*info);
}
}
@@ -1891,7 +1880,6 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
DCHECK(resource);
DCHECK(resource->StillNeedsLoad());
- ResourceRequest request(resource->GetResourceRequest());
ResourceLoader* loader = nullptr;
{
@@ -1906,19 +1894,15 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
return false;
}
+ const auto& request = resource->GetResourceRequest();
ResourceResponse response;
- resource->VirtualTimePauser().PauseVirtualTime();
if (resource_load_observer_) {
DCHECK(!IsDetached());
resource_load_observer_->WillSendRequest(
resource->InspectorId(), request, response, resource->GetType(),
resource->Options().initiator_info);
}
- // TODO(shaochuan): Saving modified ResourceRequest back to |resource|,
- // remove once dispatchWillSendRequest() takes const ResourceRequest.
- // crbug.com/632580
- resource->SetResourceRequest(request);
using QuotaType = decltype(inflight_keepalive_bytes_);
QuotaType size = 0;
@@ -1947,6 +1931,7 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
} else {
non_blocking_loaders_.insert(loader);
}
+ resource->VirtualTimePauser().PauseVirtualTime();
StorePerformanceTimingInitiatorInformation(resource);
}
@@ -2040,8 +2025,11 @@ void ResourceFetcher::UpdateAllImageResourcePriorities() {
String ResourceFetcher::GetCacheIdentifier() const {
if (properties_->GetControllerServiceWorkerMode() !=
- mojom::ControllerServiceWorkerMode::kNoController)
+ mojom::ControllerServiceWorkerMode::kNoController) {
return String::Number(properties_->ServiceWorkerId());
+ }
+ if (properties_->WebBundlePhysicalUrl().IsValid())
+ return properties_->WebBundlePhysicalUrl().GetString();
return MemoryCache::DefaultCacheIdentifier();
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
index 2ab0d512989..51da99672f2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
@@ -23,6 +23,7 @@ void DetachableResourceFetcherProperties::Detach() {
load_complete_ = properties_->IsLoadComplete();
is_subframe_deprioritization_enabled_ =
properties_->IsSubframeDeprioritizationEnabled();
+ web_bundle_physical_url_ = properties_->WebBundlePhysicalUrl();
properties_ = nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
index 297508b42ea..61810977848 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_status.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
@@ -82,6 +83,10 @@ class PLATFORM_EXPORT ResourceFetcherProperties
// Returns the scheduling status of the associated frame. Returns |kNone|
// if there is no such a frame.
virtual scheduler::FrameStatus GetFrameStatus() const = 0;
+
+ // The physical URL of Web Bundle from which this global context is loaded.
+ // Used as an additional identifier for MemoryCache.
+ virtual const KURL& WebBundlePhysicalUrl() const = 0;
};
// A delegating ResourceFetcherProperties subclass which can be retained
@@ -140,6 +145,10 @@ class PLATFORM_EXPORT DetachableResourceFetcherProperties final
return properties_ ? properties_->GetFrameStatus()
: scheduler::FrameStatus::kNone;
}
+ const KURL& WebBundlePhysicalUrl() const override {
+ return properties_ ? properties_->WebBundlePhysicalUrl()
+ : web_bundle_physical_url_;
+ }
private:
// |properties_| is null if and only if detached.
@@ -151,6 +160,7 @@ class PLATFORM_EXPORT DetachableResourceFetcherProperties final
bool paused_ = false;
bool load_complete_ = false;
bool is_subframe_deprioritization_enabled_ = false;
+ KURL web_bundle_physical_url_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
index b3ae16d95f2..3b14d081582 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
@@ -27,8 +27,7 @@ class DetachableResourceFetcherPropertiesTest : public testing::Test {
"https://example.com/foo.html", HttpsState::kModern,
AllowedByNosniff::MimeTypeCheck::kStrict, address_space,
kLeaveInsecureRequestsAlone,
- FetchClientSettingsObject::InsecureNavigationsSet(),
- false /* mixed_autoupgrade_opt_out */);
+ FetchClientSettingsObject::InsecureNavigationsSet());
}
};
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index 0d5bf38942d..bb529c83964 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -104,8 +104,7 @@ const FetchClientSettingsObjectSnapshot& CreateFetchClientSettingsObject(
network::mojom::ReferrerPolicy::kDefault, "https://example.com/foo.html",
HttpsState::kModern, AllowedByNosniff::MimeTypeCheck::kStrict,
address_space, kLeaveInsecureRequestsAlone,
- FetchClientSettingsObject::InsecureNavigationsSet(),
- false /* mixed_autoupgrade_opt_out */);
+ FetchClientSettingsObject::InsecureNavigationsSet());
}
} // namespace
@@ -295,8 +294,9 @@ TEST_F(ResourceFetcherTest, Vary) {
}
TEST_F(ResourceFetcherTest, ResourceTimingInfo) {
- auto info = ResourceTimingInfo::Create(fetch_initiator_type_names::kDocument,
- base::TimeTicks::Now());
+ auto info = ResourceTimingInfo::Create(
+ fetch_initiator_type_names::kDocument, base::TimeTicks::Now(),
+ mojom::RequestContextType::UNSPECIFIED);
info->AddFinalTransferSize(5);
EXPECT_EQ(info->TransferSize(), static_cast<uint64_t>(5));
ResourceResponse redirect_response(KURL("https://example.com/original"));
@@ -476,9 +476,6 @@ class ServeRequestsOnCompleteClient final
return true;
}
void DataDownloaded(Resource*, uint64_t) override { ASSERT_TRUE(false); }
- void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override {
- ASSERT_TRUE(false);
- }
void Trace(blink::Visitor* visitor) override {
RawResourceClient::Trace(visitor);
@@ -959,8 +956,8 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- fetch_params = FetchParameters(resource_request);
- Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
+ FetchParameters fetch_params2 = FetchParameters(resource_request);
+ Resource* new_resource = MockResource::Fetch(fetch_params2, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
EXPECT_TRUE(resource->IsLoaded());
@@ -974,7 +971,7 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
RegisterMockedURLLoadWithCustomResponse(
url, test::PlatformTestDataPath(kTestResourceFilename),
WrappedResourceResponse(revalidate_response));
- new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
+ new_resource = MockResource::Fetch(fetch_params2, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
EXPECT_TRUE(GetMemoryCache()->Contains(resource));
static_cast<scheduler::FakeTaskRunner*>(fetcher->GetTaskRunner().get())
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index 3d6537e645e..58399f33fd1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -481,7 +481,7 @@ void ResourceLoader::Start() {
if (request.IsAutomaticUpgrade()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> pending_recorder;
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
pending_recorder.InitWithNewPipeAndPassReceiver());
auto recorder =
std::make_unique<ukm::MojoUkmRecorder>(std::move(pending_recorder));
@@ -770,7 +770,7 @@ bool ResourceLoader::WillFollowRedirect(
// origin with |request|’s current url’s origin, then set |request|’s
// tainted origin flag.
if (origin &&
- !SecurityOrigin::AreSameSchemeHostPort(
+ !SecurityOrigin::AreSameOrigin(
new_url, redirect_response.CurrentRequestUrl()) &&
!origin->CanRequest(redirect_response.CurrentRequestUrl())) {
origin = SecurityOrigin::CreateUniqueOpaque();
@@ -913,7 +913,7 @@ void ResourceLoader::DidReceiveResponseInternal(
if (request.IsAutomaticUpgrade()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> pending_recorder;
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
pending_recorder.InitWithNewPipeAndPassReceiver());
auto recorder =
std::make_unique<ukm::MojoUkmRecorder>(std::move(pending_recorder));
@@ -1186,7 +1186,7 @@ void ResourceLoader::DidFail(const WebURLError& error,
if (request.IsAutomaticUpgrade()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> pending_recorder;
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
pending_recorder.InitWithNewPipeAndPassReceiver());
auto recorder =
std::make_unique<ukm::MojoUkmRecorder>(std::move(pending_recorder));
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
index fa5cd0ad990..b36dbcf738b 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -97,6 +97,7 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
std::unique_ptr<ResourceRequest> request =
std::make_unique<ResourceRequest>(new_url);
request->SetRequestorOrigin(RequestorOrigin());
+ request->SetIsolatedWorldOrigin(IsolatedWorldOrigin());
request->SetHttpMethod(new_method);
request->SetSiteForCookies(new_site_for_cookies);
String referrer =
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index ba96c04e50c..4148460ef54 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -499,9 +499,6 @@ class PLATFORM_EXPORT ResourceRequest final {
network::mojom::CredentialsMode credentials_mode_;
network::mojom::RedirectMode redirect_mode_;
String fetch_integrity_;
- // TODO(domfarolino): Use AtomicString for referrer_string_ once
- // off-main-thread fetch is fully implemented and ResourceRequest never gets
- // transferred between threads. See https://crbug.com/706331.
String referrer_string_;
network::mojom::ReferrerPolicy referrer_policy_;
bool did_set_http_referrer_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
index 9db2d03be02..e7a8fbad67f 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -263,6 +264,26 @@ void ResourceResponse::AddHttpHeaderField(const AtomicString& name,
result.stored_value->value = result.stored_value->value + ", " + value;
}
+void ResourceResponse::AddHttpHeaderFieldWithMultipleValues(
+ const AtomicString& name,
+ const Vector<AtomicString>& values) {
+ if (values.IsEmpty())
+ return;
+
+ UpdateHeaderParsedState(name);
+
+ StringBuilder value_builder;
+ const auto it = http_header_fields_.Find(name);
+ if (it != http_header_fields_.end())
+ value_builder.Append(it->value);
+ for (const auto& value : values) {
+ if (!value_builder.IsEmpty())
+ value_builder.Append(", ");
+ value_builder.Append(value);
+ }
+ http_header_fields_.Set(name, value_builder.ToAtomicString());
+}
+
void ResourceResponse::ClearHttpHeaderField(const AtomicString& name) {
http_header_fields_.Remove(name);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
index 6f2445073ad..9ba1090ee2e 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -223,6 +223,8 @@ class PLATFORM_EXPORT ResourceResponse final {
const AtomicString& HttpHeaderField(const AtomicString& name) const;
void SetHttpHeaderField(const AtomicString& name, const AtomicString& value);
void AddHttpHeaderField(const AtomicString& name, const AtomicString& value);
+ void AddHttpHeaderFieldWithMultipleValues(const AtomicString& name,
+ const Vector<AtomicString>& values);
void ClearHttpHeaderField(const AtomicString& name);
const HTTPHeaderMap& HttpHeaderFields() const;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
index 2e6dbde4b64..1e2d9198ec8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
@@ -77,11 +77,29 @@ TEST(ResourceResponseTest, CrossThreadAtomicStrings) {
ResourceResponse response(CreateTestResponse());
RunHeaderRelatedTest(response);
std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread)
+ ThreadCreationParams(ThreadType::kTestThread)
.SetThreadNameForTest("WorkerThread"));
PostCrossThreadTask(*thread->GetTaskRunner(), FROM_HERE,
CrossThreadBindOnce(&RunInThread));
thread.reset();
}
+TEST(ResourceResponseTest, AddHttpHeaderFieldWithMultipleValues) {
+ ResourceResponse response(CreateTestResponse());
+
+ Vector<AtomicString> empty_values;
+ response.AddHttpHeaderFieldWithMultipleValues("set-cookie", empty_values);
+ EXPECT_EQ(AtomicString(), response.HttpHeaderField("set-cookie"));
+
+ response.AddHttpHeaderField("set-cookie", "a=1");
+ EXPECT_EQ("a=1", response.HttpHeaderField("set-cookie"));
+
+ Vector<AtomicString> values;
+ values.push_back("b=2");
+ values.push_back("c=3");
+ response.AddHttpHeaderFieldWithMultipleValues("set-cookie", values);
+
+ EXPECT_EQ("a=1, b=2, c=3", response.HttpHeaderField("set-cookie"));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
index 6916a2542f5..2b67a18eaf2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
@@ -14,7 +14,7 @@ void ResourceTimingInfo::AddRedirect(const ResourceResponse& redirect_response,
redirect_chain_.push_back(redirect_response);
if (has_cross_origin_redirect_)
return;
- bool cross_origin = !SecurityOrigin::AreSameSchemeHostPort(
+ bool cross_origin = !SecurityOrigin::AreSameOrigin(
redirect_response.CurrentRequestUrl(), new_url);
if (cross_origin) {
has_cross_origin_redirect_ = true;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
index 7c45a290cbc..32f53487f19 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
@@ -34,6 +34,7 @@
#include <memory>
#include "base/macros.h"
+#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -47,9 +48,11 @@ class PLATFORM_EXPORT ResourceTimingInfo
USING_FAST_MALLOC(ResourceTimingInfo);
public:
- static scoped_refptr<ResourceTimingInfo> Create(const AtomicString& type,
- const base::TimeTicks time) {
- return base::AdoptRef(new ResourceTimingInfo(type, time));
+ static scoped_refptr<ResourceTimingInfo> Create(
+ const AtomicString& type,
+ const base::TimeTicks time,
+ mojom::RequestContextType context) {
+ return base::AdoptRef(new ResourceTimingInfo(type, time, context));
}
base::TimeTicks InitialTime() const { return initial_time_; }
@@ -87,13 +90,28 @@ class PLATFORM_EXPORT ResourceTimingInfo
negative_allowed_ = negative_allowed;
}
bool NegativeAllowed() const { return negative_allowed_; }
+ mojom::RequestContextType ContextType() const { return context_type_; }
+
+ void SetWorkerTimingReceiver(
+ mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+ worker_timing_receiver) {
+ worker_timing_receiver_ = std::move(worker_timing_receiver);
+ }
+
+ mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+ TakeWorkerTimingReceiver() const {
+ return std::move(worker_timing_receiver_);
+ }
private:
- ResourceTimingInfo(const AtomicString& type, const base::TimeTicks time)
- : type_(type), initial_time_(time) {}
+ ResourceTimingInfo(const AtomicString& type,
+ const base::TimeTicks time,
+ mojom::RequestContextType context_type)
+ : type_(type), initial_time_(time), context_type_(context_type) {}
AtomicString type_;
base::TimeTicks initial_time_;
+ mojom::RequestContextType context_type_;
base::TimeTicks load_response_end_;
KURL initial_url_;
ResourceResponse final_response_;
@@ -102,6 +120,16 @@ class PLATFORM_EXPORT ResourceTimingInfo
bool has_cross_origin_redirect_ = false;
bool negative_allowed_ = false;
+ // Mutable since it must be passed to blink::PerformanceResourceTiming by move
+ // semantics but ResourceTimingInfo is passed only by const reference.
+ // ResourceTimingInfo can't be changed to pass by value because it can
+ // actually be a large object.
+ // It can be null when service worker doesn't serve a response for the
+ // resource. In that case, PerformanceResourceTiming#workerTiming is kept
+ // empty.
+ mutable mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+ worker_timing_receiver_;
+
DISALLOW_COPY_AND_ASSIGN(ResourceTimingInfo);
};
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.cc
index b0b42a8bc22..dd5dac58d39 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.cc
@@ -16,12 +16,18 @@ TextResourceDecoderOptions::TextResourceDecoderOptions(
nullptr,
KURL()) {}
-TextResourceDecoderOptions
-TextResourceDecoderOptions::CreateAlwaysUseUTF8ForText() {
+TextResourceDecoderOptions TextResourceDecoderOptions::CreateUTF8Decode() {
return TextResourceDecoderOptions(kAlwaysUseUTF8ForText, kPlainTextContent,
UTF8Encoding(), nullptr, NullURL());
}
+TextResourceDecoderOptions
+TextResourceDecoderOptions::CreateUTF8DecodeWithoutBOM() {
+ TextResourceDecoderOptions options = CreateUTF8Decode();
+ options.no_bom_decoding_ = true;
+ return options;
+}
+
TextResourceDecoderOptions TextResourceDecoderOptions::CreateWithAutoDetection(
ContentType content_type,
const WTF::TextEncoding& default_encoding,
@@ -41,6 +47,7 @@ TextResourceDecoderOptions::TextResourceDecoderOptions(
: encoding_detection_option_(encoding_detection_option),
content_type_(content_type),
default_encoding_(default_encoding),
+ no_bom_decoding_(false),
use_lenient_xml_decoding_(false),
hint_encoding_(hint_encoding),
hint_url_(hint_url) {
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h b/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h
index 50b95fa43e9..c8545aeb9f6 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h
@@ -38,7 +38,11 @@ class PLATFORM_EXPORT TextResourceDecoderOptions final {
// Corresponds to utf-8 decode in Encoding spec:
// https://encoding.spec.whatwg.org/#utf-8-decode.
- static TextResourceDecoderOptions CreateAlwaysUseUTF8ForText();
+ static TextResourceDecoderOptions CreateUTF8Decode();
+
+ // Corresponds to utf-8 decode without BOM in Encoding spec:
+ // https://encoding.spec.whatwg.org/#utf-8-decode-without-bom.
+ static TextResourceDecoderOptions CreateUTF8DecodeWithoutBOM();
static TextResourceDecoderOptions CreateWithAutoDetection(
ContentType,
@@ -79,6 +83,7 @@ class PLATFORM_EXPORT TextResourceDecoderOptions final {
}
ContentType GetContentType() const { return content_type_; }
const WTF::TextEncoding& DefaultEncoding() const { return default_encoding_; }
+ bool GetNoBOMDecoding() const { return no_bom_decoding_; }
bool GetUseLenientXMLDecoding() const { return use_lenient_xml_decoding_; }
const char* HintEncoding() const { return hint_encoding_; }
@@ -95,6 +100,7 @@ class PLATFORM_EXPORT TextResourceDecoderOptions final {
EncodingDetectionOption encoding_detection_option_;
ContentType content_type_;
WTF::TextEncoding default_encoding_;
+ bool no_bom_decoding_;
bool use_lenient_xml_decoding_; // Don't stop on XML decoding errors.
// Hints for DetectTextEncoding().
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h b/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
index c7fdb961cd7..918a3528df8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_WORKER_RESOURCE_TIMING_NOTIFIER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_WORKER_RESOURCE_TIMING_NOTIFIER_H_
+#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -25,8 +26,11 @@ class WorkerResourceTimingNotifier
// Implementations should route the info to an appropriate Performance
// Timeline which may be associated with a different thread from the current
// running thread.
- virtual void AddResourceTiming(const WebResourceTimingInfo&,
- const AtomicString& initiator_type) = 0;
+ virtual void AddResourceTiming(
+ const WebResourceTimingInfo&,
+ const AtomicString& initiator_type,
+ mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
+ worker_timing_receiver) = 0;
virtual void Trace(Visitor*) {}
};
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
index 3bef4165682..723d4c721e0 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
@@ -30,8 +30,7 @@ TestResourceFetcherProperties::TestResourceFetcherProperties(
AllowedByNosniff::MimeTypeCheck::kStrict,
network::mojom::IPAddressSpace::kPublic,
kLeaveInsecureRequestsAlone,
- FetchClientSettingsObject::InsecureNavigationsSet(),
- false /* mixed_autoupgrade_opt_out */)) {}
+ FetchClientSettingsObject::InsecureNavigationsSet())) {}
TestResourceFetcherProperties::TestResourceFetcherProperties(
const FetchClientSettingsObject& fetch_client_settings_object)
@@ -42,4 +41,8 @@ void TestResourceFetcherProperties::Trace(Visitor* visitor) {
ResourceFetcherProperties::Trace(visitor);
}
+const KURL& TestResourceFetcherProperties::WebBundlePhysicalUrl() const {
+ return NullURL();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
index 9cda1a0db16..0e46490490d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
@@ -55,6 +55,7 @@ class TestResourceFetcherProperties final : public ResourceFetcherProperties {
scheduler::FrameStatus GetFrameStatus() const override {
return frame_status_;
}
+ const KURL& WebBundlePhysicalUrl() const override;
void SetIsMainFrame(bool value) { is_main_frame_ = value; }
void SetControllerServiceWorkerMode(ControllerServiceWorkerMode mode) {
diff --git a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
index 90b1e7c9b2a..979fb044f71 100644
--- a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -134,7 +134,7 @@ void WebAudioSourceProviderImpl::SetClient(
// The client will now take control by calling provideInput() periodically.
client_ = client;
- set_format_cb_ = media::BindToCurrentLoop(WTF::BindRepeating(
+ set_format_cb_ = media::BindToCurrentLoop(WTF::Bind(
&WebAudioSourceProviderImpl::OnSetFormat, weak_factory_.GetWeakPtr()));
// If |tee_filter_| is Initialize()d - then run |set_format_cb_| to send
diff --git a/chromium/third_party/blink/renderer/platform/media_capabilities/web_audio_configuration.h b/chromium/third_party/blink/renderer/platform/media_capabilities/web_audio_configuration.h
index 0ffec904a2d..e016f7c5c9c 100644
--- a/chromium/third_party/blink/renderer/platform/media_capabilities/web_audio_configuration.h
+++ b/chromium/third_party/blink/renderer/platform/media_capabilities/web_audio_configuration.h
@@ -21,6 +21,7 @@ struct WebAudioConfiguration {
WebString channels;
base::Optional<unsigned> bitrate;
base::Optional<unsigned> samplerate;
+ base::Optional<bool> spatialRendering;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_key_system_configuration.h b/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_key_system_configuration.h
deleted file mode 100644
index 7e1c5b0bdde..00000000000
--- a/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_key_system_configuration.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_KEY_SYSTEM_CONFIGURATION_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_KEY_SYSTEM_CONFIGURATION_H_
-
-#include "media/base/eme_constants.h"
-#include "third_party/blink/public/platform/web_encrypted_media_types.h"
-#include "third_party/blink/public/platform/web_media_key_system_configuration.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-namespace blink {
-
-// Represents a MediaCapabilitiesKeySystemConfiguration dictionary to be used
-// outside of Blink. When possible, the properties will be converted from string
-// to Web types. The default values and behavior when invalid or missing is
-// specific to each property.
-struct WebMediaCapabilitiesKeySystemConfiguration {
- // This property is mandatory and should always contain a value. However, it
- // is not guaranteed that the value is valid.
- WebString key_system;
-
- // This is optional and will contain media::EmeInitDataType::UNKNOWN
- // if invalid or not present.
- media::EmeInitDataType init_data_type;
-
- // Robustness properties are optional and will contain the empty string if not
- // set. These values are not verified.
- WebString audio_robustness = "";
- WebString video_robustness = "";
-
- // These two properties are optional and will be set to
- // WebMediaKeySystemConfiguration::Requirement::kOptional if invalid or not
- // present.
- WebMediaKeySystemConfiguration::Requirement distinctive_identifier =
- WebMediaKeySystemConfiguration::Requirement::kOptional;
- WebMediaKeySystemConfiguration::Requirement persistent_state =
- WebMediaKeySystemConfiguration::Requirement::kOptional;
-
- // This is optional and will be an empty vector if not set. Each item in the
- // vector will be parsed and will be set to
- // WebEncryptedMediaSessionType::kUnknown if invalid.
- WebVector<WebEncryptedMediaSessionType> session_types;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_KEY_SYSTEM_CONFIGURATION_H_
diff --git a/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_decoding_configuration.h b/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_decoding_configuration.h
deleted file mode 100644
index 5495149cca7..00000000000
--- a/chromium/third_party/blink/renderer/platform/media_capabilities/web_media_decoding_configuration.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_DECODING_CONFIGURATION_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_DECODING_CONFIGURATION_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_key_system_configuration.h"
-#include "third_party/blink/renderer/platform/media_capabilities/web_media_configuration.h"
-
-namespace blink {
-
-// Represents a MediaDecodingConfiguration dictionary to be used outside of
-// Blink. The added `key_system_configuration` is optional and, if set, can be
-// assumed to match the requirements set by the specification.
-struct WebMediaDecodingConfiguration : public WebMediaConfiguration {
- WebMediaDecodingConfiguration() = default;
-
- WebMediaDecodingConfiguration(
- MediaConfigurationType type,
- base::Optional<WebAudioConfiguration> audio_configuration,
- base::Optional<WebVideoConfiguration> video_configuration,
- base::Optional<WebMediaCapabilitiesKeySystemConfiguration>
- key_system_configuration)
- : WebMediaConfiguration(type, audio_configuration, video_configuration),
- key_system_configuration(key_system_configuration) {}
-
- base::Optional<WebMediaCapabilitiesKeySystemConfiguration>
- key_system_configuration;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_CAPABILITIES_WEB_MEDIA_DECODING_CONFIGURATION_H_
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/DEPS b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
index a9bc061d605..22e08dbd4d9 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
@@ -10,6 +10,7 @@ include_rules = [
"+media/webrtc/audio_processor_controls.h",
"+third_party/blink/renderer/platform/audio",
"+third_party/blink/renderer/platform/heap",
+ "+third_party/blink/renderer/platform/peerconnection/rtc_api_name.h",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h",
"+third_party/blink/renderer/platform/scheduler/public/worker_pool.h",
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/OWNERS b/chromium/third_party/blink/renderer/platform/mediastream/OWNERS
new file mode 100644
index 00000000000..32889ccc574
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/OWNERS
@@ -0,0 +1,6 @@
+file://third_party/blink/common/mediastream/OWNERS
+
+per-file media_stream_audio_processor*=aluebs@chromium.org
+
+# TEAM: webrtc-dev@chromium.org
+# COMPONENT: Blink>GetUserMedia
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc b/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
index 841af86d4b1..d0254a6fdb1 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
@@ -13,7 +13,7 @@ namespace blink {
// static
std::unique_ptr<AecDumpAgentImpl> AecDumpAgentImpl::Create(Delegate* delegate) {
mojo::Remote<mojom::blink::AecDumpManager> manager;
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
manager.BindNewPipeAndPassReceiver());
mojo::PendingRemote<AecDumpAgent> remote;
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.h b/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.h
index 594e4c453ea..98ff285cb05 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.h
@@ -16,8 +16,8 @@
#include "base/timer/timer.h"
#include "media/base/audio_processing.h"
#include "media/webrtc/audio_processor_controls.h"
-#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/media_stream_interface.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
#include "third_party/webrtc/rtc_base/task_queue.h"
@@ -32,7 +32,7 @@ class AecDumpAgentImpl;
// of 10 ms data chunk.
// TODO(https://crbug.com/879296): Add tests. Possibly the timer update rate
// calculation code should be encapsulated in a class.
-class BLINK_PLATFORM_EXPORT AudioServiceAudioProcessorProxy
+class PLATFORM_EXPORT AudioServiceAudioProcessorProxy
: public webrtc::AudioProcessorInterface,
public AecDumpAgentImpl::Delegate {
public:
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_level_calculator.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.cc
index 369b07b0deb..085fc24988d 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_level_calculator.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_level_calculator.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h"
#include <cmath>
#include <limits>
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h
new file mode 100644
index 00000000000..1a1f97e03a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h
@@ -0,0 +1,65 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_LEVEL_CALCULATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_LEVEL_CALCULATOR_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace media {
+class AudioBus;
+}
+
+namespace blink {
+
+// This class is used by the WebRtcAudioCapturer to calculate the level of the
+// audio signal. And the audio level will be eventually used by the volume
+// animation UI.
+//
+// The algorithm used by this class is the same as how it is done in
+// third_party/webrtc/voice_engine/level_indicator.cc.
+class PLATFORM_EXPORT MediaStreamAudioLevelCalculator {
+ public:
+ // Provides thread-safe access to the current signal level. This object is
+ // intended to be passed to modules running on other threads that poll for the
+ // current signal level.
+ class PLATFORM_EXPORT Level : public base::RefCountedThreadSafe<Level> {
+ public:
+ float GetCurrent() const;
+
+ private:
+ friend class MediaStreamAudioLevelCalculator;
+ friend class base::RefCountedThreadSafe<Level>;
+
+ Level();
+ ~Level();
+
+ void Set(float level);
+
+ mutable base::Lock lock_;
+ float level_;
+ };
+
+ MediaStreamAudioLevelCalculator();
+ ~MediaStreamAudioLevelCalculator();
+
+ const scoped_refptr<Level>& level() const { return level_; }
+
+ // Scans the audio signal in |audio_bus| and computes a new signal level
+ // exposed by Level. If |assume_nonzero_energy| is true, then a completely
+ // zero'ed-out |audio_bus| will be accounted for as having a very faint,
+ // non-zero level.
+ void Calculate(const media::AudioBus& audio_bus, bool assume_nonzero_energy);
+
+ private:
+ int counter_;
+ float max_amplitude_;
+ const scoped_refptr<Level> level_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_LEVEL_CALCULATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.cc
index 86fdef71d90..32b1d403e7f 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include <stddef.h>
#include <utility>
@@ -18,7 +18,6 @@
#include "base/values.h"
#include "build/build_config.h"
#include "media/base/audio_parameters.h"
-#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/webrtc/modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
#include "third_party/webrtc/modules/audio_processing/typing_detection.h"
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h
new file mode 100644
index 00000000000..923bc2a2a47
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h
@@ -0,0 +1,136 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
+
+#include <string>
+
+#include "base/files/file.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/threading/thread_checker.h"
+#include "build/build_config.h"
+#include "media/base/audio_point.h"
+#include "media/base/audio_processing.h"
+#include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/media_stream_interface.h"
+#include "third_party/webrtc/media/base/media_channel.h"
+#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
+#include "third_party/webrtc/rtc_base/task_queue.h"
+
+namespace webrtc {
+
+class TypingDetection;
+
+}
+
+namespace blink {
+
+using webrtc::AudioProcessing;
+
+static constexpr int kAudioProcessingSampleRate =
+#if defined(OS_ANDROID)
+ AudioProcessing::kSampleRate16kHz;
+#else
+ AudioProcessing::kSampleRate48kHz;
+#endif
+
+// Simple struct with audio-processing properties.
+struct PLATFORM_EXPORT AudioProcessingProperties {
+ enum class EchoCancellationType {
+ // Echo cancellation disabled.
+ kEchoCancellationDisabled,
+ // The WebRTC-provided AEC3 echo canceller.
+ kEchoCancellationAec3,
+ // System echo canceller, for example an OS-provided or hardware echo
+ // canceller.
+ kEchoCancellationSystem
+ };
+
+ // Creates an AudioProcessingProperties object with fields initialized to
+ // their default values.
+ AudioProcessingProperties();
+ AudioProcessingProperties(const AudioProcessingProperties& other);
+ AudioProcessingProperties& operator=(const AudioProcessingProperties& other);
+
+ // Disables properties that are enabled by default.
+ void DisableDefaultProperties();
+
+ // Returns whether echo cancellation is enabled.
+ bool EchoCancellationEnabled() const;
+
+ // Returns whether WebRTC-provided echo cancellation is enabled.
+ bool EchoCancellationIsWebRtcProvided() const;
+
+ bool HasSameReconfigurableSettings(
+ const AudioProcessingProperties& other) const;
+
+ bool HasSameNonReconfigurableSettings(
+ const AudioProcessingProperties& other) const;
+
+ // Converts this struct to an equivalent media::AudioProcessingSettings.
+ // TODO(https://crbug.com/878757): Eliminate this class in favor of the media
+ // one.
+ media::AudioProcessingSettings ToAudioProcessingSettings() const;
+
+ EchoCancellationType echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationAec3;
+ bool disable_hw_noise_suppression = false;
+ bool goog_audio_mirroring = false;
+ bool goog_auto_gain_control = true;
+ bool goog_experimental_echo_cancellation =
+#if defined(OS_ANDROID)
+ false;
+#else
+ true;
+#endif
+ bool goog_typing_noise_detection = false;
+ bool goog_noise_suppression = true;
+ bool goog_experimental_noise_suppression = true;
+ bool goog_highpass_filter = true;
+ bool goog_experimental_auto_gain_control = true;
+};
+
+// Enables the typing detection with the given detector.
+PLATFORM_EXPORT void EnableTypingDetection(
+ AudioProcessing::Config* apm_config,
+ webrtc::TypingDetection* typing_detector);
+
+// Starts the echo cancellation dump in
+// |audio_processing|. |worker_queue| must be kept alive until either
+// |audio_processing| is destroyed, or
+// StopEchoCancellationDump(audio_processing) is called.
+PLATFORM_EXPORT void StartEchoCancellationDump(
+ AudioProcessing* audio_processing,
+ base::File aec_dump_file,
+ rtc::TaskQueue* worker_queue);
+
+// Stops the echo cancellation dump in |audio_processing|.
+// This method has no impact if echo cancellation dump has not been started on
+// |audio_processing|.
+PLATFORM_EXPORT void StopEchoCancellationDump(
+ AudioProcessing* audio_processing);
+
+// Enables automatic gain control with flags and optional configures.
+PLATFORM_EXPORT void ConfigAutomaticGainControl(
+ AudioProcessing::Config* apm_config,
+ bool agc_enabled,
+ bool experimental_agc_enabled,
+ bool use_hybrid_agc,
+ base::Optional<bool> hybrid_agc_use_peaks_not_rms,
+ base::Optional<int> hybrid_agc_saturation_margin,
+ base::Optional<double> compression_gain_db);
+
+PLATFORM_EXPORT void PopulateApmConfig(
+ AudioProcessing::Config* apm_config,
+ const AudioProcessingProperties& properties,
+ const base::Optional<std::string>& audio_processing_platform_config_json,
+ base::Optional<double>* gain_control_compression_gain_db);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options_test.cc
index aeb38ac0944..8dcdcd482c0 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc
index d06b19231d2..783587fdaee 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
new file mode 100644
index 00000000000..24a2227e573
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
@@ -0,0 +1,215 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_SOURCE_H_
+
+#include <limits>
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "media/base/limits.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h"
+#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+
+PLATFORM_EXPORT extern const int kFallbackAudioLatencyMs;
+
+class MediaStreamAudioTrack;
+
+// Represents a source of audio, and manages the delivery of audio data between
+// the source implementation and one or more MediaStreamAudioTracks. This is a
+// base class providing all the necessary functionality to connect tracks and
+// have audio data delivered to them. Subclasses provide the actual audio source
+// implementation (e.g., media::AudioCapturerSource), and should implement the
+// EnsureSourceIsStarted() and EnsureSourceIsStopped() methods, and call
+// SetFormat() and DeliverDataToTracks().
+//
+// This base class can be instantiated, to be used as a place-holder or a "null"
+// source of audio. This can be useful for unit testing, wherever a mock is
+// needed, and/or calls to DeliverDataToTracks() must be made at very specific
+// times.
+//
+// An instance of this class is owned by WebMediaStreamSource.
+//
+// Usage example:
+//
+// class MyAudioSource : public MediaStreamAudioSource { ... };
+//
+// WebMediaStreamSource blink_source = ...;
+// WebMediaStreamTrack blink_track = ...;
+// blink_source.setExtraData(new MyAudioSource()); // Takes ownership.
+// if (MediaStreamAudioSource::From(blink_source)
+// ->ConnectToTrack(blink_track)) {
+// LOG(INFO) << "Success!";
+// } else {
+// LOG(ERROR) << "Failed!";
+// }
+// // Regardless of whether ConnectToTrack() succeeds, there will always be a
+// // MediaStreamAudioTrack instance created.
+// CHECK(MediaStreamAudioTrack::From(blink_track));
+class PLATFORM_EXPORT MediaStreamAudioSource
+ : public WebPlatformMediaStreamSource {
+ public:
+ MediaStreamAudioSource(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool is_local_source);
+ MediaStreamAudioSource(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool is_local_source,
+ bool disable_local_echo);
+ ~MediaStreamAudioSource() override;
+
+ // Returns the MediaStreamAudioSource instance owned by the given blink
+ // |source| or null.
+ static MediaStreamAudioSource* From(const WebMediaStreamSource& source);
+
+ // Provides a weak reference to this MediaStreamAudioSource. The weak pointer
+ // may only be dereferenced on the main thread.
+ base::WeakPtr<MediaStreamAudioSource> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
+ // Returns true if the source of audio is local to the application (e.g.,
+ // microphone input or loopback audio capture) as opposed to audio being
+ // streamed-in from outside the application.
+ bool is_local_source() const { return is_local_source_; }
+
+ // Connects this source to the given |track|, creating the appropriate
+ // implementation of the content::MediaStreamAudioTrack interface, which
+ // becomes associated with and owned by |track|. Returns true if the source
+ // was successfully started.
+ bool ConnectToTrack(const WebMediaStreamTrack& track);
+
+ // Returns the current format of the audio passing through this source to the
+ // sinks. This can return invalid parameters if the source has not yet been
+ // started. This method is thread-safe.
+ media::AudioParameters GetAudioParameters() const;
+
+ // These accessors return properties that are controlled via constraints.
+ bool disable_local_echo() const { return disable_local_echo_; }
+ bool RenderToAssociatedSinkEnabled() const;
+
+ // Returns a unique class identifier. Some subclasses override and use this
+ // method to provide safe down-casting to their type.
+ virtual void* GetClassIdentifier() const;
+
+ // Returns true if the source has audio processing properties and the
+ // reconfigurable settings associated to audio processing match
+ // |selected_properties|; false otherwise.
+ bool HasSameReconfigurableSettings(
+ const blink::AudioProcessingProperties& selected_properties) const;
+
+ // Returns true if |this| and |other_source| have audio processing properties
+ // and the set of settings that cannot be reconfigured associated to these
+ // audio sources match; false otherwise.
+ bool HasSameNonReconfigurableSettings(
+ MediaStreamAudioSource* other_source) const;
+
+ // Returns the audio processing properties associated to this source if any,
+ // or nullopt otherwise.
+ virtual base::Optional<blink::AudioProcessingProperties>
+ GetAudioProcessingProperties() const {
+ return base::nullopt;
+ }
+
+ protected:
+ // Returns a new MediaStreamAudioTrack. |id| is the blink track's ID in UTF-8.
+ // Subclasses may override this to provide an extended implementation.
+ virtual std::unique_ptr<MediaStreamAudioTrack> CreateMediaStreamAudioTrack(
+ const std::string& id);
+
+ // Returns true if the source has already been started and has not yet been
+ // stopped. Otherwise, attempts to start the source and returns true if
+ // successful. While the source is running, it may provide audio on any thread
+ // by calling DeliverDataToTracks().
+ //
+ // A default no-op implementation is provided in this base class. Subclasses
+ // should override this method.
+ virtual bool EnsureSourceIsStarted();
+
+ // Stops the source and guarantees the the flow of audio data has stopped
+ // (i.e., by the time this method returns, there will be no further calls to
+ // DeliverDataToTracks() on any thread).
+ //
+ // A default no-op implementation is provided in this base class. Subclasses
+ // should override this method.
+ virtual void EnsureSourceIsStopped();
+
+ // Stops the source and start the |new_device|.
+ // A default no-op implementation is provided in this base class. Subclasses
+ // should override this method.
+ virtual void ChangeSourceImpl(const MediaStreamDevice& new_device);
+
+ // Called by subclasses to update the format of the audio passing through this
+ // source to the sinks. This may be called at any time, before or after
+ // tracks have been connected; but must be called at least once before
+ // DeliverDataToTracks(). This method is thread-safe.
+ void SetFormat(const media::AudioParameters& params);
+
+ // Called by subclasses to deliver audio data to the currently-connected
+ // tracks. This method is thread-safe.
+ void DeliverDataToTracks(const media::AudioBus& audio_bus,
+ base::TimeTicks reference_time);
+
+ // Called by subclasses when capture error occurs.
+ // Note: This can be called on any thread, and will post a task to the main
+ // thread to stop the source soon.
+ void StopSourceOnError(const std::string& why);
+
+ // Sets muted state and notifies it to all registered tracks.
+ void SetMutedState(bool state);
+
+ // Gets the TaskRunner for the main thread, for subclasses that need it.
+ base::SingleThreadTaskRunner* GetTaskRunner() const;
+
+ private:
+ // MediaStreamSource override.
+ void DoStopSource() final;
+ void DoChangeSource(const MediaStreamDevice& new_device) final;
+
+ // Removes |track| from the list of instances that get a copy of the source
+ // audio data. The "stop callback" that was provided to the track calls
+ // this.
+ void StopAudioDeliveryTo(MediaStreamAudioTrack* track);
+
+ // True if the source of audio is a local device. False if the source is
+ // remote (e.g., streamed-in from a server).
+ const bool is_local_source_;
+
+ // Properties controlled by audio constraints.
+ const bool disable_local_echo_;
+
+ // Set to true once this source has been permanently stopped.
+ bool is_stopped_;
+
+ // Manages tracks connected to this source and the audio format and data flow.
+ MediaStreamAudioDeliverer<MediaStreamAudioTrack> deliverer_;
+
+ // The task runner for main thread. Also used to check that all methods that
+ // could cause object graph or data flow changes are being called on the main
+ // thread.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ // Provides weak pointers so that MediaStreamAudioTracks won't call
+ // StopAudioDeliveryTo() if this instance dies first.
+ base::WeakPtrFactory<MediaStreamAudioSource> weak_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioSource);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_SOURCE_H_
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
index 9e18929b075..df7371c24a7 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
index 522f342eeb6..e5de09a72b2 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
@@ -10,10 +10,10 @@
#include "base/time/time.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_push_fifo.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
#include "third_party/blink/public/platform/web_audio_destination_consumer.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms.cc b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.cc
index 2c0817e1469..30dceced733 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/webrtc_uma_histograms.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
+#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
@@ -20,16 +20,16 @@ void LogUserMediaRequestResult(mojom::blink::MediaStreamRequestResult result) {
mojom::blink::MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS);
}
-void UpdateWebRTCMethodCount(WebRTCAPIName api_name) {
+void UpdateWebRTCMethodCount(RTCAPIName api_name) {
DVLOG(3) << "Incrementing WebRTC.webkitApiCount for "
<< static_cast<int>(api_name);
UMA_HISTOGRAM_ENUMERATION("WebRTC.webkitApiCount", api_name,
- WebRTCAPIName::kInvalidName);
+ RTCAPIName::kInvalidName);
PerSessionWebRTCAPIMetrics::GetInstance()->LogUsageOnlyOnce(api_name);
}
PerSessionWebRTCAPIMetrics::~PerSessionWebRTCAPIMetrics() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
// static
@@ -38,12 +38,12 @@ PerSessionWebRTCAPIMetrics* PerSessionWebRTCAPIMetrics::GetInstance() {
}
void PerSessionWebRTCAPIMetrics::IncrementStreamCounter() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
++num_streams_;
}
void PerSessionWebRTCAPIMetrics::DecrementStreamCounter() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (--num_streams_ == 0) {
ResetUsage();
}
@@ -53,15 +53,15 @@ PerSessionWebRTCAPIMetrics::PerSessionWebRTCAPIMetrics() : num_streams_(0) {
ResetUsage();
}
-void PerSessionWebRTCAPIMetrics::LogUsage(WebRTCAPIName api_name) {
+void PerSessionWebRTCAPIMetrics::LogUsage(RTCAPIName api_name) {
DVLOG(3) << "Incrementing WebRTC.webkitApiCountPerSession for "
<< static_cast<int>(api_name);
UMA_HISTOGRAM_ENUMERATION("WebRTC.webkitApiCountPerSession", api_name,
- WebRTCAPIName::kInvalidName);
+ RTCAPIName::kInvalidName);
}
-void PerSessionWebRTCAPIMetrics::LogUsageOnlyOnce(WebRTCAPIName api_name) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+void PerSessionWebRTCAPIMetrics::LogUsageOnlyOnce(RTCAPIName api_name) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!has_used_api_[static_cast<int>(api_name)]) {
has_used_api_[static_cast<int>(api_name)] = true;
LogUsage(api_name);
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h
new file mode 100644
index 00000000000..3dcc068900c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBRTC_UMA_HISTOGRAMS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBRTC_UMA_HISTOGRAMS_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_api_name.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+// Used to investigate where UserMediaRequests end up.
+// Only UserMediaRequests that do not log with LogUserMediaRequestResult
+// should call LogUserMediaRequestWithNoResult.
+//
+// Elements in this enum should not be deleted or rearranged; the only
+// permitted operation is to add new elements before
+// NUM_MEDIA_STREAM_REQUEST_WITH_NO_RESULT.
+enum MediaStreamRequestState {
+ MEDIA_STREAM_REQUEST_EXPLICITLY_CANCELLED = 0,
+ MEDIA_STREAM_REQUEST_NOT_GENERATED = 1,
+ MEDIA_STREAM_REQUEST_PENDING_MEDIA_TRACKS = 2,
+ NUM_MEDIA_STREAM_REQUEST_WITH_NO_RESULT
+};
+
+PLATFORM_EXPORT void LogUserMediaRequestWithNoResult(
+ MediaStreamRequestState state);
+PLATFORM_EXPORT void LogUserMediaRequestResult(
+ mojom::MediaStreamRequestResult result);
+
+// Helper method used to collect information about the number of times
+// different WebRTC APIs are called from JavaScript.
+//
+// This contributes to two histograms; the former is a raw count of
+// the number of times the APIs are called, and be viewed at
+// chrome://histograms/WebRTC.webkitApiCount.
+//
+// The latter is a count of the number of times the APIs are called
+// that gets incremented only once per "session" as established by the
+// PerSessionWebRTCAPIMetrics singleton below. It can be viewed at
+// chrome://histograms/WebRTC.webkitApiCountPerSession.
+PLATFORM_EXPORT void UpdateWebRTCMethodCount(RTCAPIName api_name);
+
+// A singleton that keeps track of the number of MediaStreams being
+// sent over PeerConnections. It uses the transition to zero such
+// streams to demarcate the start of a new "session". Note that this
+// is a rough approximation of sessions, as you could conceivably have
+// multiple tabs using this renderer process, and each of them using
+// PeerConnections.
+//
+// The UpdateWebRTCMethodCount function above uses this class to log a
+// metric at most once per session.
+class PLATFORM_EXPORT PerSessionWebRTCAPIMetrics {
+ public:
+ virtual ~PerSessionWebRTCAPIMetrics();
+
+ static PerSessionWebRTCAPIMetrics* GetInstance();
+
+ // Increment/decrement the number of streams being sent or received
+ // over any current PeerConnection.
+ void IncrementStreamCounter();
+ void DecrementStreamCounter();
+
+ protected:
+ friend struct base::DefaultSingletonTraits<PerSessionWebRTCAPIMetrics>;
+ friend PLATFORM_EXPORT void UpdateWebRTCMethodCount(RTCAPIName);
+
+ // Protected so that unit tests can test without this being a
+ // singleton.
+ PerSessionWebRTCAPIMetrics();
+
+ // Overridable by unit tests.
+ virtual void LogUsage(RTCAPIName api_name);
+
+ // Called by UpdateWebRTCMethodCount above. Protected rather than
+ // private so that unit tests can call it.
+ void LogUsageOnlyOnce(RTCAPIName api_name);
+
+ private:
+ void ResetUsage();
+
+ int num_streams_;
+ bool has_used_api_[static_cast<int>(RTCAPIName::kInvalidName)];
+
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(PerSessionWebRTCAPIMetrics);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBRTC_UMA_HISTOGRAMS_H_
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms_test.cc b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms_test.cc
new file mode 100644
index 00000000000..ba88908af23
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms_test.cc
@@ -0,0 +1,78 @@
+// 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 "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+
+namespace blink {
+
+class MockPerSessionWebRTCAPIMetrics : public PerSessionWebRTCAPIMetrics {
+ public:
+ MockPerSessionWebRTCAPIMetrics() {}
+
+ using PerSessionWebRTCAPIMetrics::LogUsageOnlyOnce;
+
+ MOCK_METHOD1(LogUsage, void(RTCAPIName));
+};
+
+class PerSessionWebRTCAPIMetricsTest
+ : public testing::Test,
+ public testing::WithParamInterface<RTCAPIName> {
+ public:
+ PerSessionWebRTCAPIMetricsTest() = default;
+ ~PerSessionWebRTCAPIMetricsTest() override = default;
+
+ protected:
+ MockPerSessionWebRTCAPIMetrics metrics;
+};
+
+TEST_P(PerSessionWebRTCAPIMetricsTest, NoCallOngoing) {
+ RTCAPIName api_name = GetParam();
+ EXPECT_CALL(metrics, LogUsage(api_name)).Times(1);
+ metrics.LogUsageOnlyOnce(api_name);
+}
+
+TEST_P(PerSessionWebRTCAPIMetricsTest, CallOngoing) {
+ RTCAPIName api_name = GetParam();
+ metrics.IncrementStreamCounter();
+ EXPECT_CALL(metrics, LogUsage(api_name)).Times(1);
+ metrics.LogUsageOnlyOnce(api_name);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerSessionWebRTCAPIMetricsTest,
+ PerSessionWebRTCAPIMetricsTest,
+ ::testing::ValuesIn({RTCAPIName::kGetUserMedia,
+ RTCAPIName::kGetDisplayMedia,
+ RTCAPIName::kEnumerateDevices,
+ RTCAPIName::kRTCPeerConnection}));
+
+TEST(PerSessionWebRTCAPIMetrics, NoCallOngoingMultiplePC) {
+ MockPerSessionWebRTCAPIMetrics metrics;
+ EXPECT_CALL(metrics, LogUsage(RTCAPIName::kRTCPeerConnection)).Times(1);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+}
+
+TEST(PerSessionWebRTCAPIMetrics, BeforeAfterCallMultiplePC) {
+ MockPerSessionWebRTCAPIMetrics metrics;
+ EXPECT_CALL(metrics, LogUsage(RTCAPIName::kRTCPeerConnection)).Times(1);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.IncrementStreamCounter();
+ metrics.IncrementStreamCounter();
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.DecrementStreamCounter();
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.DecrementStreamCounter();
+ EXPECT_CALL(metrics, LogUsage(RTCAPIName::kRTCPeerConnection)).Times(1);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+ metrics.LogUsageOnlyOnce(RTCAPIName::kRTCPeerConnection);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn b/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn
deleted file mode 100644
index cd2c135048e..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn
+++ /dev/null
@@ -1,15 +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.
-
-source_set("geometry_mojom_traits") {
- sources = [
- "geometry_mojom_traits.cc",
- "geometry_mojom_traits.h",
- ]
- public_deps = [
- "//third_party/blink/public:blink_headers",
- "//ui/gfx/geometry",
- "//ui/gfx/geometry/mojom:mojom_blink_headers",
- ]
-}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/DEPS b/chromium/third_party/blink/renderer/platform/mojo/DEPS
index d2be0c4703a..ee6991fbfd1 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mojo/DEPS
@@ -23,3 +23,9 @@ include_rules = [
"+third_party/blink/renderer/platform/weborigin",
"+third_party/blink/renderer/platform/wtf",
]
+
+specific_include_rules = {
+ "geometry_mojom_traits*": [
+ "+third_party/blink/renderer/platform/geometry",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
index 410098fd757..176545f7ecb 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
+++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -16,8 +16,8 @@ typemaps = [
"//third_party/blink/renderer/core/messaging/blink_transferable_message.typemap",
"//third_party/blink/renderer/modules/indexeddb/indexed_db_blink.typemap",
"//third_party/blink/renderer/platform/blob/serialized_blob.typemap",
+ "//third_party/blink/renderer/platform/cookie/canonical_cookie.typemap",
"//third_party/blink/renderer/platform/mojo/big_string.typemap",
- "//third_party/blink/renderer/platform/mojo/canonical_cookie.typemap",
"//third_party/blink/renderer/platform/mojo/fetch_api_request_headers.typemap",
"//third_party/blink/renderer/platform/mojo/geometry.typemap",
"//third_party/blink/renderer/platform/mojo/kurl.typemap",
diff --git a/chromium/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
index cde9a60e6d8..b970277f73a 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
@@ -7,12 +7,14 @@
#include "device/bluetooth/public/mojom/uuid.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace mojo {
template <>
-struct StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String> {
+struct PLATFORM_EXPORT
+ StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String> {
static const WTF::String& device_id(const WTF::String& input) {
return input;
}
@@ -22,7 +24,8 @@ struct StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String> {
};
template <>
-struct StructTraits<bluetooth::mojom::UUIDDataView, WTF::String> {
+struct PLATFORM_EXPORT
+ StructTraits<bluetooth::mojom::UUIDDataView, WTF::String> {
static const WTF::String& uuid(const WTF::String& input) { return input; }
static bool Read(bluetooth::mojom::UUIDDataView, WTF::String* output);
diff --git a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h
deleted file mode 100644
index c6d6ec8d0a4..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/canonical_cookie_mojom_traits.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_CANONICAL_COOKIE_MOJOM_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_CANONICAL_COOKIE_MOJOM_TRAITS_H_
-
-#include "base/time/time.h"
-#include "mojo/public/cpp/bindings/struct_traits.h"
-#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink-forward.h"
-#include "third_party/blink/public/platform/web_canonical_cookie.h"
-#include "third_party/blink/public/platform/web_string.h"
-
-namespace mojo {
-
-template <>
-struct PLATFORM_EXPORT StructTraits<network::mojom::CanonicalCookieDataView,
- blink::WebCanonicalCookie> {
- static WTF::String name(const blink::WebCanonicalCookie& c);
- static WTF::String value(const blink::WebCanonicalCookie& c);
- static WTF::String domain(const blink::WebCanonicalCookie& c);
- static WTF::String path(const blink::WebCanonicalCookie& c);
- static base::Time creation(const blink::WebCanonicalCookie& c);
- static base::Time expiry(const blink::WebCanonicalCookie& c);
- static base::Time last_access(const blink::WebCanonicalCookie& c);
- static bool secure(const blink::WebCanonicalCookie& c);
- static bool httponly(const blink::WebCanonicalCookie& c);
- static network::mojom::CookieSameSite site_restrictions(
- const blink::WebCanonicalCookie& c);
- static network::mojom::CookiePriority priority(
- const blink::WebCanonicalCookie& c);
-
- static bool Read(network::mojom::CanonicalCookieDataView cookie,
- blink::WebCanonicalCookie* out);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_CANONICAL_COOKIE_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap b/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap
index b557340578a..8029163748a 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap
+++ b/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap
@@ -8,10 +8,10 @@ public_headers = [
"//ui/gfx/geometry/vector3d_f.h",
"//third_party/blink/public/platform/web_float_rect.h",
"//third_party/blink/public/platform/web_float_point.h",
- "//third_party/blink/public/platform/web_float_point_3d.h",
"//third_party/blink/public/platform/web_point.h",
"//third_party/blink/public/platform/web_rect.h",
"//third_party/blink/public/platform/web_size.h",
+ "//third_party/blink/renderer/platform/geometry/float_point_3d.h",
]
traits_headers = [
"//third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h",
@@ -24,7 +24,10 @@ deps = [
]
public_deps = [
- "//third_party/blink/renderer/platform/mojo:geometry_mojom_traits",
+ "//third_party/blink/public:blink_headers",
+ "//third_party/blink/renderer/platform:geometry_mojom_traits",
+ "//ui/gfx/geometry",
+ "//ui/gfx/geometry/mojom:mojom_traits",
]
# TODO(zqzhang): ideally, gfx.mojom.Size should be mapped into ::blink::IntSize.
@@ -32,7 +35,7 @@ public_deps = [
type_mappings = [
"gfx.mojom.Point=::blink::WebPoint",
"gfx.mojom.PointF=::blink::WebFloatPoint",
- "gfx.mojom.Point3F=::blink::WebFloatPoint3D",
+ "gfx.mojom.Point3F=::blink::FloatPoint3D",
"gfx.mojom.Quaternion=::gfx::Quaternion",
"gfx.mojom.RectF=::blink::WebFloatRect",
"gfx.mojom.Rect=::blink::WebRect",
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc
index 851463222de..29128e0055d 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc
@@ -50,12 +50,12 @@ bool StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint>::Read(
return true;
}
-bool StructTraits<gfx::mojom::Point3FDataView, ::blink::WebFloatPoint3D>::Read(
+bool StructTraits<gfx::mojom::Point3FDataView, ::blink::FloatPoint3D>::Read(
gfx::mojom::Point3FDataView data,
- ::blink::WebFloatPoint3D* out) {
- out->x = data.x();
- out->y = data.y();
- out->z = data.z();
+ ::blink::FloatPoint3D* out) {
+ out->SetX(data.x());
+ out->SetY(data.y());
+ out->SetZ(data.z());
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h
index bc7c409c95d..eb16fc06bb1 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h
@@ -6,12 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_MOJOM_TRAITS_H_
#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_point_3d.h"
#include "third_party/blink/public/platform/web_float_rect.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 "ui/gfx/geometry/mojom/geometry.mojom-blink.h"
+#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
+#include "ui/gfx/geometry/mojom/geometry.mojom-shared.h"
namespace mojo {
@@ -30,12 +30,12 @@ struct StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint> {
};
template <>
-struct StructTraits<gfx::mojom::Point3FDataView, ::blink::WebFloatPoint3D> {
+struct StructTraits<gfx::mojom::Point3FDataView, ::blink::FloatPoint3D> {
static float x(const gfx::Point3F& p) { return p.x(); }
static float y(const gfx::Point3F& p) { return p.y(); }
static float z(const gfx::Point3F& p) { return p.z(); }
static bool Read(gfx::mojom::Point3FDataView data,
- ::blink::WebFloatPoint3D* out);
+ ::blink::FloatPoint3D* out);
};
template <>
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc
index 7ae4b572773..0c1d8a69650 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc
@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "ui/gfx/geometry/mojom/geometry.mojom-blink.h"
#include "ui/gfx/geometry/mojom/geometry_traits_test_service.mojom-blink.h"
@@ -40,7 +41,7 @@ class GeometryStructTraitsTest
std::move(callback).Run(p);
}
- void EchoPoint3F(const WebFloatPoint3D& p,
+ void EchoPoint3F(const FloatPoint3D& p,
EchoPoint3FCallback callback) override {
std::move(callback).Run(p);
}
@@ -142,10 +143,10 @@ TEST_F(GeometryStructTraitsTest, Point3D) {
const float kX = 1.234;
const float kY = 5.678;
const float kZ = 9.098;
- WebFloatPoint3D input(kX, kY, kZ);
+ FloatPoint3D input(kX, kY, kZ);
mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
GetTraitsTestProxy();
- WebFloatPoint3D output;
+ FloatPoint3D output;
proxy->EchoPoint3F(input, &output);
EXPECT_EQ(input, output);
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc b/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
index 408d26185e8..b9f7c73fd27 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
@@ -79,7 +79,7 @@ TEST(KURLSecurityOriginStructTraitsTest, Basic) {
SecurityOrigin::Create("http", "www.google.com", 80);
scoped_refptr<const SecurityOrigin> output;
EXPECT_TRUE(proxy->BounceOrigin(non_unique, &output));
- EXPECT_TRUE(non_unique->IsSameSchemeHostPort(output.get()));
+ EXPECT_TRUE(non_unique->IsSameOriginWith(output.get()));
EXPECT_FALSE(output->IsOpaque());
scoped_refptr<const SecurityOrigin> unique =
diff --git a/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
index 762af709982..386bc631ecd 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_MOJOM_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_MOJOM_TRAITS_H_
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "url/mojom/origin.mojom-blink-forward.h"
@@ -22,9 +23,13 @@ struct UrlOriginAdapter {
const base::Optional<base::UnguessableToken>& nonce_if_opaque) {
scoped_refptr<blink::SecurityOrigin> tuple_origin;
if (!tuple.IsInvalid()) {
+ // url::SchemeHostPort is percent encoded and SecurityOrigin is percent
+ // decoded.
+ String host = blink::DecodeURLEscapeSequences(
+ String::FromUTF8(tuple.host()),
+ url::DecodeURLMode::kUTF8OrIsomorphic);
tuple_origin = blink::SecurityOrigin::Create(
- String::FromUTF8(tuple.scheme()), String::FromUTF8(tuple.host()),
- tuple.port());
+ String::FromUTF8(tuple.scheme()), host, tuple.port());
}
if (nonce_if_opaque) {
diff --git a/chromium/third_party/blink/renderer/platform/network/DEPS b/chromium/third_party/blink/renderer/platform/network/DEPS
index e678379bc8a..d89e72da0dd 100644
--- a/chromium/third_party/blink/renderer/platform/network/DEPS
+++ b/chromium/third_party/blink/renderer/platform/network/DEPS
@@ -13,8 +13,6 @@ include_rules = [
"+net/base",
"+net/http",
"+net/nqe",
- # For URLRequestDataJob::BuildResponse().
- "+net/url_request/url_request_data_job.h",
"+services/network/public/cpp/features.h",
"+third_party/blink/renderer/platform/blob/blob_data.h",
diff --git a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
index 44c66028918..3d106e98802 100644
--- a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
+++ b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
-#include "third_party/blink/public/mojom/csp/content_security_policy.mojom-blink.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
@@ -58,16 +58,16 @@ bool IsMediaTypeCharacter(UChar c) {
return !IsASCIISpace(c) && c != '/';
}
-STATIC_ASSERT_ENUM(mojom::ContentSecurityPolicyType::kReport,
+STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kReport,
kContentSecurityPolicyHeaderTypeReport);
-STATIC_ASSERT_ENUM(mojom::ContentSecurityPolicyType::kEnforce,
+STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kEnforce,
kContentSecurityPolicyHeaderTypeEnforce);
-STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceHTTP,
+STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kHTTP,
kContentSecurityPolicyHeaderSourceHTTP);
-STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceMeta,
+STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kMeta,
kContentSecurityPolicyHeaderSourceMeta);
-STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceOriginPolicy,
+STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kOriginPolicy,
kContentSecurityPolicyHeaderSourceOriginPolicy);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
index 1b660e6ffc9..03a6c6d3aac 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
@@ -40,10 +40,11 @@ bool FormDataElement::IsSafeToSendToAnotherThread() const {
blob_uuid_.IsSafeToSendToAnotherThread();
}
-FormDataElement::FormDataElement(const String& filename,
- int64_t file_start,
- int64_t file_length,
- double expected_file_modification_time)
+FormDataElement::FormDataElement(
+ const String& filename,
+ int64_t file_start,
+ int64_t file_length,
+ const base::Optional<base::Time>& expected_file_modification_time)
: type_(kEncodedFile),
filename_(filename),
file_start_(file_start),
@@ -176,13 +177,14 @@ void EncodedFormData::AppendData(const void* data, wtf_size_t size) {
void EncodedFormData::AppendFile(const String& filename) {
elements_.push_back(
- FormDataElement(filename, 0, BlobData::kToEndOfFile, InvalidFileTime()));
+ FormDataElement(filename, 0, BlobData::kToEndOfFile, base::nullopt));
}
-void EncodedFormData::AppendFileRange(const String& filename,
- int64_t start,
- int64_t length,
- double expected_modification_time) {
+void EncodedFormData::AppendFileRange(
+ const String& filename,
+ int64_t start,
+ int64_t length,
+ const base::Optional<base::Time>& expected_modification_time) {
elements_.push_back(
FormDataElement(filename, start, length, expected_modification_time));
}
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
index 865f664dd07..a3de079f0ce 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
@@ -29,6 +29,8 @@
#include <utility>
+#include "base/optional.h"
+#include "base/time/time.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -52,10 +54,11 @@ class PLATFORM_EXPORT FormDataElement final {
public:
FormDataElement();
explicit FormDataElement(const Vector<char>&);
- FormDataElement(const String& filename,
- int64_t file_start,
- int64_t file_length,
- double expected_file_modification_time);
+ FormDataElement(
+ const String& filename,
+ int64_t file_start,
+ int64_t file_length,
+ const base::Optional<base::Time>& expected_file_modification_time);
FormDataElement(const String& blob_uuid,
scoped_refptr<BlobDataHandle> optional_handle);
explicit FormDataElement(scoped_refptr<WrappedDataPipeGetter>);
@@ -77,7 +80,7 @@ class PLATFORM_EXPORT FormDataElement final {
scoped_refptr<BlobDataHandle> optional_blob_data_handle_;
int64_t file_start_;
int64_t file_length_;
- double expected_file_modification_time_;
+ base::Optional<base::Time> expected_file_modification_time_;
scoped_refptr<WrappedDataPipeGetter> data_pipe_getter_;
};
@@ -108,10 +111,11 @@ class PLATFORM_EXPORT EncodedFormData : public RefCounted<EncodedFormData> {
void AppendData(const void* data, wtf_size_t);
void AppendFile(const String& file_path);
- void AppendFileRange(const String& filename,
- int64_t start,
- int64_t length,
- double expected_modification_time);
+ void AppendFileRange(
+ const String& filename,
+ int64_t start,
+ int64_t length,
+ const base::Optional<base::Time>& expected_modification_time);
void AppendBlob(const String& blob_uuid,
scoped_refptr<BlobDataHandle> optional_handle);
void AppendDataPipe(scoped_refptr<WrappedDataPipeGetter> handle);
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
index 0df4fbecb5a..4807a6de7a7 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
@@ -17,6 +17,7 @@
#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
@@ -100,7 +101,7 @@ base::Time StructTraits<blink::mojom::FetchAPIDataElementDataView,
blink::FormDataElement>::
expected_modification_time(const blink::FormDataElement& data) {
if (data.type_ == blink::FormDataElement::kEncodedFile)
- return base::Time::FromDoubleT(data.expected_file_modification_time_);
+ return data.expected_file_modification_time_.value_or(base::Time());
return base::Time();
}
@@ -136,9 +137,11 @@ bool StructTraits<blink::mojom::FetchAPIDataElementDataView,
!data.ReadExpectedModificationTime(&expected_time)) {
return false;
}
- out->expected_file_modification_time_ = expected_time.ToDoubleT();
- out->filename_ =
- WTF::String(file_path.value().data(), file_path.value().size());
+ if (expected_time.is_null())
+ out->expected_file_modification_time_ = base::nullopt;
+ else
+ out->expected_file_modification_time_ = expected_time;
+ out->filename_ = blink::FilePathToString(file_path);
break;
}
case network::mojom::DataElementType::kDataPipe: {
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
index 461380f721c..4cbe801e38c 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
@@ -57,7 +57,8 @@ class EncodedFormDataMojomTraitsTest : public testing::Test {
TEST_F(EncodedFormDataTest, DeepCopy) {
scoped_refptr<EncodedFormData> original(EncodedFormData::Create());
original->AppendData("Foo", 3);
- original->AppendFileRange("example.txt", 12345, 56789, 9999.0);
+ original->AppendFileRange("example.txt", 12345, 56789,
+ base::Time::FromDoubleT(9999.0));
original->AppendBlob("originalUUID", nullptr);
Vector<char> boundary_vector;
@@ -83,7 +84,8 @@ TEST_F(EncodedFormDataTest, DeepCopy) {
EXPECT_EQ(String("example.txt"), copy_elements[1].filename_);
EXPECT_EQ(12345ll, copy_elements[1].file_start_);
EXPECT_EQ(56789ll, copy_elements[1].file_length_);
- EXPECT_EQ(9999.0, copy_elements[1].expected_file_modification_time_);
+ EXPECT_EQ(9999.0,
+ copy_elements[1].expected_file_modification_time_->ToDoubleT());
EXPECT_EQ(FormDataElement::kEncodedBlob, copy_elements[2].type_);
EXPECT_EQ(String("originalUUID"), copy_elements[2].blob_uuid_);
@@ -131,7 +133,7 @@ TEST_F(EncodedFormDataMojomTraitsTest, Roundtrips_FormDataElement) {
original2.file_start_ = 0;
original2.file_length_ = 4;
original2.filename_ = "file.name";
- original2.expected_file_modification_time_ = base::Time::Now().ToDoubleT();
+ original2.expected_file_modification_time_ = base::Time::Now();
FormDataElement copied2;
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
blink::mojom::blink::FetchAPIDataElement>(&original2, &copied2));
diff --git a/chromium/third_party/blink/renderer/platform/network/http_parsers.cc b/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
index 4e7f8a25eff..9c376f04607 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
+++ b/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -497,10 +498,13 @@ bool ParseMultipartHeadersFromBody(const char* bytes,
size_t iterator = 0;
response->ClearHttpHeaderField(header);
+ Vector<AtomicString> values;
while (response_headers->EnumerateHeader(&iterator, header_string_piece,
&value)) {
- response->AddHttpHeaderField(header, WebString::FromLatin1(value));
+ const AtomicString atomic_value = WebString::FromLatin1(value);
+ values.push_back(atomic_value);
}
+ response->AddHttpHeaderFieldWithMultipleValues(header, values);
}
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/network/http_parsers_test.cc b/chromium/third_party/blink/renderer/platform/network/http_parsers_test.cc
index feee0ce34f6..1cf4dded67d 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_parsers_test.cc
+++ b/chromium/third_party/blink/renderer/platform/network/http_parsers_test.cc
@@ -320,8 +320,14 @@ TEST(HTTPParsersTest, ParseMultipartHeaders) {
response.AddHttpHeaderField("foo", "bar");
response.AddHttpHeaderField("range", "piyo");
response.AddHttpHeaderField("content-length", "999");
-
- const char kData[] = "content-type: image/png\ncontent-length: 10\n\n";
+ response.AddHttpHeaderField("set-cookie", "a=1");
+
+ const char kData[] =
+ "content-type: image/png\n"
+ "content-length: 10\n"
+ "set-cookie: x=2\n"
+ "set-cookie: y=3\n"
+ "\n";
wtf_size_t end = 0;
bool result =
ParseMultipartHeadersFromBody(kData, strlen(kData), &response, &end);
@@ -332,6 +338,7 @@ TEST(HTTPParsersTest, ParseMultipartHeaders) {
EXPECT_EQ("10", response.HttpHeaderField("content-length"));
EXPECT_EQ("bar", response.HttpHeaderField("foo"));
EXPECT_EQ(AtomicString(), response.HttpHeaderField("range"));
+ EXPECT_EQ("x=2, y=3", response.HttpHeaderField("set-cookie"));
}
TEST(HTTPParsersTest, ParseMultipartHeadersContentCharset) {
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
index 5547c546623..9f56c4b2da6 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
+++ b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
@@ -114,6 +114,10 @@ bool MIMETypeRegistry::IsSupportedJavaScriptMIMEType(const String& mime_type) {
return blink::IsSupportedJavascriptMimeType(ToLowerASCIIOrEmpty(mime_type));
}
+bool MIMETypeRegistry::IsJSONMimeType(const String& mime_type) {
+ return blink::IsJSONMimeType(ToLowerASCIIOrEmpty(mime_type));
+}
+
bool MIMETypeRegistry::IsLegacySupportedJavaScriptLanguage(
const String& language) {
// Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
index 9cf2888df44..8d8eb216769 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
+++ b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
@@ -68,6 +68,9 @@ class PLATFORM_EXPORT MIMETypeRegistry {
// resource.
static bool IsSupportedJavaScriptMIMEType(const String& mime_type);
+ // https://mimesniff.spec.whatwg.org/#json-mime-type
+ static bool IsJSONMimeType(const String& mime_type);
+
static bool IsLegacySupportedJavaScriptLanguage(const String& language);
// Checks to see if a non-image mime type is suitable for being loaded as a
diff --git a/chromium/third_party/blink/renderer/platform/network/network_utils.cc b/chromium/third_party/blink/renderer/platform/network/network_utils.cc
index 58197a65fc3..7cd2d356989 100644
--- a/chromium/third_party/blink/renderer/platform/network/network_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/network/network_utils.cc
@@ -11,7 +11,6 @@
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
-#include "net/url_request/url_request_data_job.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
@@ -75,11 +74,11 @@ std::tuple<int, ResourceResponse, scoped_refptr<SharedBuffer>> ParseDataURL(
std::string utf8_mime_type;
std::string utf8_charset;
std::string data_string;
- auto headers = base::MakeRefCounted<net::HttpResponseHeaders>(std::string());
+ scoped_refptr<net::HttpResponseHeaders> headers;
- int result = net::URLRequestDataJob::BuildResponse(
- GURL(url), method.Ascii(), &utf8_mime_type, &utf8_charset, &data_string,
- headers.get());
+ net::Error result =
+ net::DataURL::BuildResponse(GURL(url), method.Ascii(), &utf8_mime_type,
+ &utf8_charset, &data_string, &headers);
if (result != net::OK)
return std::make_tuple(result, ResourceResponse(), nullptr);
@@ -102,13 +101,18 @@ std::tuple<int, ResourceResponse, scoped_refptr<SharedBuffer>> ParseDataURL(
return std::make_tuple(net::OK, std::move(response), std::move(buffer));
}
-bool IsDataURLMimeTypeSupported(const KURL& url, std::string* data) {
+bool IsDataURLMimeTypeSupported(const KURL& url,
+ std::string* data,
+ std::string* mime_type) {
std::string utf8_mime_type;
std::string utf8_charset;
- if (net::DataURL::Parse(GURL(url), &utf8_mime_type, &utf8_charset, data)) {
- return blink::IsSupportedMimeType(utf8_mime_type);
- }
- return false;
+ if (!net::DataURL::Parse(GURL(url), &utf8_mime_type, &utf8_charset, data))
+ return false;
+ if (!blink::IsSupportedMimeType(utf8_mime_type))
+ return false;
+ if (mime_type)
+ utf8_mime_type.swap(*mime_type);
+ return true;
}
bool IsRedirectResponseCode(int response_code) {
diff --git a/chromium/third_party/blink/renderer/platform/network/network_utils.h b/chromium/third_party/blink/renderer/platform/network/network_utils.h
index 7c314e3f986..23220caec85 100644
--- a/chromium/third_party/blink/renderer/platform/network/network_utils.h
+++ b/chromium/third_party/blink/renderer/platform/network/network_utils.h
@@ -38,8 +38,10 @@ ParseDataURL(const KURL&, const String& method);
// Returns true if the URL is a data URL and its MIME type is in the list of
// supported/recognized MIME types.
-PLATFORM_EXPORT bool IsDataURLMimeTypeSupported(const KURL&,
- std::string* data = nullptr);
+PLATFORM_EXPORT bool IsDataURLMimeTypeSupported(
+ const KURL&,
+ std::string* data = nullptr,
+ std::string* mime_type = nullptr);
PLATFORM_EXPORT bool IsRedirectResponseCode(int);
diff --git a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
index f9dc5f61c8a..1bc21566bab 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
+++ b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
@@ -9,8 +9,8 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
-#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/renderer/platform/p2p/network_manager_uma.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/rtc_base/network.h"
#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
#include "url/gurl.h"
@@ -32,23 +32,22 @@ namespace blink {
// to reduce any extra call setup delay. This class is not thread safe and
// should only be used by WebRTC's network thread. It inherits from
// rtc::NetworkManagerBase to have the same implementation of
-// GetAnyAddressNetworks(). We can't mark the whole class BLINK_PLATFORM_EXPORT
-// as it requires all super classes to be BLINK_PLATFORM_EXPORT as well.
+// GetAnyAddressNetworks(). We can't mark the whole class PLATFORM_EXPORT
+// as it requires all super classes to be PLATFORM_EXPORT as well.
//
-// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
-// all users of it have been Onion souped. Also, move it away from url/gurl.h.
+// TODO(crbug.com/787254): Also, move it away from url/gurl.h.
class FilteringNetworkManager : public rtc::NetworkManagerBase,
public sigslot::has_slots<> {
public:
// This class is created by WebRTC's signaling thread but used by WebRTC's
// worker thread |task_runner|.
- BLINK_PLATFORM_EXPORT FilteringNetworkManager(
+ PLATFORM_EXPORT FilteringNetworkManager(
rtc::NetworkManager* network_manager,
const GURL& requesting_origin,
media::MediaPermission* media_permission,
bool allow_mdns_obfuscation);
- BLINK_PLATFORM_EXPORT ~FilteringNetworkManager() override;
+ PLATFORM_EXPORT ~FilteringNetworkManager() override;
// rtc::NetworkManager:
void Initialize() override;
diff --git a/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc b/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
index c2ecba2cd67..eca457b7ee7 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
@@ -35,7 +35,7 @@ void P2PAsyncAddressResolver::Start(const rtc::SocketAddress& host_name,
done_callback_ = std::move(done_callback);
bool enable_mdns = base::FeatureList::IsEnabled(
blink::features::kWebRtcHideLocalIpsWithMdns);
- dispatcher_->GetP2PSocketManager()->get()->GetHostAddress(
+ dispatcher_->GetP2PSocketManager()->GetHostAddress(
String(host_name.hostname().data()), enable_mdns,
base::BindOnce(&P2PAsyncAddressResolver::OnResponse,
base::Unretained(this)));
diff --git a/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc b/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
index ae1a35be488..ffb14185658 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
@@ -46,7 +46,7 @@ MdnsResponderAdapter::MdnsResponderAdapter() {
shared_remote_client_ =
mojo::SharedRemote<network::mojom::blink::MdnsResponder>(
std::move(client));
- blink::Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ blink::Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
std::move(receiver));
}
diff --git a/chromium/third_party/blink/renderer/platform/p2p/port_allocator.cc b/chromium/third_party/blink/renderer/platform/p2p/port_allocator.cc
new file mode 100644
index 00000000000..fe4922018bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/p2p/port_allocator.cc
@@ -0,0 +1,60 @@
+// 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 "third_party/blink/renderer/platform/p2p/port_allocator.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
+
+namespace blink {
+
+P2PPortAllocator::P2PPortAllocator(
+ const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher,
+ std::unique_ptr<rtc::NetworkManager> network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const Config& config,
+ const GURL& origin)
+ : cricket::BasicPortAllocator(network_manager.get(), socket_factory),
+ network_manager_(std::move(network_manager)),
+ socket_dispatcher_(socket_dispatcher),
+ config_(config),
+ origin_(origin) {
+ DCHECK(socket_dispatcher);
+ DCHECK(network_manager_);
+ DCHECK(socket_factory);
+ uint32_t flags = 0;
+ if (!config_.enable_multiple_routes) {
+ flags |= cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION;
+ }
+ if (!config_.enable_default_local_candidate) {
+ flags |= cricket::PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE;
+ }
+ if (!config_.enable_nonproxied_udp) {
+ flags |= cricket::PORTALLOCATOR_DISABLE_UDP |
+ cricket::PORTALLOCATOR_DISABLE_STUN |
+ cricket::PORTALLOCATOR_DISABLE_UDP_RELAY;
+ }
+ set_flags(flags);
+ set_allow_tcp_listen(false);
+ bool enable_webrtc_stun_origin =
+ Platform::Current()->IsWebRtcStunOriginEnabled();
+ if (enable_webrtc_stun_origin) {
+ set_origin(origin_.spec());
+ }
+}
+
+P2PPortAllocator::~P2PPortAllocator() {}
+
+void P2PPortAllocator::Initialize() {
+ BasicPortAllocator::Initialize();
+ network_manager_->Initialize();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/p2p/port_allocator.h b/chromium/third_party/blink/renderer/platform/p2p/port_allocator.h
new file mode 100644
index 00000000000..1703c230399
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/p2p/port_allocator.h
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_P2P_PORT_ALLOCATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_P2P_PORT_ALLOCATOR_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/p2p/client/basic_port_allocator.h"
+#include "url/gurl.h"
+
+namespace blink {
+
+class P2PSocketDispatcher;
+
+class PLATFORM_EXPORT P2PPortAllocator : public cricket::BasicPortAllocator {
+ public:
+ struct Config {
+ // Enable non-proxied UDP-based transport when set to true. When set to
+ // false, it effectively disables all UDP traffic until UDP-supporting proxy
+ // RETURN is available in the future.
+ bool enable_nonproxied_udp = true;
+
+ // Request binding to individual NICs. Whether multiple routes is allowed is
+ // subject to the permission check on mic/camera. When specified as false or
+ // the permission request is denied, it still uses the default local address
+ // to generate a single local candidate. TODO(guoweis): Rename this to
+ // |request_multiple_routes|.
+ bool enable_multiple_routes = true;
+
+ // Enable exposing the default local address when set to true. This is
+ // only in effect when the |enable_multiple_routes| is false or the
+ // permission check of mic/camera is denied.
+ bool enable_default_local_candidate = true;
+ };
+
+ P2PPortAllocator(const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher,
+ std::unique_ptr<rtc::NetworkManager> network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const Config& config,
+ const GURL& origin);
+ ~P2PPortAllocator() override;
+
+ // Will also initialize the network manager passed into the constructor.
+ void Initialize() override;
+
+ private:
+ std::unique_ptr<rtc::NetworkManager> network_manager_;
+ scoped_refptr<P2PSocketDispatcher> socket_dispatcher_;
+ Config config_;
+ GURL origin_;
+
+ DISALLOW_COPY_AND_ASSIGN(P2PPortAllocator);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_P2P_PORT_ALLOCATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
index 65a89454e60..cbf7777bd9d 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
@@ -34,8 +34,7 @@ P2PSocketClientImpl::P2PSocketClientImpl(
state_(STATE_UNINITIALIZED),
traffic_annotation_(traffic_annotation),
random_socket_id_(0),
- next_packet_id_(0),
- binding_(this) {
+ next_packet_id_(0) {
crypto::RandBytes(&random_socket_id_, sizeof(random_socket_id_));
}
@@ -57,13 +56,12 @@ void P2PSocketClientImpl::Init(
DCHECK_EQ(state_, STATE_UNINITIALIZED);
state_ = STATE_OPENING;
- network::mojom::blink::P2PSocketClientPtr socket_client;
- binding_.Bind(mojo::MakeRequest(&socket_client));
- binding_.set_connection_error_handler(base::BindOnce(
- &P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
- dispatcher_->GetP2PSocketManager()->get()->CreateSocket(
+ dispatcher_->GetP2PSocketManager()->CreateSocket(
type, local_address, network::P2PPortRange(min_port, max_port),
- remote_address, std::move(socket_client), mojo::MakeRequest(&socket_));
+ remote_address, receiver_.BindNewPipeAndPassRemote(),
+ socket_.BindNewPipeAndPassReceiver());
+ receiver_.set_disconnect_handler(base::BindOnce(
+ &P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
}
uint64_t P2PSocketClientImpl::Send(const net::IPEndPoint& address,
@@ -134,18 +132,18 @@ void P2PSocketClientImpl::SendComplete(
void P2PSocketClientImpl::IncomingTcpConnection(
const net::IPEndPoint& socket_address,
- network::mojom::blink::P2PSocketPtr socket,
- network::mojom::blink::P2PSocketClientRequest client_request) {
+ mojo::PendingRemote<network::mojom::blink::P2PSocket> socket,
+ mojo::PendingReceiver<network::mojom::blink::P2PSocketClient>
+ client_receiver) {
DCHECK_EQ(state_, STATE_OPEN);
auto new_client =
std::make_unique<P2PSocketClientImpl>(dispatcher_, traffic_annotation_);
new_client->state_ = STATE_OPEN;
- network::mojom::blink::P2PSocketClientPtr socket_client;
- new_client->socket_ = std::move(socket);
- new_client->binding_.Bind(std::move(client_request));
- new_client->binding_.set_connection_error_handler(base::BindOnce(
+ new_client->socket_.Bind(std::move(socket));
+ new_client->receiver_.Bind(std::move(client_receiver));
+ new_client->receiver_.set_disconnect_handler(base::BindOnce(
&P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.h b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.h
index 080c3fa5c8e..a04db9a1f1a 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.h
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.h
@@ -10,7 +10,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/ip_endpoint.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/p2p_socket_type.h"
@@ -88,8 +91,9 @@ class P2PSocketClientImpl : public blink::P2PSocketClient,
void SendComplete(const network::P2PSendPacketMetrics& send_metrics) override;
void IncomingTcpConnection(
const net::IPEndPoint& socket_address,
- network::mojom::blink::P2PSocketPtr socket,
- network::mojom::blink::P2PSocketClientRequest client_request) override;
+ mojo::PendingRemote<network::mojom::blink::P2PSocket> socket,
+ mojo::PendingReceiver<network::mojom::blink::P2PSocketClient>
+ client_receiver) override;
void DataReceived(const net::IPEndPoint& socket_address,
const Vector<int8_t>& data,
base::TimeTicks timestamp) override;
@@ -107,8 +111,8 @@ class P2PSocketClientImpl : public blink::P2PSocketClient,
uint32_t random_socket_id_;
uint32_t next_packet_id_;
- network::mojom::blink::P2PSocketPtr socket_;
- mojo::Binding<network::mojom::blink::P2PSocketClient> binding_;
+ mojo::Remote<network::mojom::blink::P2PSocket> socket_;
+ mojo::Receiver<network::mojom::blink::P2PSocketClient> receiver_{this};
DISALLOW_COPY_AND_ASSIGN(P2PSocketClientImpl);
};
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
index c82473ef536..370e34ed1ac 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
@@ -35,22 +35,26 @@ void P2PSocketDispatcher::RemoveNetworkListObserver(
network_list_observers_->RemoveObserver(network_list_observer);
}
-scoped_refptr<network::mojom::blink::ThreadSafeP2PSocketManagerPtr>
+network::mojom::blink::P2PSocketManager*
P2PSocketDispatcher::GetP2PSocketManager() {
base::AutoLock lock(p2p_socket_manager_lock_);
- if (!thread_safe_p2p_socket_manager_) {
- network::mojom::blink::P2PSocketManagerPtr p2p_socket_manager;
- p2p_socket_manager_request_ = mojo::MakeRequest(&p2p_socket_manager);
- p2p_socket_manager.set_connection_error_handler(base::BindOnce(
- &P2PSocketDispatcher::OnConnectionError, base::Unretained(this)));
- thread_safe_p2p_socket_manager_ =
- network::mojom::blink::ThreadSafeP2PSocketManagerPtr::Create(
+ if (!p2p_socket_manager_) {
+ mojo::PendingRemote<network::mojom::blink::P2PSocketManager>
+ p2p_socket_manager;
+ p2p_socket_manager_receiver_ =
+ p2p_socket_manager.InitWithNewPipeAndPassReceiver();
+ p2p_socket_manager_ =
+ mojo::SharedRemote<network::mojom::blink::P2PSocketManager>(
std::move(p2p_socket_manager));
+ p2p_socket_manager_.set_disconnect_handler(
+ base::BindOnce(&P2PSocketDispatcher::OnConnectionError,
+ base::Unretained(this)),
+ main_task_runner_);
}
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary, this));
- return thread_safe_p2p_socket_manager_;
+ return p2p_socket_manager_.get();
}
void P2PSocketDispatcher::NetworkListChanged(
@@ -75,11 +79,11 @@ void P2PSocketDispatcher::NetworkListChanged(
}
void P2PSocketDispatcher::RequestInterfaceIfNecessary() {
- if (!p2p_socket_manager_request_.is_pending())
+ if (!p2p_socket_manager_receiver_.is_valid())
return;
- blink::Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
- std::move(p2p_socket_manager_request_));
+ blink::Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
+ std::move(p2p_socket_manager_receiver_));
}
void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
@@ -96,14 +100,14 @@ void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
std::move(copy), default_ipv4_local_address_,
default_ipv6_local_address_);
} else {
- GetP2PSocketManager()->get()->StartNetworkNotifications(
+ GetP2PSocketManager()->StartNetworkNotifications(
network_notification_client_receiver_.BindNewPipeAndPassRemote());
}
}
void P2PSocketDispatcher::OnConnectionError() {
base::AutoLock lock(p2p_socket_manager_lock_);
- thread_safe_p2p_socket_manager_.reset();
+ p2p_socket_manager_.reset();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.h b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
index 53423773df6..de9b6690e0b 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
@@ -29,7 +29,9 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
#include "base/synchronization/lock.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/shared_remote.h"
#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
#include "net/base/ip_address.h"
#include "net/base/network_interfaces.h"
@@ -64,8 +66,7 @@ class PLATFORM_EXPORT P2PSocketDispatcher
void RemoveNetworkListObserver(
blink::NetworkListObserver* network_list_observer) override;
- scoped_refptr<network::mojom::blink::ThreadSafeP2PSocketManagerPtr>
- GetP2PSocketManager();
+ network::mojom::blink::P2PSocketManager* GetP2PSocketManager();
private:
friend class base::RefCountedThreadSafe<P2PSocketDispatcher>;
@@ -90,9 +91,10 @@ class PLATFORM_EXPORT P2PSocketDispatcher
scoped_refptr<base::ObserverListThreadSafe<blink::NetworkListObserver>>
network_list_observers_;
- network::mojom::blink::P2PSocketManagerRequest p2p_socket_manager_request_;
- scoped_refptr<network::mojom::blink::ThreadSafeP2PSocketManagerPtr>
- thread_safe_p2p_socket_manager_;
+ mojo::PendingReceiver<network::mojom::blink::P2PSocketManager>
+ p2p_socket_manager_receiver_;
+ mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
+ p2p_socket_manager_;
base::Lock p2p_socket_manager_lock_;
// Cached from last |NetworkListChanged| call.
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/DEPS b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
index 27851784cbb..705fa3fe2c3 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
@@ -6,6 +6,7 @@ include_rules = [
"+third_party/blink/renderer/platform/p2p",
"+third_party/blink/renderer/platform/peerconnection",
"+third_party/blink/renderer/platform/media_capabilities",
+ "+third_party/blink/renderer/platform/mediastream",
"+third_party/blink/renderer/platform/webrtc",
# Dependencies.
@@ -27,6 +28,7 @@ include_rules = [
specific_include_rules = {
".*_test\.cc": [
+ "+base/task/task_traits.h",
"+base/threading/thread.h",
"+gpu/command_buffer/common/mailbox.h",
"+media/video/mock_gpu_video_accelerator_factories.h",
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.cc b/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.cc
index abbae4c11b1..0165a9bd17c 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/peerconnection/audio_codec_factory.h"
+#include "third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h"
#include <memory>
#include <vector>
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h b/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h
new file mode 100644
index 00000000000..a528ac82910
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h
@@ -0,0 +1,23 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_AUDIO_CODEC_FACTORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_AUDIO_CODEC_FACTORY_H_
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/audio_codecs/audio_decoder_factory.h"
+#include "third_party/webrtc/api/audio_codecs/audio_encoder_factory.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
+
+namespace blink {
+
+PLATFORM_EXPORT rtc::scoped_refptr<webrtc::AudioEncoderFactory>
+CreateWebrtcAudioEncoderFactory();
+
+PLATFORM_EXPORT rtc::scoped_refptr<webrtc::AudioDecoderFactory>
+CreateWebrtcAudioDecoderFactory();
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_AUDIO_CODEC_FACTORY_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h
new file mode 100644
index 00000000000..2453e23844f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h
@@ -0,0 +1,28 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_API_NAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_API_NAME_H_
+
+namespace blink {
+
+// Helper enum used for histogramming calls to WebRTC APIs from JavaScript.
+// The entries are linked to UMA values in //tools/metrics/histograms/enums.xml
+// and shouldn't be renumbered or removed.
+enum class RTCAPIName {
+ kGetUserMedia,
+ kPeerConnection,
+ kDeprecatedPeerConnection,
+ kRTCPeerConnection,
+ kEnumerateDevices,
+ kMediaStreamRecorder,
+ kCanvasCaptureStream,
+ kVideoCaptureStream,
+ kGetDisplayMedia,
+ kInvalidName
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_API_NAME_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.cc
index 52871916e34..d36fc214d7e 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.cc
@@ -6,27 +6,17 @@
#include "base/location.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
+
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-using webrtc::DtmfSenderInterface;
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace blink {
-std::unique_ptr<WebRTCDTMFSenderHandler> CreateRTCDTMFSenderHandler(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- webrtc::DtmfSenderInterface* dtmf_sender) {
- return std::make_unique<RtcDtmfSenderHandler>(std::move(main_thread),
- dtmf_sender);
-}
-
class RtcDtmfSenderHandler::Observer
- : public base::RefCountedThreadSafe<Observer>,
+ : public WTF::ThreadSafeRefCounted<Observer>,
public webrtc::DtmfSenderObserverInterface {
public:
explicit Observer(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
@@ -34,7 +24,7 @@ class RtcDtmfSenderHandler::Observer
: main_thread_(std::move(main_thread)), handler_(handler) {}
private:
- friend class base::RefCountedThreadSafe<Observer>;
+ friend class WTF::ThreadSafeRefCounted<Observer>;
~Observer() override {}
@@ -58,10 +48,11 @@ class RtcDtmfSenderHandler::Observer
RtcDtmfSenderHandler::RtcDtmfSenderHandler(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- DtmfSenderInterface* dtmf_sender)
+ webrtc::DtmfSenderInterface* dtmf_sender)
: dtmf_sender_(dtmf_sender), webkit_client_(nullptr) {
DVLOG(1) << "::ctor";
- observer_ = new Observer(std::move(main_thread), weak_factory_.GetWeakPtr());
+ observer_ = base::MakeRefCounted<Observer>(std::move(main_thread),
+ weak_factory_.GetWeakPtr());
dtmf_sender_->RegisterObserver(observer_.get());
}
@@ -73,29 +64,28 @@ RtcDtmfSenderHandler::~RtcDtmfSenderHandler() {
observer_ = nullptr;
}
-void RtcDtmfSenderHandler::SetClient(
- blink::WebRTCDTMFSenderHandlerClient* client) {
+void RtcDtmfSenderHandler::SetClient(RtcDtmfSenderHandler::Client* client) {
webkit_client_ = client;
}
-blink::WebString RtcDtmfSenderHandler::CurrentToneBuffer() {
- return blink::WebString::FromUTF8(dtmf_sender_->tones());
+String RtcDtmfSenderHandler::CurrentToneBuffer() {
+ return String::FromUTF8(dtmf_sender_->tones());
}
bool RtcDtmfSenderHandler::CanInsertDTMF() {
return dtmf_sender_->CanInsertDtmf();
}
-bool RtcDtmfSenderHandler::InsertDTMF(const blink::WebString& tones,
+bool RtcDtmfSenderHandler::InsertDTMF(const String& tones,
int duration,
- int interToneGap) {
+ int inter_tone_gap) {
std::string utf8_tones = tones.Utf8();
- return dtmf_sender_->InsertDtmf(utf8_tones, duration, interToneGap);
+ return dtmf_sender_->InsertDtmf(utf8_tones, duration, inter_tone_gap);
}
void RtcDtmfSenderHandler::OnToneChange(const String& tone) {
if (!webkit_client_) {
- LOG(ERROR) << "WebRTCDTMFSenderHandlerClient not set.";
+ LOG(ERROR) << "RtcDtmfSenderHandler::Client not set.";
return;
}
webkit_client_->DidPlayTone(tone);
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
index 4467b69d478..86aa4a620e2 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
@@ -10,11 +10,20 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
-#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h"
-#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h"
-#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/dtmf_sender_interface.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace webrtc {
+class DtmfSenderInterface;
+}
+
namespace blink {
// RtcDtmfSenderHandler is a delegate for the RTC DTMF Sender API messages
@@ -23,25 +32,30 @@ namespace blink {
// WebKit call all of these methods on the main render thread.
// Callbacks to the webrtc::DtmfSenderObserverInterface implementation also
// occur on the main render thread.
-class RtcDtmfSenderHandler : public blink::WebRTCDTMFSenderHandler {
+class PLATFORM_EXPORT RtcDtmfSenderHandler final {
public:
+ class PLATFORM_EXPORT Client : public GarbageCollectedMixin {
+ public:
+ virtual ~Client() = default;
+ virtual void DidPlayTone(const String& tone) = 0;
+
+ void Trace(blink::Visitor* visitor) override {}
+ };
+
RtcDtmfSenderHandler(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
webrtc::DtmfSenderInterface* dtmf_sender);
- ~RtcDtmfSenderHandler() override;
+ ~RtcDtmfSenderHandler();
- // blink::WebRTCDTMFSenderHandler implementation.
- void SetClient(blink::WebRTCDTMFSenderHandlerClient* client) override;
- blink::WebString CurrentToneBuffer() override;
- bool CanInsertDTMF() override;
- bool InsertDTMF(const blink::WebString& tones,
- int duration,
- int interToneGap) override;
+ void SetClient(RtcDtmfSenderHandler::Client* client);
+ String CurrentToneBuffer();
+ bool CanInsertDTMF();
+ bool InsertDTMF(const String& tones, int duration, int inter_tone_gap);
void OnToneChange(const String& tone);
private:
scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender_;
- blink::WebRTCDTMFSenderHandlerClient* webkit_client_;
+ WeakPersistent<RtcDtmfSenderHandler::Client> webkit_client_;
class Observer;
scoped_refptr<Observer> observer_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h
new file mode 100644
index 00000000000..be9e3f265a3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h
@@ -0,0 +1,21 @@
+// Copyright (c) 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_H_
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT RtcEventLogOutputSink {
+ public:
+ virtual ~RtcEventLogOutputSink() = default;
+
+ virtual void OnWebRtcEventLogWrite(const std::string& output) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
index ad2e0c2a4ce..4a8649ad39c 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
@@ -5,16 +5,10 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h"
#include "base/logging.h"
-#include "third_party/blink/public/platform/modules/peerconnection/rtc_event_log_output_sink.h"
-#include "third_party/blink/public/platform/modules/peerconnection/rtc_event_log_output_sink_proxy_util.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h"
namespace blink {
-std::unique_ptr<webrtc::RtcEventLogOutput> CreateRtcEventLogOutputSinkProxy(
- RtcEventLogOutputSink* sink) {
- return std::make_unique<RtcEventLogOutputSinkProxy>(sink);
-}
-
RtcEventLogOutputSinkProxy::RtcEventLogOutputSinkProxy(
RtcEventLogOutputSink* sink)
: sink_(sink) {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
index 994f1db6b80..8ecdf912ee2 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
@@ -5,13 +5,21 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_PROXY_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_PROXY_H_
+#include <memory>
+
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/rtc_event_log_output.h"
+namespace webrtc {
+class RtcEventLogOutput;
+}
+
namespace blink {
class RtcEventLogOutputSink;
-class RtcEventLogOutputSinkProxy final : public webrtc::RtcEventLogOutput {
+class PLATFORM_EXPORT RtcEventLogOutputSinkProxy final
+ : public webrtc::RtcEventLogOutput {
public:
RtcEventLogOutputSinkProxy(RtcEventLogOutputSink* sink);
~RtcEventLogOutputSinkProxy() override;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc
index e67ee46cfe3..74d1d404a04 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
#include "third_party/webrtc/api/candidate.h"
#include "third_party/webrtc/p2p/base/p2p_constants.h"
@@ -15,56 +15,56 @@ namespace {
// Maps |component| to constants defined in
// https://w3c.github.io/webrtc-pc/#dom-rtcicecomponent
-blink::WebString CandidateComponentToWebString(int component) {
+String CandidateComponentToString(int component) {
if (component == cricket::ICE_CANDIDATE_COMPONENT_RTP)
- return blink::WebString::FromASCII("rtp");
+ return String("rtp");
if (component == cricket::ICE_CANDIDATE_COMPONENT_RTCP)
- return blink::WebString::FromASCII("rtcp");
- return blink::WebString();
+ return String("rtcp");
+ return String();
}
// Maps |type| to constants defined in
// https://w3c.github.io/webrtc-pc/#rtcicecandidatetype-enum
-blink::WebString CandidateTypeToWebString(const std::string& type) {
+String CandidateTypeToString(const std::string& type) {
if (type == cricket::LOCAL_PORT_TYPE)
- return blink::WebString::FromASCII("host");
+ return String("host");
if (type == cricket::STUN_PORT_TYPE)
- return blink::WebString::FromASCII("srflx");
+ return String("srflx");
if (type == cricket::PRFLX_PORT_TYPE)
- return blink::WebString::FromASCII("prflx");
+ return String("prflx");
if (type == cricket::RELAY_PORT_TYPE)
- return blink::WebString::FromASCII("relay");
- return blink::WebString();
+ return String("relay");
+ return String();
}
} // namespace
// static
-scoped_refptr<WebRTCICECandidate> WebRTCICECandidate::Create(
- WebString candidate,
- WebString sdp_mid,
+scoped_refptr<RTCIceCandidatePlatform> RTCIceCandidatePlatform::Create(
+ String candidate,
+ String sdp_mid,
base::Optional<uint16_t> sdp_m_line_index,
- WebString username_fragment) {
- return base::AdoptRef(new WebRTCICECandidate(
+ String username_fragment) {
+ return base::AdoptRef(new RTCIceCandidatePlatform(
std::move(candidate), std::move(sdp_mid), std::move(sdp_m_line_index),
std::move(username_fragment)));
}
-scoped_refptr<WebRTCICECandidate> WebRTCICECandidate::Create(
- WebString candidate,
- WebString sdp_mid,
+scoped_refptr<RTCIceCandidatePlatform> RTCIceCandidatePlatform::Create(
+ String candidate,
+ String sdp_mid,
int sdp_m_line_index) {
- return base::AdoptRef(new WebRTCICECandidate(
+ return base::AdoptRef(new RTCIceCandidatePlatform(
std::move(candidate), std::move(sdp_mid),
sdp_m_line_index < 0 ? base::Optional<uint16_t>()
: base::Optional<uint16_t>(sdp_m_line_index)));
}
-WebRTCICECandidate::WebRTCICECandidate(
- WebString candidate,
- WebString sdp_mid,
+RTCIceCandidatePlatform::RTCIceCandidatePlatform(
+ String candidate,
+ String sdp_mid,
base::Optional<uint16_t> sdp_m_line_index,
- WebString username_fragment)
+ String username_fragment)
: candidate_(std::move(candidate)),
sdp_mid_(std::move(sdp_mid)),
sdp_m_line_index_(std::move(sdp_m_line_index)),
@@ -72,9 +72,9 @@ WebRTCICECandidate::WebRTCICECandidate(
PopulateFields(false);
}
-WebRTCICECandidate::WebRTCICECandidate(
- WebString candidate,
- WebString sdp_mid,
+RTCIceCandidatePlatform::RTCIceCandidatePlatform(
+ String candidate,
+ String sdp_mid,
base::Optional<uint16_t> sdp_m_line_index)
: candidate_(std::move(candidate)),
sdp_mid_(std::move(sdp_mid)),
@@ -82,29 +82,29 @@ WebRTCICECandidate::WebRTCICECandidate(
PopulateFields(true);
}
-void WebRTCICECandidate::PopulateFields(bool use_username_from_candidate) {
+void RTCIceCandidatePlatform::PopulateFields(bool use_username_from_candidate) {
cricket::Candidate c;
if (!webrtc::ParseCandidate(candidate_.Utf8(), &c, nullptr, true))
return;
- foundation_ = blink::WebString::FromUTF8(c.foundation());
- component_ = CandidateComponentToWebString(c.component());
+ foundation_ = String::FromUTF8(c.foundation().data());
+ component_ = CandidateComponentToString(c.component());
priority_ = c.priority();
- protocol_ = blink::WebString::FromUTF8(c.protocol());
+ protocol_ = String::FromUTF8(c.protocol().data());
if (!c.address().IsNil()) {
- address_ = blink::WebString::FromUTF8(c.address().HostAsURIString());
+ address_ = String::FromUTF8(c.address().HostAsURIString().data());
port_ = c.address().port();
}
- type_ = CandidateTypeToWebString(c.type());
- tcp_type_ = blink::WebString::FromUTF8(c.tcptype());
+ type_ = CandidateTypeToString(c.type());
+ tcp_type_ = String::FromUTF8(c.tcptype().data());
if (!c.related_address().IsNil()) {
related_address_ =
- blink::WebString::FromUTF8(c.related_address().HostAsURIString());
+ String::FromUTF8(c.related_address().HostAsURIString().data());
related_port_ = c.related_address().port();
}
if (use_username_from_candidate)
- username_fragment_ = blink::WebString::FromUTF8(c.username());
+ username_fragment_ = String::FromUTF8(c.username().data());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h
new file mode 100644
index 00000000000..6baacd5ae97
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ICE_CANDIDATE_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ICE_CANDIDATE_PLATFORM_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT RTCIceCandidatePlatform final
+ : public WTF::ThreadSafeRefCounted<RTCIceCandidatePlatform> {
+ public:
+ // Creates a new RTCIceCandidatePlatform using |candidate|, |sdp_mid| and
+ // |sdp_m_line_index|. If |sdp_m_line_index| is negative, it is
+ // considered as having no value.
+ static scoped_refptr<RTCIceCandidatePlatform> Create(String candidate,
+ String sdp_mid,
+ int sdp_m_line_index);
+
+ // Creates a new RTCIceCandidatePlatform using |candidate|, |sdp_mid|,
+ // |sdp_m_line_index|, and |username_fragment|.
+ static scoped_refptr<RTCIceCandidatePlatform> Create(
+ String candidate,
+ String sdp_mid,
+ base::Optional<uint16_t> sdp_m_line_index,
+ String username_fragment);
+
+ const String& Candidate() const { return candidate_; }
+ const String& SdpMid() const { return sdp_mid_; }
+ const base::Optional<uint16_t>& SdpMLineIndex() const {
+ return sdp_m_line_index_;
+ }
+ const String& Foundation() const { return foundation_; }
+ const String& Component() const { return component_; }
+ const base::Optional<uint32_t>& Priority() const { return priority_; }
+ const String& Address() const { return address_; }
+ const String Protocol() const { return protocol_; }
+ const base::Optional<uint16_t>& Port() const { return port_; }
+ const String& Type() const { return type_; }
+ const String& TcpType() const { return tcp_type_; }
+ const String& RelatedAddress() const { return related_address_; }
+ const base::Optional<uint16_t>& RelatedPort() const { return related_port_; }
+ const String& UsernameFragment() const { return username_fragment_; }
+
+ private:
+ friend class WTF::ThreadSafeRefCounted<RTCIceCandidatePlatform>;
+
+ RTCIceCandidatePlatform(String candidate,
+ String sdp_mid,
+ base::Optional<uint16_t> sdp_m_line_index);
+
+ RTCIceCandidatePlatform(String candidate,
+ String sdp_mid,
+ base::Optional<uint16_t> sdp_m_line_index,
+ String username_fragment);
+
+ void PopulateFields(bool use_username_from_candidate);
+
+ ~RTCIceCandidatePlatform() = default;
+
+ String candidate_;
+ String sdp_mid_;
+ base::Optional<uint16_t> sdp_m_line_index_;
+ String foundation_;
+ String component_;
+ base::Optional<uint32_t> priority_;
+ String address_;
+ String protocol_;
+ base::Optional<uint16_t> port_;
+ String type_;
+ String tcp_type_;
+ String related_address_;
+ base::Optional<uint16_t> related_port_;
+ String username_fragment_;
+
+ DISALLOW_COPY_AND_ASSIGN(RTCIceCandidatePlatform);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ICE_CANDIDATE_PLATFORM_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_legacy_stats.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_legacy_stats.h
new file mode 100644
index 00000000000..8b40d91289d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_legacy_stats.h
@@ -0,0 +1,53 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_LEGACY_STATS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_LEGACY_STATS_H_
+
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/webrtc/api/stats_types.h"
+
+namespace blink {
+
+class RTCLegacyStatsMemberIterator;
+
+// TODO(crbug.com/787254): Remove both RTCLegacyStats and
+// RTCLegacyStatsMemberIterator base interfaces when they stopped
+// being referenced by renderer/platform (namely rtc_stats_response_base.h).
+class RTCLegacyStats {
+ public:
+ virtual ~RTCLegacyStats() = default;
+
+ virtual String Id() const = 0;
+ virtual String GetType() const = 0;
+ virtual double Timestamp() const = 0;
+
+ // The caller owns the iterator. The iterator must not be used after
+ // the |RTCLegacyStats| that created it is destroyed.
+ virtual RTCLegacyStatsMemberIterator* Iterator() const = 0;
+};
+
+class RTCLegacyStatsMemberIterator {
+ public:
+ virtual ~RTCLegacyStatsMemberIterator() = default;
+ virtual bool IsEnd() const = 0;
+ virtual void Next() = 0;
+
+ virtual String GetName() const = 0;
+ virtual webrtc::StatsReport::Value::Type GetType() const = 0;
+ // Value getters. No conversion is performed; the function must match the
+ // member's |type|.
+ virtual int ValueInt() const = 0;
+ virtual int64_t ValueInt64() const = 0;
+ virtual float ValueFloat() const = 0;
+ virtual String ValueString() const = 0;
+ virtual bool ValueBool() const = 0;
+
+ // Converts the value to string (regardless of |type|).
+ virtual String ValueToString() const = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_LEGACY_STATS_H_
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_sender.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.cc
index 6a88a1ab147..d01bd27333d 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_sender.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
namespace blink {
-WebRTCRtpSender::~WebRTCRtpSender() = default;
+RTCRtpReceiverPlatform::~RTCRtpReceiverPlatform() = default;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h
new file mode 100644
index 00000000000..ad18bf33776
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h
@@ -0,0 +1,53 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_RECEIVER_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_RECEIVER_PLATFORM_H_
+
+#include <memory>
+
+#include "base/optional.h"
+#include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/webrtc/api/dtls_transport_interface.h"
+#include "third_party/webrtc/api/rtp_parameters.h"
+#include "third_party/webrtc/api/stats/rtc_stats.h"
+
+namespace blink {
+
+class RTCRtpSource;
+class WebMediaStreamTrack;
+
+// Implementations of this interface keep the corresponding WebRTC-layer
+// receiver alive through reference counting. Multiple |RTCRtpReceiverPlatform|s
+// could reference the same receiver, see |id|.
+// https://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface
+class BLINK_PLATFORM_EXPORT RTCRtpReceiverPlatform {
+ public:
+ virtual ~RTCRtpReceiverPlatform();
+
+ virtual std::unique_ptr<RTCRtpReceiverPlatform> ShallowCopy() const = 0;
+ // Two |RTCRtpReceiverPlatform|s referencing the same WebRTC-layer receiver
+ // have the same |id|.
+ virtual uintptr_t Id() const = 0;
+ virtual rtc::scoped_refptr<webrtc::DtlsTransportInterface>
+ DtlsTransport() = 0;
+ // Note: For convenience, DtlsTransportInformation always returns a value.
+ // The information is only interesting if DtlsTransport() is non-null.
+ virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
+ virtual const WebMediaStreamTrack& Track() const = 0;
+ virtual WebVector<WebString> StreamIds() const = 0;
+ virtual WebVector<std::unique_ptr<RTCRtpSource>> GetSources() = 0;
+ virtual void GetStats(blink::WebRTCStatsReportCallback,
+ const WebVector<webrtc::NonStandardGroupId>&) = 0;
+ virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
+ virtual void SetJitterBufferMinimumDelay(
+ base::Optional<double> delay_seconds) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_RECEIVER_PLATFORM_H_
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_receiver.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.cc
index a09e4d5da73..3188899871c 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_receiver.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
namespace blink {
-WebRTCRtpReceiver::~WebRTCRtpReceiver() = default;
+RTCRtpSenderPlatform::~RTCRtpSenderPlatform() = default;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h
new file mode 100644
index 00000000000..e2db21cc70f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h
@@ -0,0 +1,59 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_SENDER_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_SENDER_PLATFORM_H_
+
+#include <memory>
+
+#include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/dtls_transport_interface.h"
+#include "third_party/webrtc/api/rtp_parameters.h"
+#include "third_party/webrtc/api/stats/rtc_stats.h"
+
+namespace blink {
+
+class RTCVoidRequest;
+class WebMediaStreamTrack;
+class RtcDtmfSenderHandler;
+
+// Implementations of this interface keep the corresponding WebRTC-layer sender
+// alive through reference counting. Multiple |RTCRtpSenderPlatform|s could
+// reference the same sender; check for equality with |id|.
+// https://w3c.github.io/webrtc-pc/#rtcrtpsender-interface
+class PLATFORM_EXPORT RTCRtpSenderPlatform {
+ public:
+ virtual ~RTCRtpSenderPlatform();
+ virtual std::unique_ptr<RTCRtpSenderPlatform> ShallowCopy() const = 0;
+
+ // Two |RTCRtpSenderPlatform|s referencing the same WebRTC-layer sender have
+ // the same |id|. IDs are guaranteed to be unique amongst senders but they are
+ // allowed to be reused after a sender is destroyed.
+ virtual uintptr_t Id() const = 0;
+ virtual rtc::scoped_refptr<webrtc::DtlsTransportInterface>
+ DtlsTransport() = 0;
+ // Note: For convenience, DtlsTransportInformation always returns a value.
+ // The information is only interesting if DtlsTransport() is non-null.
+ virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
+ virtual WebMediaStreamTrack Track() const = 0;
+ virtual WebVector<WebString> StreamIds() const = 0;
+ // TODO(hbos): Replace RTCVoidRequest by something resolving promises based
+ // on RTCError, as to surface both exception type and error message.
+ // https://crbug.com/790007
+ virtual void ReplaceTrack(WebMediaStreamTrack, RTCVoidRequest*) = 0;
+ virtual std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const = 0;
+ virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
+ virtual void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
+ webrtc::DegradationPreference,
+ RTCVoidRequest*) = 0;
+ virtual void GetStats(blink::WebRTCStatsReportCallback,
+ const WebVector<webrtc::NonStandardGroupId>&) = 0;
+ virtual void SetStreams(const WebVector<WebString>& stream_ids) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_SENDER_PLATFORM_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
index 7169cc9def8..be6a3c88bf9 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
@@ -12,24 +12,19 @@
namespace blink {
-std::unique_ptr<WebRTCRtpSource> CreateRTCRtpSource(
- const webrtc::RtpSource& source) {
- return std::make_unique<RTCRtpSource>(source);
-}
-
RTCRtpSource::RTCRtpSource(const webrtc::RtpSource& source) : source_(source) {}
RTCRtpSource::~RTCRtpSource() {}
-WebRTCRtpSource::Type RTCRtpSource::SourceType() const {
+RTCRtpSource::Type RTCRtpSource::SourceType() const {
switch (source_.source_type()) {
case webrtc::RtpSourceType::SSRC:
- return WebRTCRtpSource::Type::kSSRC;
+ return RTCRtpSource::Type::kSSRC;
case webrtc::RtpSourceType::CSRC:
- return WebRTCRtpSource::Type::kCSRC;
+ return RTCRtpSource::Type::kCSRC;
default:
NOTREACHED();
- return WebRTCRtpSource::Type::kSSRC;
+ return RTCRtpSource::Type::kSSRC;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
index cd771acda3b..a36dd370c77 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
@@ -6,22 +6,35 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_SOURCE_H_
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "third_party/blink/public/platform/web_rtc_rtp_source.h"
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/rtp_receiver_interface.h"
+namespace base {
+class TimeTicks;
+}
+
+namespace webrtc {
+class RtpSource;
+}
+
namespace blink {
-class RTCRtpSource : public WebRTCRtpSource {
+class PLATFORM_EXPORT RTCRtpSource {
public:
+ enum class Type {
+ kSSRC,
+ kCSRC,
+ };
+
explicit RTCRtpSource(const webrtc::RtpSource& source);
- ~RTCRtpSource() override;
+ ~RTCRtpSource();
- WebRTCRtpSource::Type SourceType() const override;
- base::TimeTicks Timestamp() const override;
- uint32_t Source() const override;
- base::Optional<double> AudioLevel() const override;
- uint32_t RtpTimestamp() const override;
+ Type SourceType() const;
+ base::TimeTicks Timestamp() const;
+ uint32_t Source() const;
+ base::Optional<double> AudioLevel() const;
+ uint32_t RtpTimestamp() const;
private:
const webrtc::RtpSource source_;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_transceiver.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.cc
index e84f55ab58b..e9f05f26e04 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_rtp_transceiver.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
namespace blink {
-WebRTCRtpTransceiver::~WebRTCRtpTransceiver() = default;
+RTCRtpTransceiverPlatform::~RTCRtpTransceiverPlatform() = default;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h
new file mode 100644
index 00000000000..91e1c1a8b85
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h
@@ -0,0 +1,73 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_TRANSCEIVER_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_TRANSCEIVER_PLATFORM_H_
+
+#include <memory>
+
+#include "base/optional.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/rtp_transceiver_interface.h"
+
+namespace blink {
+
+class RTCRtpReceiverPlatform;
+class RTCRtpSenderPlatform;
+
+// In Unified Plan transceivers exist and a full implementation of
+// RTCRtpTransceiverPlatform is required.
+// In Plan B, the same methods that would be used to surface transceivers only
+// surface the sender or receiver component.
+// To make the Plan B -> Unified Plan transition easier,
+// RTCRtpTransceiverPlatform is used in both cases and ImplementationType
+// indicates which methods are applicable for the RTCRtpTransceiverPlatform
+// implementation.
+enum class RTCRtpTransceiverPlatformImplementationType {
+ // Unified Plan: All methods implemented.
+ kFullTransceiver,
+ // Plan B: Only Sender() is implemented.
+ kPlanBSenderOnly,
+ // Plan B: Only Receiver() is implemented.
+ kPlanBReceiverOnly,
+};
+
+// Interface for content to implement as to allow the surfacing of transceivers.
+// TODO(hbos): [Onion Soup] Remove the content layer versions of this class and
+// rely on webrtc directly from blink. Requires coordination with senders and
+// receivers. https://crbug.com/787254
+class PLATFORM_EXPORT RTCRtpTransceiverPlatform {
+ public:
+ virtual ~RTCRtpTransceiverPlatform();
+
+ // Which methods (other than ImplementationType()) is guaranteed to be
+ // implemented.
+ virtual RTCRtpTransceiverPlatformImplementationType ImplementationType()
+ const = 0;
+
+ // Identifies the webrtc-layer transceiver. Multiple RTCRtpTransceiverPlatform
+ // can exist for the same webrtc-layer transceiver.
+ virtual uintptr_t Id() const = 0;
+ virtual WebString Mid() const = 0;
+ virtual void SetMid(base::Optional<WebString>) {}
+ virtual std::unique_ptr<RTCRtpSenderPlatform> Sender() const = 0;
+ virtual std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const = 0;
+ virtual bool Stopped() const = 0;
+ virtual webrtc::RtpTransceiverDirection Direction() const = 0;
+ virtual void SetDirection(webrtc::RtpTransceiverDirection) = 0;
+ virtual base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const = 0;
+ virtual base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const = 0;
+ virtual webrtc::RTCError SetCodecPreferences(
+ WebVector<webrtc::RtpCodecCapability>) {
+ return {};
+ }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_RTP_TRANSCEIVER_PLATFORM_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.cc
new file mode 100644
index 00000000000..f150d01cb42
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.cc
@@ -0,0 +1,13 @@
+// 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 "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
+
+namespace blink {
+
+RTCSessionDescriptionPlatform::RTCSessionDescriptionPlatform(const String& type,
+ const String& sdp)
+ : type_(type), sdp_(sdp) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
new file mode 100644
index 00000000000..6c003142933
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_SESSION_DESCRIPTION_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_SESSION_DESCRIPTION_PLATFORM_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT RTCSessionDescriptionPlatform final
+ : public GarbageCollected<RTCSessionDescriptionPlatform> {
+ public:
+ RTCSessionDescriptionPlatform(const String& type, const String& sdp);
+
+ String GetType() { return type_; }
+ void SetType(const String& type) { type_ = type; }
+
+ String Sdp() { return sdp_; }
+ void SetSdp(const String& sdp) { sdp_ = sdp; }
+
+ void Trace(blink::Visitor* visitor) {}
+
+ private:
+ String type_;
+ String sdp_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_SESSION_DESCRIPTION_PLATFORM_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
index f13f8e955f6..9d88696043e 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
@@ -39,14 +39,14 @@ class RTCError;
}
namespace blink {
-class WebRTCSessionDescription;
+class RTCSessionDescriptionPlatform;
class RTCSessionDescriptionRequest
: public GarbageCollected<RTCSessionDescriptionRequest> {
public:
virtual ~RTCSessionDescriptionRequest() = default;
- virtual void RequestSucceeded(const WebRTCSessionDescription&) = 0;
+ virtual void RequestSucceeded(RTCSessionDescriptionPlatform*) = 0;
virtual void RequestFailed(const webrtc::RTCError&) = 0;
virtual void Trace(blink::Visitor* visitor) {}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
index bc9f8989ed0..6093874c03c 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -118,13 +118,6 @@ size_t CountWhitelistedStats(
} // namespace
-std::unique_ptr<blink::WebRTCStatsReport> CreateRTCStatsReport(
- const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
- return std::make_unique<RTCStatsReportPlatform>(std::move(stats_report),
- exposed_group_ids);
-}
-
RTCStatsReportPlatform::RTCStatsReportPlatform(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids)
@@ -138,41 +131,36 @@ RTCStatsReportPlatform::RTCStatsReportPlatform(
RTCStatsReportPlatform::~RTCStatsReportPlatform() {}
-std::unique_ptr<blink::WebRTCStatsReport> RTCStatsReportPlatform::CopyHandle()
+std::unique_ptr<RTCStatsReportPlatform> RTCStatsReportPlatform::CopyHandle()
const {
- return CreateRTCStatsReport(stats_report_, exposed_group_ids_);
+ return std::make_unique<RTCStatsReportPlatform>(stats_report_,
+ exposed_group_ids_);
}
-std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::GetStats(
- blink::WebString id) const {
+std::unique_ptr<RTCStats> RTCStatsReportPlatform::GetStats(
+ const String& id) const {
const webrtc::RTCStats* stats = stats_report_->Get(id.Utf8());
if (!stats || !IsWhitelistedStats(*stats))
- return std::unique_ptr<blink::WebRTCStats>();
- return CreateRTCStats(stats_report_, stats, exposed_group_ids_);
+ return std::unique_ptr<RTCStats>();
+ return std::make_unique<RTCStats>(stats_report_, stats, exposed_group_ids_);
}
-std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::Next() {
+std::unique_ptr<RTCStats> RTCStatsReportPlatform::Next() {
while (it_ != end_) {
const webrtc::RTCStats& next = *it_;
++it_;
- if (IsWhitelistedStats(next))
- return CreateRTCStats(stats_report_, &next, exposed_group_ids_);
+ if (IsWhitelistedStats(next)) {
+ return std::make_unique<RTCStats>(stats_report_, &next,
+ exposed_group_ids_);
+ }
}
- return std::unique_ptr<blink::WebRTCStats>();
+ return std::unique_ptr<RTCStats>();
}
size_t RTCStatsReportPlatform::Size() const {
return size_;
}
-std::unique_ptr<blink::WebRTCStats> CreateRTCStats(
- const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
- const webrtc::RTCStats* stats,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
- return std::make_unique<RTCStats>(std::move(stats_owner), stats,
- exposed_group_ids);
-}
-
RTCStats::RTCStats(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
const webrtc::RTCStats* stats,
@@ -187,12 +175,12 @@ RTCStats::RTCStats(
RTCStats::~RTCStats() {}
-blink::WebString RTCStats::Id() const {
- return blink::WebString::FromUTF8(stats_->id());
+String RTCStats::Id() const {
+ return String::FromUTF8(stats_->id());
}
-blink::WebString RTCStats::GetType() const {
- return blink::WebString::FromUTF8(stats_->type());
+String RTCStats::GetType() const {
+ return String::FromUTF8(stats_->type());
}
double RTCStats::Timestamp() const {
@@ -204,15 +192,9 @@ size_t RTCStats::MembersCount() const {
return stats_members_.size();
}
-std::unique_ptr<blink::WebRTCStatsMember> RTCStats::GetMember(size_t i) const {
+std::unique_ptr<RTCStatsMember> RTCStats::GetMember(size_t i) const {
DCHECK_LT(i, stats_members_.size());
- return CreateRTCStatsMember(stats_owner_, stats_members_[i]);
-}
-
-std::unique_ptr<blink::WebRTCStatsMember> CreateRTCStatsMember(
- const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
- const webrtc::RTCStatsMemberInterface* member) {
- return std::make_unique<RTCStatsMember>(std::move(stats_owner), member);
+ return std::make_unique<RTCStatsMember>(stats_owner_, stats_members_[i]);
}
RTCStatsMember::RTCStatsMember(
@@ -225,8 +207,8 @@ RTCStatsMember::RTCStatsMember(
RTCStatsMember::~RTCStatsMember() {}
-blink::WebString RTCStatsMember::GetName() const {
- return blink::WebString::FromUTF8(member_->name());
+String RTCStatsMember::GetName() const {
+ return String::FromUTF8(member_->name());
}
webrtc::RTCStatsMemberInterface::Type RTCStatsMember::GetType() const {
@@ -267,9 +249,9 @@ double RTCStatsMember::ValueDouble() const {
return *member_->cast_to<webrtc::RTCStatsMember<double>>();
}
-blink::WebString RTCStatsMember::ValueString() const {
+String RTCStatsMember::ValueString() const {
DCHECK(IsDefined());
- return blink::WebString::FromUTF8(
+ return String::FromUTF8(
*member_->cast_to<webrtc::RTCStatsMember<std::string>>());
}
@@ -315,13 +297,13 @@ blink::WebVector<double> RTCStatsMember::ValueSequenceDouble() const {
*member_->cast_to<webrtc::RTCStatsMember<std::vector<double>>>());
}
-blink::WebVector<blink::WebString> RTCStatsMember::ValueSequenceString() const {
+blink::WebVector<String> RTCStatsMember::ValueSequenceString() const {
DCHECK(IsDefined());
const std::vector<std::string>& sequence =
*member_->cast_to<webrtc::RTCStatsMember<std::vector<std::string>>>();
- blink::WebVector<blink::WebString> web_sequence(sequence.size());
+ blink::WebVector<String> web_sequence(sequence.size());
for (size_t i = 0; i < sequence.size(); ++i)
- web_sequence[i] = blink::WebString::FromUTF8(sequence[i]);
+ web_sequence[i] = String::FromUTF8(sequence[i]);
return web_sequence;
}
@@ -362,7 +344,7 @@ void RTCStatsCollectorCallbackImpl::OnStatsDeliveredOnMainThread(
DCHECK(report);
DCHECK(callback_);
// Make sure the callback is destroyed in the main thread as well.
- std::move(callback_).Run(CreateRTCStatsReport(
+ std::move(callback_).Run(std::make_unique<RTCStatsReportPlatform>(
base::WrapRefCounted(report.get()), exposed_group_ids_));
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
index 5f20aa1e151..e518f20d4d0 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -9,12 +9,16 @@
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
#include "third_party/webrtc/api/stats/rtc_stats_collector_callback.h"
#include "third_party/webrtc/api/stats/rtc_stats_report.h"
namespace blink {
+class RTCStats;
+class RTCStatsMember;
+
// Wrapper around a webrtc::RTCStatsReport. Filters out any stats objects that
// aren't whitelisted. |filter| controls whether to include only standard
// members (RTCStatsMemberInterface::is_standardized return true) or not
@@ -24,20 +28,26 @@ namespace blink {
// |RTCStatsReport|, from renderer/modules/peerconnection/rtc_stats_report.cc|h.
//
// TODO(crbug.com/787254): Switch over the classes below from using WebVector
-// and WebString to WTF::Vector and WTF::String, when their respective parent
-// classes are gone.
-class PLATFORM_EXPORT RTCStatsReportPlatform : public WebRTCStatsReport {
+// to WTF::Vector, when their respective parent classes are gone.
+class PLATFORM_EXPORT RTCStatsReportPlatform {
public:
RTCStatsReportPlatform(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
- ~RTCStatsReportPlatform() override;
- std::unique_ptr<blink::WebRTCStatsReport> CopyHandle() const override;
+ virtual ~RTCStatsReportPlatform();
+ // Creates a new report object that is a handle to the same underlying stats
+ // report (the stats are not copied). The new report's iterator is reset,
+ // useful when needing multiple iterators.
+ std::unique_ptr<RTCStatsReportPlatform> CopyHandle() const;
+
+ // Gets stats object by |id|, or null if no stats with that |id| exists.
+ std::unique_ptr<RTCStats> GetStats(const String& id) const;
+
+ // The next stats object, or null if the end has been reached.
+ std::unique_ptr<RTCStats> Next();
- std::unique_ptr<blink::WebRTCStats> GetStats(
- blink::WebString id) const override;
- std::unique_ptr<blink::WebRTCStats> Next() override;
- size_t Size() const override;
+ // The number of stats objects.
+ size_t Size() const;
private:
const scoped_refptr<const webrtc::RTCStatsReport> stats_report_;
@@ -48,20 +58,20 @@ class PLATFORM_EXPORT RTCStatsReportPlatform : public WebRTCStatsReport {
const size_t size_;
};
-class PLATFORM_EXPORT RTCStats : public blink::WebRTCStats {
+class PLATFORM_EXPORT RTCStats {
public:
RTCStats(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
const webrtc::RTCStats* stats,
const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
- ~RTCStats() override;
+ virtual ~RTCStats();
- blink::WebString Id() const override;
- blink::WebString GetType() const override;
- double Timestamp() const override;
+ String Id() const;
+ String GetType() const;
+ double Timestamp() const;
- size_t MembersCount() const override;
- std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const override;
+ size_t MembersCount() const;
+ std::unique_ptr<RTCStatsMember> GetMember(size_t i) const;
private:
// Reference to keep the report that owns |stats_| alive.
@@ -72,30 +82,30 @@ class PLATFORM_EXPORT RTCStats : public blink::WebRTCStats {
const std::vector<const webrtc::RTCStatsMemberInterface*> stats_members_;
};
-class PLATFORM_EXPORT RTCStatsMember : public blink::WebRTCStatsMember {
+class PLATFORM_EXPORT RTCStatsMember {
public:
RTCStatsMember(const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
const webrtc::RTCStatsMemberInterface* member);
- ~RTCStatsMember() override;
-
- blink::WebString GetName() const override;
- webrtc::RTCStatsMemberInterface::Type GetType() const override;
- bool IsDefined() const override;
-
- bool ValueBool() const override;
- int32_t ValueInt32() const override;
- uint32_t ValueUint32() const override;
- int64_t ValueInt64() const override;
- uint64_t ValueUint64() const override;
- double ValueDouble() const override;
- blink::WebString ValueString() const override;
- blink::WebVector<int> ValueSequenceBool() const override;
- blink::WebVector<int32_t> ValueSequenceInt32() const override;
- blink::WebVector<uint32_t> ValueSequenceUint32() const override;
- blink::WebVector<int64_t> ValueSequenceInt64() const override;
- blink::WebVector<uint64_t> ValueSequenceUint64() const override;
- blink::WebVector<double> ValueSequenceDouble() const override;
- blink::WebVector<blink::WebString> ValueSequenceString() const override;
+ virtual ~RTCStatsMember();
+
+ String GetName() const;
+ webrtc::RTCStatsMemberInterface::Type GetType() const;
+ bool IsDefined() const;
+
+ bool ValueBool() const;
+ int32_t ValueInt32() const;
+ uint32_t ValueUint32() const;
+ int64_t ValueInt64() const;
+ uint64_t ValueUint64() const;
+ double ValueDouble() const;
+ String ValueString() const;
+ blink::WebVector<int> ValueSequenceBool() const;
+ blink::WebVector<int32_t> ValueSequenceInt32() const;
+ blink::WebVector<uint32_t> ValueSequenceUint32() const;
+ blink::WebVector<int64_t> ValueSequenceInt64() const;
+ blink::WebVector<uint64_t> ValueSequenceUint64() const;
+ blink::WebVector<double> ValueSequenceDouble() const;
+ blink::WebVector<String> ValueSequenceString() const;
private:
// Reference to keep the report that owns |member_|'s stats object alive.
@@ -107,7 +117,7 @@ class PLATFORM_EXPORT RTCStatsMember : public blink::WebRTCStatsMember {
// A stats collector callback.
// It is invoked on the WebRTC signaling thread and will post a task to invoke
// |callback| on the thread given in the |main_thread| argument.
-// The argument to the callback will be a |blink::WebRTCStatsReport|.
+// The argument to the callback will be a |RTCStatsReportPlatform|.
class PLATFORM_EXPORT RTCStatsCollectorCallbackImpl
: public webrtc::RTCStatsCollectorCallback {
public:
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
index 8510fb9635c..5c83bbd6d7f 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
@@ -40,12 +40,37 @@ namespace blink {
class MediaStreamComponent;
class RTCStatsResponseBase;
+// TODO(crbug.com/787254): Merge RTCStatsRequest and RTCStatsRequestImpl
+// when the former is not referenced in renderer/platform anymore.
+//
+// The RTCStatsRequest class represents a JavaScript call on
+// RTCPeerConnection.getStats(). The user of this API will use
+// the calls on this class and RTCStatsResponseBase to fill in the
+// data that will be returned via a callback to the user in an
+// RTCStatsResponse structure.
+//
+// The typical usage pattern is:
+// RTCStatsRequest* request = <from somewhere>
+// RTCStatsResponseBase* response = request->CreateResponse();
+//
+// For each item on which statistics are going to be reported:
+// RTCLegacyStats stats(...);
+// (configuration of stats object depends on item type)
+// response.AddStats(stats);
+// When finished adding information:
+// request->RequestSucceeded(response);
class RTCStatsRequest : public GarbageCollected<RTCStatsRequest> {
public:
virtual ~RTCStatsRequest() = default;
virtual RTCStatsResponseBase* CreateResponse() = 0;
+
+ // This function returns true if a selector argument was given to getStats.
virtual bool HasSelector() = 0;
+
+ // The Component() accessor give the information
+ // required to look up a MediaStreamTrack implementation.
+ // It is only useful to call it when HasSelector() returns true.
virtual MediaStreamComponent* Component() = 0;
virtual void RequestSucceeded(RTCStatsResponseBase*) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h
index 113d1454164..eca388b0326 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h
@@ -25,17 +25,19 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_STATS_RESPONSE_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_STATS_RESPONSE_BASE_H_
-#include "third_party/blink/public/platform/web_rtc_legacy_stats.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_legacy_stats.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
+// TODO(crbug.com/787254): Merge RTCStatsResponseBase and RTCStatsResponse
+// when the former is not referenced in renderer/platform anymore.
class RTCStatsResponseBase : public ScriptWrappable {
public:
~RTCStatsResponseBase() override = default;
- virtual void AddStats(const WebRTCLegacyStats&) = 0;
+ virtual void AddStats(const RTCLegacyStats&) = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
index 082c9d6d321..12678fb053f 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
@@ -26,8 +26,8 @@ TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_GetStats) {
new webrtc::RTCPeerConnectionStats(whitelisted_id, 42)));
RTCStatsReportPlatform report(webrtc_report.get(), {});
- EXPECT_FALSE(report.GetStats(blink::WebString::FromUTF8(not_whitelisted_id)));
- EXPECT_TRUE(report.GetStats(blink::WebString::FromUTF8(whitelisted_id)));
+ EXPECT_FALSE(report.GetStats(not_whitelisted_id));
+ EXPECT_TRUE(report.GetStats(whitelisted_id));
}
TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
@@ -45,7 +45,7 @@ TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
// Only whitelisted stats are counted.
EXPECT_EQ(report.Size(), 1u);
- std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+ std::unique_ptr<RTCStats> stats = report.Next();
EXPECT_TRUE(stats);
EXPECT_EQ(stats->Id(), whitelisted_id);
EXPECT_FALSE(report.Next());
@@ -89,7 +89,7 @@ TEST(RTCStatsTest, OnlyIncludeStandarizedMembers) {
// TestStats has two members, but the non-standard member should be filtered
// out.
RTCStatsReportPlatform report(webrtc_report.get(), {});
- std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+ std::unique_ptr<RTCStats> stats = report.Next();
ASSERT_NE(nullptr, stats);
ASSERT_EQ(1u, stats->MembersCount());
EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
@@ -105,7 +105,7 @@ TEST(RTCStatsTest, IncludeAllMembers) {
RTCStatsReportPlatform report(
webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
webrtc::NonStandardGroupId::kGroupIdForTesting});
- std::unique_ptr<blink::WebRTCStats> stats = report.GetStats("id");
+ std::unique_ptr<RTCStats> stats = report.GetStats("id");
ASSERT_NE(nullptr, stats);
ASSERT_EQ(2u, stats->MembersCount());
EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
@@ -120,7 +120,7 @@ TEST(RTCStatsTest, CopyHandle) {
// Check that filtering options are preserved during copy.
RTCStatsReportPlatform standard_members_report(webrtc_report.get(), {});
- std::unique_ptr<blink::WebRTCStatsReport> standard_members_copy =
+ std::unique_ptr<RTCStatsReportPlatform> standard_members_copy =
standard_members_report.CopyHandle();
ASSERT_EQ(1u, standard_members_report.GetStats("id")->MembersCount());
@@ -129,7 +129,7 @@ TEST(RTCStatsTest, CopyHandle) {
RTCStatsReportPlatform all_members_report(
webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
webrtc::NonStandardGroupId::kGroupIdForTesting});
- std::unique_ptr<blink::WebRTCStatsReport> all_members_copy =
+ std::unique_ptr<RTCStatsReportPlatform> all_members_copy =
all_members_report.CopyHandle();
ASSERT_EQ(2u, all_members_report.GetStats("id")->MembersCount());
ASSERT_EQ(2u, all_members_copy->GetStats("id")->MembersCount());
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
index 55ec5e8354b..3783f4c79f8 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -154,8 +154,10 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
GuessVideoCodecProfile(format),
media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(),
media::kNoTransformation, kDefaultSize, gfx::Rect(kDefaultSize),
- kDefaultSize, media::EmptyExtraData(), media::Unencrypted());
- if (!gpu_factories->IsDecoderConfigSupported(kImplementation, config))
+ kDefaultSize, media::EmptyExtraData(),
+ media::EncryptionScheme::kUnencrypted);
+ if (gpu_factories->IsDecoderConfigSupported(kImplementation, config) ==
+ media::GpuVideoAcceleratorFactories::Supported::kFalse)
return nullptr;
// Synchronously verify that the decoder can be initialized.
@@ -384,7 +386,7 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread(
// Encryption is not supported.
media::CdmContext* cdm_context = nullptr;
- media::VideoDecoder::OutputCB output_cb = ConvertToBaseCallback(
+ media::VideoDecoder::OutputCB output_cb = ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&RTCVideoDecoderAdapter::OnOutput, weak_this_));
video_decoder_->Initialize(config, low_delay, cdm_context,
ConvertToBaseOnceCallback(std::move(init_cb)),
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
index a43ed3733e6..213daa35f8a 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
@@ -118,7 +118,8 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
EXPECT_CALL(gpu_factories_, GetTaskRunner()).Times(AtLeast(0));
ON_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
- .WillByDefault(Return(true));
+ .WillByDefault(
+ Return(media::GpuVideoAcceleratorFactories::Supported::kTrue));
EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
.Times(AtLeast(0));
@@ -181,9 +182,9 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
int32_t Decode(uint32_t timestamp) {
webrtc::EncodedImage input_image;
- input_image.Allocate(1);
- input_image.set_size(1);
- input_image.data()[0] = 0;
+ static const uint8_t data[1] = {0};
+ input_image.SetEncodedData(
+ webrtc::EncodedImageBuffer::Create(data, sizeof(data)));
input_image._frameType = webrtc::VideoFrameType::kVideoFrameKey;
input_image._completeFrame = true;
input_image.SetTimestamp(timestamp);
@@ -214,7 +215,9 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
webrtc::EncodedImage GetEncodedImageWithColorSpace(uint32_t timestamp) {
webrtc::EncodedImage input_image;
- input_image.Allocate(1);
+ static const uint8_t data[1] = {0};
+ input_image.SetEncodedData(
+ webrtc::EncodedImageBuffer::Create(data, sizeof(data)));
input_image.set_size(1);
input_image.data()[0] = 0;
input_image._completeFrame = true;
@@ -265,7 +268,7 @@ TEST_F(RTCVideoDecoderAdapterTest, Create_UnknownFormat) {
TEST_F(RTCVideoDecoderAdapterTest, Create_UnsupportedFormat) {
EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
- .WillOnce(Return(false));
+ .WillOnce(Return(media::GpuVideoAcceleratorFactories::Supported::kFalse));
rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create(
&gpu_factories_, webrtc::SdpVideoFormat(webrtc::CodecTypeToPayloadString(
webrtc::kVideoCodecVP9)));
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
index bf83cf5c630..fdb679f48a6 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
@@ -8,7 +8,6 @@
#include <memory>
#include <vector>
-#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/location.h"
@@ -18,6 +17,7 @@
#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/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_checker.h"
@@ -33,10 +33,12 @@
#include "media/video/h264_parser.h"
#include "media/video/video_encode_accelerator.h"
#include "mojo/public/cpp/base/shared_memory_utils.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/libyuv/include/libyuv.h"
@@ -364,6 +366,30 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
if (IsBitrateTooHigh(bitrate))
return;
+ // Check that |profile| supports |input_visible_size|.
+ if (base::FeatureList::IsEnabled(features::kWebRtcUseMinMaxVEADimensions)) {
+ const auto vea_supported_profiles =
+ gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
+ for (const auto vea_profile : vea_supported_profiles) {
+ if (vea_profile.profile == profile &&
+ (input_visible_size.width() > vea_profile.max_resolution.width() ||
+ input_visible_size.height() > vea_profile.max_resolution.height() ||
+ input_visible_size.width() < vea_profile.min_resolution.width() ||
+ input_visible_size.height() < vea_profile.min_resolution.height())) {
+ LogAndNotifyError(
+ FROM_HERE,
+ base::StringPrintf(
+ "Requested dimensions (%s) beyond accelerator limits (%s - %s)",
+ input_visible_size.ToString().c_str(),
+ vea_profile.min_resolution.ToString().c_str(),
+ vea_profile.max_resolution.ToString().c_str())
+ .c_str(),
+ media::VideoEncodeAccelerator::kInvalidArgumentError);
+ return;
+ }
+ }
+ }
+
video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator();
if (!video_encoder_) {
LogAndNotifyError(FROM_HERE, "Error creating VideoEncodeAccelerator",
@@ -848,8 +874,9 @@ void RTCVideoEncoder::Impl::EncodeOneFrameWithNativeInput() {
}
constexpr int kDummyIndex = -1;
- frame->AddDestructionObserver(media::BindToCurrentLoop(base::BindOnce(
- &RTCVideoEncoder::Impl::EncodeFrameFinished, this, kDummyIndex)));
+ frame->AddDestructionObserver(media::BindToCurrentLoop(
+ WTF::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished,
+ CrossThreadUnretained(this), kDummyIndex)));
if (!failed_timestamp_match_) {
DCHECK(std::find_if(pending_timestamps_.begin(), pending_timestamps_.end(),
[&frame](const RTCTimestamps& entry) {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
index fc5bcb11250..5ba62ba4f96 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
@@ -29,11 +29,11 @@ base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
if (profile.profile >= media::VP8PROFILE_MIN &&
profile.profile <= media::VP8PROFILE_MAX) {
- if (base::FeatureList::IsEnabled(blink::features::kWebRtcHWVP8Encoding)) {
- return webrtc::SdpVideoFormat("VP8");
- }
- } else if (profile.profile >= media::H264PROFILE_MIN &&
- profile.profile <= media::H264PROFILE_MAX) {
+ return webrtc::SdpVideoFormat("VP8");
+ }
+ if (profile.profile >= media::H264PROFILE_MIN &&
+ profile.profile <= media::H264PROFILE_MAX) {
+#if !defined(OS_ANDROID)
// Enable H264 HW encode for WebRTC when SW fallback is available, which is
// checked by kWebRtcH264WithOpenH264FFmpeg flag. This check should be
// removed when SW implementation is fully enabled.
@@ -42,58 +42,58 @@ base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
webrtc_h264_sw_enabled = base::FeatureList::IsEnabled(
blink::features::kWebRtcH264WithOpenH264FFmpeg);
#endif // BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
- if (webrtc_h264_sw_enabled ||
- base::FeatureList::IsEnabled(blink::features::kWebRtcHWH264Encoding)) {
- webrtc::H264::Profile h264_profile;
- switch (profile.profile) {
- case media::H264PROFILE_BASELINE:
+ if (!webrtc_h264_sw_enabled)
+ return base::nullopt;
+#endif
+
+ webrtc::H264::Profile h264_profile;
+ switch (profile.profile) {
+ case media::H264PROFILE_BASELINE:
#if defined(OS_ANDROID)
- // Force HW H264 on Android to be CBP for most compatibility, since:
- // - Only HW H264 is available on Android at present.
- // - MediaCodec only advise BP, which works same as CBP in most cases.
- // - Some peers only expect CBP in negotiation.
- h264_profile = webrtc::H264::kProfileConstrainedBaseline;
+ // Force HW H264 on Android to be CBP for most compatibility, since:
+ // - Only HW H264 is available on Android at present.
+ // - MediaCodec only advise BP, which works same as CBP in most cases.
+ // - Some peers only expect CBP in negotiation.
+ h264_profile = webrtc::H264::kProfileConstrainedBaseline;
#else
- h264_profile = webrtc::H264::kProfileBaseline;
+ h264_profile = webrtc::H264::kProfileBaseline;
#endif
- break;
- case media::H264PROFILE_MAIN:
- h264_profile = webrtc::H264::kProfileMain;
- break;
- case media::H264PROFILE_HIGH:
- h264_profile = webrtc::H264::kProfileHigh;
- break;
- default:
- // Unsupported H264 profile in WebRTC.
- return base::nullopt;
- }
-
- const int width = profile.max_resolution.width();
- const int height = profile.max_resolution.height();
- const int fps = profile.max_framerate_numerator;
- DCHECK_EQ(1u, profile.max_framerate_denominator);
-
- const absl::optional<webrtc::H264::Level> h264_level =
- webrtc::H264::SupportedLevel(width * height, fps);
- const webrtc::H264::ProfileLevelId profile_level_id(
- h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
-
- webrtc::SdpVideoFormat format("H264");
- format.parameters = {
- {cricket::kH264FmtpProfileLevelId,
- *webrtc::H264::ProfileLevelIdToString(profile_level_id)},
- {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
- {cricket::kH264FmtpPacketizationMode, "1"}};
- return format;
- }
- } else if (profile.profile >= media::VP9PROFILE_MIN &&
- profile.profile <= media::VP9PROFILE_MAX) {
- if (base::FeatureList::IsEnabled(blink::features::kWebRtcHWVP9Encoding)) {
- return webrtc::SdpVideoFormat("VP9");
+ break;
+ case media::H264PROFILE_MAIN:
+ h264_profile = webrtc::H264::kProfileMain;
+ break;
+ case media::H264PROFILE_HIGH:
+ h264_profile = webrtc::H264::kProfileHigh;
+ break;
+ default:
+ // Unsupported H264 profile in WebRTC.
+ return base::nullopt;
}
+
+ const int width = profile.max_resolution.width();
+ const int height = profile.max_resolution.height();
+ const int fps = profile.max_framerate_numerator;
+ DCHECK_EQ(1u, profile.max_framerate_denominator);
+
+ const absl::optional<webrtc::H264::Level> h264_level =
+ webrtc::H264::SupportedLevel(width * height, fps);
+ const webrtc::H264::ProfileLevelId profile_level_id(
+ h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
+
+ webrtc::SdpVideoFormat format("H264");
+ format.parameters = {
+ {cricket::kH264FmtpProfileLevelId,
+ *webrtc::H264::ProfileLevelIdToString(profile_level_id)},
+ {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
+ {cricket::kH264FmtpPacketizationMode, "1"}};
+ return format;
+ }
+ if (profile.profile >= media::VP9PROFILE_MIN &&
+ profile.profile <= media::VP9PROFILE_MAX) {
+ return webrtc::SdpVideoFormat("VP9");
}
return base::nullopt;
-}
+} // namespace
bool IsSameFormat(const webrtc::SdpVideoFormat& format1,
const webrtc::SdpVideoFormat& format2) {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/task_queue_factory_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/task_queue_factory_test.cc
new file mode 100644
index 00000000000..8a34a04608f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/task_queue_factory_test.cc
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/webrtc_overrides/task_queue_factory.h"
+
+#include "base/task/task_traits.h"
+#include "base/test/task_environment.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/webrtc/api/task_queue/task_queue_test.h"
+
+namespace {
+
+using ::webrtc::TaskQueueTest;
+
+// Wrapper around WebrtcTaskQueueFactory to set up required testing environment.
+class TestTaskQueueFactory final : public webrtc::TaskQueueFactory {
+ public:
+ TestTaskQueueFactory() : factory_(CreateWebRtcTaskQueueFactory()) {}
+
+ std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
+ CreateTaskQueue(absl::string_view name, Priority priority) const override {
+ return factory_->CreateTaskQueue(name, priority);
+ }
+
+ private:
+ base::test::TaskEnvironment task_environment_;
+ std::unique_ptr<webrtc::TaskQueueFactory> factory_;
+};
+
+} // namespace
+
+INSTANTIATE_TEST_SUITE_P(
+ WebRtc,
+ TaskQueueTest,
+ ::testing::Values(std::make_unique<TestTaskQueueFactory>));
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.cc b/chromium/third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.cc
index 9ce0d60d4e9..e1020d02e2e 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.cc
@@ -10,10 +10,10 @@
#include "base/cpu.h"
#include "base/logging.h"
#include "base/system/sys_info.h"
-#include "third_party/blink/public/platform/modules/peerconnection/audio_codec_factory.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/media_capabilities/web_media_configuration.h"
#include "third_party/blink/renderer/platform/media_capabilities/web_video_configuration.h"
+#include "third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h"
#include "third_party/blink/renderer/platform/peerconnection/video_codec_factory.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/webrtc/api/audio_codecs/audio_encoder_factory.h"
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h
new file mode 100644
index 00000000000..792fc6562b7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h
@@ -0,0 +1,139 @@
+// Copyright (c) 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_TWO_KEYS_ADAPTER_MAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_TWO_KEYS_ADAPTER_MAP_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+
+namespace blink {
+
+// A map with up to two keys per entry. An element is inserted with a key, this
+// is the primary key. A secondary key can optionally be set to the same entry
+// and it may be set at a later point in time than the element was inserted. For
+// lookup and erasure both keys can be used.
+//
+// This was designed to assist the implementation of adapter maps. The adapters
+// are the glue between the blink and webrtc layer objects. The adapter maps
+// keep track of which blink and webrtc layer objects have which associated
+// adapter. This requires two keys per adapter entry: something that can be used
+// for lookup based on a webrtc layer object and something that can be used for
+// lookup based on a blink layer object. The primary key is based on the
+// webrtc/blink object that was used to create the adapter and the secondary key
+// is based on the resulting blink/webrtc object after the adapter has been
+// initialized.
+//
+// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+// its clients get Onion souped, and change the use of std::map below to
+// WTF::HashMap.
+template <typename PrimaryKey, typename SecondaryKey, typename Value>
+class TwoKeysAdapterMap {
+ public:
+ // Maps the primary key to the value, increasing |PrimarySize| by one and
+ // allowing lookup of the value based on primary key. Returns a pointer to the
+ // value in the map, the pointer is valid for as long as the value is in the
+ // map. There must not already exist a mapping for this primary key, in other
+ // words |!FindByPrimary(primary)| must hold.
+ Value* Insert(PrimaryKey primary, Value value) {
+ DCHECK(entries_by_primary_.find(primary) == entries_by_primary_.end());
+ auto it = entries_by_primary_
+ .insert(std::make_pair(
+ std::move(primary),
+ std::unique_ptr<Entry>(new Entry(std::move(value)))))
+ .first;
+ it->second->primary_it = it;
+ return &it->second->value;
+ }
+
+ // Maps the secondary key to the value mapped by the primary key, increasing
+ // |SecondarySize| by one and allowing lookup of the value based on secondary
+ // key.
+ // There must exist a mapping for this primary key and there must not already
+ // exist a mapping for this secondary key, in other words
+ // |FindByPrimary(primary) && !FindBySecondary(secondary)| must hold.
+ void SetSecondaryKey(const PrimaryKey& primary, SecondaryKey secondary) {
+ auto it = entries_by_primary_.find(primary);
+ DCHECK(it != entries_by_primary_.end());
+ DCHECK(entries_by_secondary_.find(secondary) ==
+ entries_by_secondary_.end());
+ Entry* entry = it->second.get();
+ entry->secondary_it =
+ entries_by_secondary_
+ .insert(std::make_pair(std::move(secondary), entry))
+ .first;
+ }
+
+ // Returns a pointer to the value mapped by the primary key, or null if the
+ // primary key is not mapped to any value. The pointer is valid for as long as
+ // the value is in the map.
+ Value* FindByPrimary(const PrimaryKey& primary) const {
+ auto it = entries_by_primary_.find(primary);
+ if (it == entries_by_primary_.end())
+ return nullptr;
+ return &it->second->value;
+ }
+
+ // Returns a pointer to the value mapped by the secondary key, or null if the
+ // secondary key is not mapped to any value. The pointer is valid for as long
+ // as the value is in the map.
+ Value* FindBySecondary(const SecondaryKey& secondary) const {
+ auto it = entries_by_secondary_.find(secondary);
+ if (it == entries_by_secondary_.end())
+ return nullptr;
+ return &it->second->value;
+ }
+
+ // Erases the value associated with the primary key, removing the mapping of
+ // of its primary and secondary key, if it had one. Returns true on removal or
+ // false if there was no value associated with the primary key.
+ bool EraseByPrimary(const PrimaryKey& primary) {
+ auto primary_it = entries_by_primary_.find(primary);
+ if (primary_it == entries_by_primary_.end())
+ return false;
+ if (primary_it->second->secondary_it != entries_by_secondary_.end())
+ entries_by_secondary_.erase(primary_it->second->secondary_it);
+ entries_by_primary_.erase(primary_it);
+ return true;
+ }
+
+ // Erases the value associated with the secondary key, removing the mapping of
+ // of both its primary and secondary keys. Returns true on removal or false if
+ // there was no value associated with the secondary key.
+ bool EraseBySecondary(const SecondaryKey& secondary) {
+ auto secondary_it = entries_by_secondary_.find(secondary);
+ if (secondary_it == entries_by_secondary_.end())
+ return false;
+ entries_by_primary_.erase(secondary_it->second->primary_it);
+ entries_by_secondary_.erase(secondary_it);
+ return true;
+ }
+
+ // The number of elements in the map.
+ size_t PrimarySize() const { return entries_by_primary_.size(); }
+ // The number of elements in the map which have secondary keys.
+ size_t SecondarySize() const { return entries_by_secondary_.size(); }
+ bool empty() const { return entries_by_primary_.empty(); }
+
+ private:
+ // TODO(crbug.com/787254): Move this class out of the Blink exposed API when
+ // its clients get Onion souped.
+ struct Entry {
+ Entry(Value value) : value(std::move(value)) {}
+
+ Value value;
+ typename std::map<PrimaryKey, std::unique_ptr<Entry>>::iterator primary_it;
+ typename std::map<SecondaryKey, Entry*>::iterator secondary_it;
+ };
+
+ typename std::map<PrimaryKey, std::unique_ptr<Entry>> entries_by_primary_;
+ typename std::map<SecondaryKey, Entry*> entries_by_secondary_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_TWO_KEYS_ADAPTER_MAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
index cf4e86c51da..0d27ce7e9ae 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/peerconnection/two_keys_adapter_map.h"
+#include "third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc b/chromium/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc
index 85ae4df4e58..4854229b4fb 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc
@@ -104,23 +104,36 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) override {
- std::unique_ptr<webrtc::VideoEncoder> software_encoder;
- if (IsFormatSupported(&software_encoder_factory_, format)) {
- software_encoder = std::make_unique<webrtc::EncoderSimulcastProxy>(
- &software_encoder_factory_, format);
+ const bool supported_in_software =
+ IsFormatSupported(&software_encoder_factory_, format);
+ const bool supported_in_hardware =
+ IsFormatSupported(hardware_encoder_factory_.get(), format);
+
+ if (!supported_in_software && !supported_in_hardware)
+ return nullptr;
+
+ if (base::EqualsCaseInsensitiveASCII(format.name.c_str(),
+ cricket::kVp9CodecName)) {
+ // For VP9, we don't use simulcast.
+ if (supported_in_hardware && supported_in_software) {
+ return Wrap(software_encoder_factory_.CreateVideoEncoder(format),
+ hardware_encoder_factory_->CreateVideoEncoder(format));
+ } else if (supported_in_software) {
+ return software_encoder_factory_.CreateVideoEncoder(format);
+ }
+ return hardware_encoder_factory_->CreateVideoEncoder(format);
}
- std::unique_ptr<webrtc::VideoEncoder> hardware_encoder;
- if (IsFormatSupported(hardware_encoder_factory_.get(), format)) {
- hardware_encoder =
- base::EqualsCaseInsensitiveASCII(format.name.c_str(),
- cricket::kVp9CodecName)
- ? hardware_encoder_factory_->CreateVideoEncoder(format)
- : std::make_unique<webrtc::SimulcastEncoderAdapter>(
- hardware_encoder_factory_.get(), format);
+ if (!supported_in_hardware || !hardware_encoder_factory_.get()) {
+ return std::make_unique<webrtc::SimulcastEncoderAdapter>(
+ &software_encoder_factory_, nullptr, format);
+ } else if (!supported_in_software) {
+ return std::make_unique<webrtc::SimulcastEncoderAdapter>(
+ hardware_encoder_factory_.get(), nullptr, format);
}
- return Wrap(std::move(software_encoder), std::move(hardware_encoder));
+ return std::make_unique<webrtc::SimulcastEncoderAdapter>(
+ hardware_encoder_factory_.get(), &software_encoder_factory_, format);
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
index f70a1d098ec..0f6c85f8258 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
@@ -2,18 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/peerconnection/webrtc_audio_sink.h"
+#include "third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h"
#include <algorithm>
#include <limits>
-#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/stl_util.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<scoped_refptr<webrtc::AudioProcessorInterface>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<webrtc::AudioProcessorInterface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<scoped_refptr<blink::WebRtcAudioSink::Adapter>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<blink::WebRtcAudioSink::Adapter>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
namespace blink {
WebRtcAudioSink::WebRtcAudioSink(
@@ -26,8 +45,9 @@ WebRtcAudioSink::WebRtcAudioSink(
std::move(track_source),
std::move(signaling_task_runner),
std::move(main_task_runner))),
- fifo_(base::BindRepeating(&WebRtcAudioSink::DeliverRebufferedAudio,
- base::Unretained(this))) {
+ fifo_(ConvertToBaseRepeatingCallback(
+ CrossThreadBindRepeating(&WebRtcAudioSink::DeliverRebufferedAudio,
+ CrossThreadUnretained(this)))) {
DVLOG(1) << "WebRtcAudioSink::WebRtcAudioSink()";
}
@@ -52,10 +72,11 @@ void WebRtcAudioSink::SetLevel(
void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- adapter_->signaling_task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(base::IgnoreResult(&WebRtcAudioSink::Adapter::set_enabled),
- adapter_, enabled));
+ PostCrossThreadTask(
+ *adapter_->signaling_task_runner(), FROM_HERE,
+ CrossThreadBindOnce(
+ base::IgnoreResult(&WebRtcAudioSink::Adapter::set_enabled), adapter_,
+ enabled));
}
void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
@@ -117,9 +138,9 @@ WebRtcAudioSink::Adapter::Adapter(
WebRtcAudioSink::Adapter::~Adapter() {
if (audio_processor_) {
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&DereferenceOnMainThread, std::move(audio_processor_)));
+ PostCrossThreadTask(*main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&DereferenceOnMainThread,
+ std::move(audio_processor_)));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h
new file mode 100644
index 00000000000..b405636dffe
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h
@@ -0,0 +1,190 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_AUDIO_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_AUDIO_SINK_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/audio_push_fifo.h"
+#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/media_stream_interface.h"
+#include "third_party/webrtc/pc/media_stream_track.h"
+
+namespace blink {
+
+// Provides an implementation of the WebMediaStreamAudioSink which
+// re-chunks audio data into the 10ms chunks required by WebRTC and then
+// delivers the audio to one or more objects implementing the
+// webrtc::AudioTrackSinkInterface.
+//
+// The inner class, Adapter, implements the webrtc::AudioTrackInterface and
+// manages one or more "WebRTC sinks" (i.e., instances of
+// webrtc::AudioTrackSinkInterface) which are added/removed on the WebRTC
+// signaling thread.
+//
+// TODO(crbug.com/787254): Switch this class away from using std::string and
+// std::vector. Also merge it with WebMediaStreamAudioSink.
+class PLATFORM_EXPORT WebRtcAudioSink : public WebMediaStreamAudioSink {
+ public:
+ WebRtcAudioSink(
+ const std::string& label,
+ scoped_refptr<webrtc::AudioSourceInterface> track_source,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+
+ ~WebRtcAudioSink() override;
+
+ webrtc::AudioTrackInterface* webrtc_audio_track() const {
+ return adapter_.get();
+ }
+
+ // Set the object that provides shared access to the current audio signal
+ // level. This is passed via the Adapter to libjingle. This method may only
+ // be called once, before the audio data flow starts, and before any calls to
+ // Adapter::GetSignalLevel() might be made.
+ void SetLevel(scoped_refptr<MediaStreamAudioLevelCalculator::Level> level);
+
+ // Set the processor that applies signal processing on the data from the
+ // source. This is passed via the Adapter to libjingle. This method may only
+ // be called once, before the audio data flow starts, and before any calls to
+ // GetAudioProcessor() might be made.
+ void SetAudioProcessor(
+ scoped_refptr<webrtc::AudioProcessorInterface> processor);
+
+ // MediaStreamSink override.
+ void OnEnabledChanged(bool enabled) override;
+
+ private:
+ // Private implementation of the webrtc::AudioTrackInterface whose control
+ // methods are all called on the WebRTC signaling thread. This class is
+ // ref-counted, per the requirements of webrtc::AudioTrackInterface.
+ class Adapter : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
+ public:
+ Adapter(const std::string& label,
+ scoped_refptr<webrtc::AudioSourceInterface> source,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+
+ base::SingleThreadTaskRunner* signaling_task_runner() const {
+ return signaling_task_runner_.get();
+ }
+
+ // These setters are called before the audio data flow starts, and before
+ // any methods called on the signaling thread reference these objects.
+ void set_processor(
+ scoped_refptr<webrtc::AudioProcessorInterface> processor) {
+ audio_processor_ = std::move(processor);
+ }
+ void set_level(
+ scoped_refptr<MediaStreamAudioLevelCalculator::Level> level) {
+ level_ = std::move(level);
+ }
+
+ // Delivers a 10ms chunk of audio to all WebRTC sinks managed by this
+ // Adapter. This is called on the audio thread.
+ void DeliverPCMToWebRtcSinks(const int16_t* audio_data,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_frames);
+
+ // webrtc::MediaStreamTrack implementation.
+ std::string kind() const override;
+ bool set_enabled(bool enable) override;
+
+ // webrtc::AudioTrackInterface implementation.
+ void AddSink(webrtc::AudioTrackSinkInterface* sink) override;
+ void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override;
+ bool GetSignalLevel(int* level) override;
+ rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
+ override;
+ webrtc::AudioSourceInterface* GetSource() const override;
+
+ protected:
+ ~Adapter() override;
+
+ private:
+ const scoped_refptr<webrtc::AudioSourceInterface> source_;
+
+ // Task runner for operations that must be done on libjingle's signaling
+ // thread.
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+
+ // Task runner used for the final de-referencing of |audio_processor_| at
+ // destruction time.
+ //
+ // TODO(miu): Remove this once MediaStreamAudioProcessor is fixed.
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+
+ // The audio processsor that applies audio post-processing on the source
+ // audio. This is null if there is no audio processing taking place
+ // upstream. This must be set before calls to GetAudioProcessor() are made.
+ scoped_refptr<webrtc::AudioProcessorInterface> audio_processor_;
+
+ // Thread-safe accessor to current audio signal level. This may be null, if
+ // not applicable to the current use case. This must be set before calls to
+ // GetSignalLevel() are made.
+ scoped_refptr<MediaStreamAudioLevelCalculator::Level> level_;
+
+ // Lock that protects concurrent access to the |sinks_| list.
+ base::Lock lock_;
+
+ // A vector of pointers to unowned WebRTC-internal objects which each
+ // receive the audio data.
+ std::vector<webrtc::AudioTrackSinkInterface*> sinks_;
+
+ DISALLOW_COPY_AND_ASSIGN(Adapter);
+ };
+
+ template <typename>
+ friend struct WTF::CrossThreadCopier;
+
+ // WebMediaStreamAudioSink implementation.
+ void OnData(const media::AudioBus& audio_bus,
+ base::TimeTicks estimated_capture_time) override;
+ void OnSetFormat(const media::AudioParameters& params) override;
+
+ // Called by AudioPushFifo zero or more times during the call to OnData().
+ // Delivers audio data with the required 10ms buffer size to |adapter_|.
+ void DeliverRebufferedAudio(const media::AudioBus& audio_bus,
+ int frame_delay);
+
+ // Owner of the WebRTC sinks. May outlive this WebRtcAudioSink (if references
+ // are held by libjingle).
+ const scoped_refptr<Adapter> adapter_;
+
+ // The current format of the audio passing through this sink.
+ media::AudioParameters params_;
+
+ // Light-weight fifo used for re-chunking audio into the 10ms chunks required
+ // by the WebRTC sinks.
+ media::AudioPushFifo fifo_;
+
+ // Buffer used for converting into the required signed 16-bit integer
+ // interleaved samples.
+ std::unique_ptr<int16_t[]> interleaved_data_;
+
+ // In debug builds, check that WebRtcAudioSink's public methods are all being
+ // called on the main render thread.
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcAudioSink);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_AUDIO_SINK_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_util.h b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_util.h
new file mode 100644
index 00000000000..65d7dace210
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_util.h
@@ -0,0 +1,49 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_UTIL_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_UTIL_H_
+
+#include "base/optional.h"
+
+namespace blink {
+
+// TODO(crbug.com/787254): Move these template definitions out of the Blink
+// exposed API when all their clients get Onion souped.
+template <typename OptionalT>
+base::Optional<typename OptionalT::value_type> ToBaseOptional(
+ const OptionalT& optional) {
+ return optional ? base::make_optional(*optional) : base::nullopt;
+}
+
+template <typename OptionalT>
+base::Optional<typename OptionalT::value_type> ToBaseOptional(
+ OptionalT&& optional) {
+ return optional ? base::make_optional(*optional) : base::nullopt;
+}
+
+template <typename OptionalT>
+absl::optional<typename OptionalT::value_type> ToAbslOptional(
+ const OptionalT& optional) {
+ return optional ? absl::make_optional(*optional) : absl::nullopt;
+}
+
+template <typename OptionalT>
+absl::optional<typename OptionalT::value_type> ToAbslOptional(
+ OptionalT&& optional) {
+ return optional ? absl::make_optional(*optional) : absl::nullopt;
+}
+
+template <typename OptionalT1, typename OptionalT2>
+bool OptionalEquals(const OptionalT1& lhs, const OptionalT2& rhs) {
+ if (!lhs)
+ return !rhs;
+ if (!rhs)
+ return false;
+ return *lhs == *rhs;
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_UTIL_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
index 1698102ad64..0fcc39afecb 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/peerconnection/webrtc_video_track_source.h"
+#include "third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/trace_event/trace_event.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h"
#include "third_party/libyuv/include/libyuv/scale.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -25,6 +26,43 @@ gfx::Rect CropRectangle(const gfx::Rect& input_rect,
return result;
}
+gfx::Rect ScaleRectangle(const gfx::Rect& input_rect,
+ gfx::Size original,
+ gfx::Size scaled) {
+ if (input_rect.IsEmpty()) {
+ return input_rect;
+ }
+ gfx::Rect result;
+ // Rounded down.
+ result.set_x(input_rect.x() * scaled.width() / original.width());
+ result.set_y(input_rect.y() * scaled.height() / original.height());
+ // rounded up.
+ result.set_width(input_rect.width() * scaled.width() / original.width());
+ result.set_height(input_rect.height() * scaled.height() / original.height());
+ // Snap to 2x2 grid because of UV subsampling.
+ if (result.x() % 2) {
+ result.set_x(result.x() - 1);
+ result.set_width(result.width() + 1);
+ }
+ if (result.y() % 2) {
+ result.set_y(result.y() - 1);
+ result.set_height(result.height() + 1);
+ }
+ if (result.width() % 2) {
+ result.set_width(result.width() + 1);
+ }
+ if (result.height() % 2) {
+ result.set_height(result.height() + 1);
+ }
+ // Expand the rect by 2 pixels in each direction, to include any possible
+ // scaling artifacts.
+ result.set_x(result.x() - 2);
+ result.set_y(result.y() - 2);
+ result.set_width(result.width() + 4);
+ result.set_height(result.height() + 4);
+ result.Intersect(gfx::Rect(0, 0, scaled.width(), scaled.height()));
+ return result;
+}
} // anonymous namespace
namespace blink {
@@ -98,15 +136,22 @@ void WebRtcVideoTrackSource::OnFrameCaptured(
DVLOG(3) << "has_valid_update_rect = " << has_valid_update_rect;
if (has_capture_counter)
previous_capture_counter_ = capture_counter;
- if (has_valid_update_rect)
- accumulated_update_rect_.Union(update_rect);
- else
- accumulated_update_rect_.Union(gfx::Rect(frame->coded_size()));
+ if (has_valid_update_rect) {
+ if (!accumulated_update_rect_) {
+ accumulated_update_rect_ = update_rect;
+ } else {
+ accumulated_update_rect_->Union(update_rect);
+ }
+ } else {
+ accumulated_update_rect_ = base::nullopt;
+ }
- DVLOG(3) << "accumulated_update_rect_ = [" << accumulated_update_rect_.x()
- << ", " << accumulated_update_rect_.y() << ", "
- << accumulated_update_rect_.width() << ", "
- << accumulated_update_rect_.height() << "]";
+ if (accumulated_update_rect_) {
+ DVLOG(3) << "accumulated_update_rect_ = [" << accumulated_update_rect_->x()
+ << ", " << accumulated_update_rect_->y() << ", "
+ << accumulated_update_rect_->width() << ", "
+ << accumulated_update_rect_->height() << "]";
+ }
// Calculate desired target cropping and scaling of the received frame. Note,
// that the frame may already have some cropping and scaling soft-applied via
@@ -132,9 +177,14 @@ void WebRtcVideoTrackSource::OnFrameCaptured(
frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
// The webrtc::VideoFrame::UpdateRect expected by WebRTC must
// be relative to the |visible_rect()|. We need to translate.
- const auto cropped_rect =
- CropRectangle(accumulated_update_rect_, frame->visible_rect());
- DeliverFrame(std::move(frame), cropped_rect, translated_camera_time_us);
+ base::Optional<gfx::Rect> cropped_rect;
+ if (accumulated_update_rect_) {
+ cropped_rect =
+ CropRectangle(*accumulated_update_rect_, frame->visible_rect());
+ }
+
+ DeliverFrame(std::move(frame), OptionalOrNullptr(cropped_rect),
+ translated_camera_time_us);
return;
}
@@ -168,29 +218,34 @@ void WebRtcVideoTrackSource::OnFrameCaptured(
if (!video_frame)
return;
+ // The webrtc::VideoFrame::UpdateRect expected by WebRTC must be
+ // relative to the |visible_rect()|. We need to translate.
+ if (accumulated_update_rect_) {
+ accumulated_update_rect_ =
+ CropRectangle(*accumulated_update_rect_, frame->visible_rect());
+ }
+
// If no scaling is needed, return a wrapped version of |frame| directly.
// The soft-applied cropping will be taken into account by the remainder
// of the pipeline.
if (video_frame->natural_size() == video_frame->visible_rect().size()) {
- // The webrtc::VideoFrame::UpdateRect expected by WebRTC must be
- // relative to the |visible_rect()|. We need to translate.
- const auto cropped_rect =
- CropRectangle(accumulated_update_rect_, video_frame->visible_rect());
- DeliverFrame(std::move(video_frame), cropped_rect,
+ DeliverFrame(std::move(video_frame),
+ OptionalOrNullptr(accumulated_update_rect_),
translated_camera_time_us);
return;
}
+ if (accumulated_update_rect_) {
+ accumulated_update_rect_ = ScaleRectangle(
+ *accumulated_update_rect_, video_frame->visible_rect().size(),
+ video_frame->natural_size());
+ }
+
// Delay scaling if |video_frame| is backed by GpuMemoryBuffer.
if (video_frame->storage_type() ==
media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
- // When scaling is applied and any part of the frame has changed, we mark
- // the whole frame as changed.
- const auto update_rect_on_scaled =
- accumulated_update_rect_.IsEmpty()
- ? gfx::Rect()
- : gfx::Rect(video_frame->natural_size());
- DeliverFrame(std::move(video_frame), update_rect_on_scaled,
+ DeliverFrame(std::move(video_frame),
+ OptionalOrNullptr(accumulated_update_rect_),
translated_camera_time_us);
return;
}
@@ -228,14 +283,9 @@ void WebRtcVideoTrackSource::OnFrameCaptured(
adapted_size.width(), adapted_size.height(),
libyuv::kFilterBilinear);
}
- // When scaling is applied and any part of the frame has changed, we mark the
- // whole frame as changed.
- DeliverFrame(
- std::move(scaled_frame),
- accumulated_update_rect_.IsEmpty()
- ? gfx::Rect()
- : gfx::Rect(0, 0, adapted_size.width(), adapted_size.height()),
- translated_camera_time_us);
+ DeliverFrame(std::move(scaled_frame),
+ OptionalOrNullptr(accumulated_update_rect_),
+ translated_camera_time_us);
}
WebRtcVideoTrackSource::FrameAdaptationParams
@@ -254,11 +304,13 @@ WebRtcVideoTrackSource::ComputeAdaptationParams(int width,
void WebRtcVideoTrackSource::DeliverFrame(
scoped_refptr<media::VideoFrame> frame,
- gfx::Rect update_rect,
+ gfx::Rect* update_rect,
int64_t timestamp_us) {
- DVLOG(3) << "update_rect = "
- << "[" << update_rect.x() << ", " << update_rect.y() << ", "
- << update_rect.width() << ", " << update_rect.height() << "]";
+ if (update_rect) {
+ DVLOG(3) << "update_rect = "
+ << "[" << update_rect->x() << ", " << update_rect->y() << ", "
+ << update_rect->width() << ", " << update_rect->height() << "]";
+ }
// If the cropping or the size have changed since the previous
// frame, even if nothing in the incoming coded frame content has changed, we
@@ -267,27 +319,24 @@ void WebRtcVideoTrackSource::DeliverFrame(
frame->natural_size() != natural_size_of_previous_delivered_frame_) {
cropping_rect_of_previous_delivered_frame_ = frame->visible_rect();
natural_size_of_previous_delivered_frame_ = frame->natural_size();
- if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
- // Use the frame natural size since we delay the scaling.
- update_rect = gfx::Rect(frame->natural_size());
- } else {
- update_rect = gfx::Rect(0, 0, frame->visible_rect().width(),
- frame->visible_rect().height());
- }
+ update_rect = nullptr;
}
+ webrtc::VideoFrame::Builder frame_builder =
+ webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(
+ new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame))
+ .set_rotation(webrtc::kVideoRotation_0)
+ .set_timestamp_us(timestamp_us);
+ if (update_rect) {
+ frame_builder.set_update_rect(webrtc::VideoFrame::UpdateRect{
+ update_rect->x(), update_rect->y(), update_rect->width(),
+ update_rect->height()});
+ }
+ OnFrame(frame_builder.build());
+
// Clear accumulated_update_rect_.
accumulated_update_rect_ = gfx::Rect();
-
- OnFrame(webrtc::VideoFrame::Builder()
- .set_video_frame_buffer(
- new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame))
- .set_rotation(webrtc::kVideoRotation_0)
- .set_timestamp_us(timestamp_us)
- .set_update_rect(webrtc::VideoFrame::UpdateRect{
- update_rect.x(), update_rect.y(), update_rect.width(),
- update_rect.height()})
- .build());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h
new file mode 100644
index 00000000000..9a6c26f42cb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h
@@ -0,0 +1,88 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_VIDEO_TRACK_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_VIDEO_TRACK_SOURCE_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/threading/thread_checker.h"
+#include "media/base/video_frame_pool.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/media/base/adapted_video_track_source.h"
+#include "third_party/webrtc/rtc_base/timestamp_aligner.h"
+
+namespace blink {
+
+// This class implements webrtc's VideoTrackSourceInterface. To pass frames down
+// the webrtc video pipeline, each received a media::VideoFrame is converted to
+// a webrtc::VideoFrame, taking any adaptation requested by downstream classes
+// into account.
+class PLATFORM_EXPORT WebRtcVideoTrackSource
+ : public rtc::AdaptedVideoTrackSource {
+ public:
+ struct FrameAdaptationParams {
+ bool should_drop_frame;
+ int crop_x;
+ int crop_y;
+ int crop_width;
+ int crop_height;
+ int scale_to_width;
+ int scale_to_height;
+ };
+
+ WebRtcVideoTrackSource(bool is_screencast,
+ absl::optional<bool> needs_denoising);
+ ~WebRtcVideoTrackSource() override;
+
+ void SetCustomFrameAdaptationParamsForTesting(
+ const FrameAdaptationParams& params);
+
+ SourceState state() const override;
+
+ bool remote() const override;
+ bool is_screencast() const override;
+ absl::optional<bool> needs_denoising() const override;
+ void OnFrameCaptured(scoped_refptr<media::VideoFrame> frame);
+
+ using webrtc::VideoTrackSourceInterface::AddOrUpdateSink;
+ using webrtc::VideoTrackSourceInterface::RemoveSink;
+
+ private:
+ FrameAdaptationParams ComputeAdaptationParams(int width,
+ int height,
+ int64_t time_us);
+
+ // Delivers |frame| to base class method
+ // rtc::AdaptedVideoTrackSource::OnFrame(). If the cropping (given via
+ // |frame->visible_rect()|) has changed since the last delivered frame, the
+ // whole frame is marked as updated.
+ void DeliverFrame(scoped_refptr<media::VideoFrame> frame,
+ gfx::Rect* update_rect,
+ int64_t timestamp_us);
+
+ // |thread_checker_| is bound to the libjingle worker thread.
+ THREAD_CHECKER(thread_checker_);
+ media::VideoFramePool scaled_frame_pool_;
+ // State for the timestamp translation.
+ rtc::TimestampAligner timestamp_aligner_;
+
+ const bool is_screencast_;
+ const absl::optional<bool> needs_denoising_;
+
+ // Stores the accumulated value of CAPTURE_UPDATE_RECT in case that frames
+ // are dropped.
+ base::Optional<gfx::Rect> accumulated_update_rect_;
+ base::Optional<int> previous_capture_counter_;
+ gfx::Rect cropping_rect_of_previous_delivered_frame_;
+ gfx::Size natural_size_of_previous_delivered_frame_;
+
+ absl::optional<FrameAdaptationParams>
+ custom_frame_adaptation_params_for_testing_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcVideoTrackSource);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_VIDEO_TRACK_SOURCE_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
index 5d339e4e602..bd1958dee5b 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
@@ -10,7 +10,7 @@
#include "media/base/video_frame.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/peerconnection/webrtc_video_track_source.h"
+#include "third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h"
#include "third_party/blink/renderer/platform/testing/video_frame_utils.h"
#include "third_party/webrtc/api/video/video_frame.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -358,24 +358,23 @@ TEST_P(WebRtcVideoTrackSourceTest, UpdateRectWithScaling) {
FrameAdaptation_Scale(kNaturalSize, kScaleToSize));
// Any UPDATE_RECT for the first received frame is expected to get
- // ignored and the full frame should be marked as updated.
+ // ignored and no update rect should be set.
const gfx::Rect kUpdateRect1(120, 70, 160, 40);
EXPECT_CALL(mock_sink_, OnFrame(_))
.WillOnce(Invoke([](const webrtc::VideoFrame& frame) {
- ExpectUpdateRectEquals(gfx::Rect(0, 0, frame.width(), frame.height()),
- frame.update_rect());
+ EXPECT_FALSE(frame.has_update_rect());
}));
int capture_counter = 101; // arbitrary absolute value
SendTestFrameWithUpdateRect(kCodedSize, kVisibleRect, kNaturalSize,
capture_counter, kUpdateRect1, storage_type);
Mock::VerifyAndClearExpectations(&mock_sink_);
- // When scaling is applied and UPDATE_RECT is not empty, we always expect a
- // full update rect.
+ // When scaling is applied and UPDATE_RECT is not empty, we scale the
+ // update rect.
+ // Calculated by hand according to KNaturalSize and KScaleToSize.
EXPECT_CALL(mock_sink_, OnFrame(_))
.WillOnce(Invoke([](const webrtc::VideoFrame& frame) {
- ExpectUpdateRectEquals(gfx::Rect(0, 0, frame.width(), frame.height()),
- frame.update_rect());
+ ExpectUpdateRectEquals(gfx::Rect(10, 10, 100, 30), frame.update_rect());
}));
SendTestFrameWithUpdateRect(kCodedSize, kVisibleRect, kNaturalSize,
++capture_counter, kUpdateRect1, storage_type);
@@ -390,11 +389,10 @@ TEST_P(WebRtcVideoTrackSourceTest, UpdateRectWithScaling) {
++capture_counter, gfx::Rect(), storage_type);
// When UPDATE_RECT is empty, but the scaling has changed, we expect to
- // deliver an full UpdateRect.
+ // deliver no known update_rect.
EXPECT_CALL(mock_sink_, OnFrame(_))
.WillOnce(Invoke([](const webrtc::VideoFrame& frame) {
- ExpectUpdateRectEquals(gfx::Rect(0, 0, frame.width(), frame.height()),
- frame.update_rect());
+ EXPECT_FALSE(frame.has_update_rect());
}));
const gfx::Size kScaleToSize2 = gfx::Size(60, 26);
track_source_->SetCustomFrameAdaptationParamsForTesting(
diff --git a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 1cdb197f045..fb78dd6dfb9 100644
--- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -62,15 +62,31 @@
// feature with the Origin Trials framework. The framework allows the
// feature to be enabled at runtime on a per-page basis through a signed
// token for the corresponding feature name. Declaring the
- // origin_trial_feature_name will cause a static method to be generated in
- // origin_trials.h/cpp. This static method allows the feature implementation
- // to check if it is enabled for the current context.
+ // origin_trial_feature_name will modify the generation of the static
+ // methods in runtime_enabled_features.h/cpp. The static method then allows
+ // the feature implementation to check if the trial is enabled for the
+ // current context.
origin_trial_feature_name: {
},
+ // origin_trial_os specifies the platforms where the trial is available.
+ // The default is empty, meaning all platforms.
origin_trial_os: {
default: [],
valid_type: "list",
},
+ // origin_trial_type specifies the unique type of the trial, when not the
+ // usual trial for a new experimental feature.
+ origin_trial_type: {
+ default: "",
+ valid_type: "str",
+ valid_values: ["deprecation", "intervention", ""],
+ },
+ // origin_trial_allows_insecure specifies whether the trial can be enabled
+ // in an insecure context, with default being false. This can only be set
+ // to true for a "deprecation" type trial.
+ origin_trial_allows_insecure: {
+ valid_type: "bool",
+ },
// settable_from_internals specifies whether a feature can be set from
// internals.runtimeFlags, with the default being false.
@@ -100,6 +116,7 @@
},
{
name: "AccessibilityExposeARIAAnnotations",
+ origin_trial_feature_name: "AccessibilityExposeARIAAnnotations",
status: "experimental",
},
{
@@ -138,7 +155,11 @@
status: "experimental",
},
{
- name: "AOMPhase1",
+ name: "AOMAriaProperties",
+ status: "experimental",
+ },
+ {
+ name: "AOMAriaRelationshipProperties",
status: "experimental",
},
{
@@ -230,7 +251,7 @@
name: "BlockHTMLParserOnStyleSheets",
},
{
- name: "BlockingDownloadsInSandboxWithoutUserActivation",
+ name: "BlockingDownloadsInSandbox",
status: "test",
},
{
@@ -262,8 +283,9 @@
name: "CacheInlineScriptCode"
},
{
- name: "CacheStorageAddAllRejectsDuplicates",
- status: "stable",
+ name: "CacheStorageCodeCacheHint",
+ origin_trial_feature_name: "CacheStorageCodeCacheHint",
+ status: "experimental",
},
{
name: "Canvas2dContextLostRestored",
@@ -297,6 +319,13 @@
status: "experimental",
},
{
+ name: "CloneableNativeFileSystemHandles",
+ status: {"Android": "test", "default": "experimental"},
+ // NativeFileSystem is in Origin Trial, which doesn't support having
+ // non-origin-trial-enabled features depend on it. https://crbug.com/1000486
+ // depends_on: ["NativeFileSystem"]
+ },
+ {
name: "CompositeAfterPaint",
},
{
@@ -308,10 +337,6 @@
status: "test",
},
{
- name: "CompressionStreams",
- status: "experimental",
- },
- {
name: "ComputedAccessibilityInfo",
status: "experimental",
},
@@ -320,16 +345,18 @@
},
{
name: "ContactsManager",
- origin_trial_feature_name: "ContactsManager",
- origin_trial_os: ["android"],
- status: {"Android": "experimental", "default": "test"},
+ status: {"Android": "stable", "default": "test"},
},
{
- name: "ContactsManagerAddresses",
+ name: "ContactsManagerExtraProperties",
+ origin_trial_feature_name: "ContactsManagerExtraProperties",
+ origin_trial_os: ["android"],
status: {"Android": "experimental", "default": "test"},
},
{
name: "ContentIndex",
+ origin_trial_feature_name: "ContentIndex",
+ origin_trial_os: ["android"],
status: "experimental",
},
{
@@ -347,7 +374,7 @@
},
{
name: "CookiesWithoutSameSiteMustBeSecure",
- status: "experimental",
+ status: "test",
},
{
name: "CooperativeScheduling"
@@ -362,7 +389,7 @@
},
{
name: "CSS3TextBreakAnywhere",
- status: "experimental",
+ status: "stable",
},
{
name: "CSSAdditiveAnimations",
@@ -370,10 +397,6 @@
status: "experimental",
},
{
- name: "CSSBackdropFilter",
- status: "stable",
- },
- {
name: "CSSCalcAsInt",
status: "test",
},
@@ -392,13 +415,6 @@
status: "stable",
},
{
- // Support for CSS content-size property.
- // http://tabatkins.github.io/specs/css-content-size/
- name: "CSSContentSize",
- implied_by: ["DisplayLocking"],
- status: "experimental",
- },
- {
name: "CSSFocusVisible",
status: "experimental",
},
@@ -418,6 +434,13 @@
status: "experimental",
},
{
+ // Support for CSS intrinsic-* sizing properties.
+ // https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override
+ name: "CSSIntrinsicSize",
+ implied_by: ["DisplayLocking"],
+ status: "experimental",
+ },
+ {
name: "CSSLayoutAPI",
status: "experimental",
},
@@ -431,6 +454,10 @@
status: "test",
},
{
+ name: "CSSMarkerPseudoElement",
+ status: "experimental",
+ },
+ {
name: "CSSMaskSourceType",
status: "experimental",
},
@@ -469,6 +496,10 @@
status: "experimental",
},
{
+ name: "CSSRenderSubtree",
+ status: "test",
+ },
+ {
name: "CSSSnapSize",
status: "experimental",
},
@@ -502,12 +533,14 @@
name: "CustomElementDefaultStyle",
status: "experimental",
},
- // Introduced this flag as stable so web developers can test their sites
- // without native Custom Elements v0 support.
+ // TODO(937746): Web Components v0 is disabled by default, and will be
+ // removed after M87.
{
name: "CustomElementsV0",
origin_trial_feature_name: "WebComponentsV0",
- status: "stable",
+ origin_trial_type: "deprecation",
+ origin_trial_allows_insecure: true,
+ status: "test",
},
{
name: "CustomStatePseudoClass",
@@ -519,7 +552,6 @@
},
{
name: "DecodeJpeg420ImagesToYUV",
- status: "test"
},
{
name: "DecodeLossyWebPImagesToYUV",
@@ -535,6 +567,10 @@
status: "experimental",
},
{
+ name: "DisallowDocumentAccess",
+ status: "experimental",
+ },
+ {
name: "DiscardInputToMovingIframes",
status: "stable",
},
@@ -560,14 +596,13 @@
name: "DocumentWrite",
},
{
- // http://crbug.com/707656 content editable in LayoutNG.
- name: "EditingNG",
+ name: "EditContext",
+ settable_from_internals: true,
+ status: "test",
},
{
- // http://crbug.com/905922
- name: "ElementInternals",
- status: "stable",
- implied_by: ["FormAssociatedCustomElements"],
+ // http://crbug.com/707656 content editable in LayoutNG.
+ name: "EditingNG",
},
{
name: "EmbeddedVTTStylesheets",
@@ -651,10 +686,6 @@
status: "experimental",
},
{
- name: "FastMobileScrolling",
- status: {"Android": "stable"},
- },
- {
name: "FeaturePolicyForClientHints",
status: "experimental",
},
@@ -697,6 +728,7 @@
// flat-tree instead of shadow-including ancestors for child dirtiness.
{
name: "FlatTreeStyleRecalc",
+ status: "stable",
},
{
name: "FocuslessSpatialNavigation",
@@ -725,20 +757,12 @@
name: "ForceTallerSelectPopup",
status: {"ChromeOS": "stable"},
},
- {
- name: "FormAssociatedCustomElements",
- status: "stable",
- },
// This is to communicate features::FormControlsRefresh from ui (and can be
// removed when the feature launches).
{
name: "FormControlsRefresh",
},
{
- name: "FormDataEvent",
- status: "stable",
- },
- {
name: "FractionalMouseEvent",
},
{
@@ -767,20 +791,14 @@
origin_trial_feature_name: "HrefTranslate",
status: "experimental",
},
- // https://crbug.com/766694 for testing disabling the feature.
+ // TODO(937746): Web Components v0 is disabled by default, and will be
+ // removed after M87.
{
name: "HTMLImports",
origin_trial_feature_name: "WebComponentsV0",
- status: "stable",
- },
- // Allow import only chrome internal resources.
- {
- name: "HTMLImportsOnlyChrome",
- },
- // https://crbug.com/523952 for testing disabling the feature.
- {
- name: "HTMLImportsStyleApplication",
- status: "stable",
+ origin_trial_type: "deprecation",
+ origin_trial_allows_insecure: true,
+ status: "test",
},
{
name: "IDBObserver",
@@ -822,8 +840,7 @@
},
{
name: "InstalledApp",
- origin_trial_feature_name: "InstalledApp",
- status: "experimental",
+ status: "stable",
},
{
name: "IntersectionObserverDocumentScrollingElementRoot",
@@ -864,7 +881,7 @@
},
{
name: "LayoutNG",
- implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFlexBox", "LayoutNGFragmentItem", "LayoutNGFragmentPaint", "LayoutNGLineCache", "EditingNG", "BidiCaretAffinity", "LayoutNGTable"],
+ implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFlexBox", "LayoutNGFragmentItem", "LayoutNGLineCache", "EditingNG", "BidiCaretAffinity", "LayoutNGTable"],
status: "stable",
},
{
@@ -885,6 +902,7 @@
},
{
name: "LayoutNGFragmentPaint",
+ implied_by: ["LayoutNG"],
},
{
name: "LayoutNGLineCache",
@@ -927,6 +945,11 @@
status:"experimental",
},
{
+ name: "MathMLCore",
+ status:"test",
+ depends_on: ["LayoutNG"],
+ },
+ {
name:"MeasureMemory",
status:"experimental",
},
@@ -936,8 +959,11 @@
},
{
name: "MediaCapabilitiesEncryptedMedia",
- origin_trial_feature_name: "MediaCapabilitiesEncryptedMedia",
- status: "experimental",
+ status: "stable",
+ },
+ {
+ name: "MediaCapabilitiesSpatialAudio",
+ status: "test",
},
{
name: "MediaCapture",
@@ -974,6 +1000,10 @@
name: "MediaEngagementBypassAutoplayPolicies",
},
{
+ name: "MediaLatencyHint",
+ status: "test",
+ },
+ {
name: "MediaQueryNavigationControls",
},
{
@@ -1016,9 +1046,6 @@
name: "MediaSourceStable",
status: "stable",
},
- {
- name: "MergeBlockingNonBlockingPools",
- },
// Support for META tag for setting color-scheme used for opting into dark
// UA theming and opting out of forced dark mode.
// https://drafts.csswg.org/css-color-adjust/#color-scheme-meta
@@ -1031,17 +1058,13 @@
name: "MiddleClickAutoscroll",
status: "test",
},
- // Specific mime-types such as PDF are rendered in cross-process frames.
- {
- name: "MimeHandlerViewInCrossProcessFrame",
- },
{
name: "MobileLayoutTheme",
},
{
name: "ModuleDedicatedWorker",
- status: "experimental",
+ status: "stable",
},
{
name: "ModuleServiceWorker",
@@ -1065,7 +1088,7 @@
// Also enabled when blink::features::kNativeFileSystemAPI is overridden
// on the command line (or via chrome://flags).
name: "NativeFileSystem",
- status: "experimental",
+ status: {"Android": "test", "default": "experimental"},
origin_trial_feature_name: "NativeFileSystem",
origin_trial_os: ["win", "macosx", "linux", "chromeos"],
},
@@ -1087,11 +1110,18 @@
// Only Android, ChromeOS support NetInfo downlinkMax, type and ontypechange now
status: {"Android": "stable", "ChromeOS": "stable"},
},
+ {
+ name: "NeverSlowMode",
+ },
// Not a web exposed feature, enabled from the command line.
{
name: "NewRemotePlaybackPipeline",
},
{
+ name: "NewSystemColors",
+ status: "stable",
+ },
+ {
name: "NoIdleEncodingForWebTests",
status: "test",
},
@@ -1141,25 +1171,37 @@
name: "OriginTrialsSampleAPI",
origin_trial_feature_name: "Frobulate",
},
+ // As above. Do not change this flag to stable, as it exists solely to
+ // generate code used by the origin trials sample API implementation.
// TODO(yashard): Add tests for this feature.
{
name: "OriginTrialsSampleAPIDependent",
depends_on: ["OriginTrialsSampleAPI"],
},
- // Define a sample API for testing integration with the Origin Trials
- // Framework. The sample API is used in both unit and web tests for the
- // Origin Trials Framework. Do not change this flag to stable, as it exists
- // solely to generate code used by the sample API implementation.
+ // As above. Do not change this flag to stable, as it exists solely to
+ // generate code used by the origin trials sample API implementation.
+ {
+ name: "OriginTrialsSampleAPIDeprecation",
+ origin_trial_feature_name: "FrobulateDeprecation",
+ origin_trial_type: "deprecation",
+ origin_trial_allows_insecure: true,
+ },
+ // As above. Do not change this flag to stable, as it exists solely to
+ // generate code used by the origin trials sample API implementation.
{
name: "OriginTrialsSampleAPIImplied",
origin_trial_feature_name: "FrobulateImplied",
implied_by: ["OriginTrialsSampleAPI", "OriginTrialsSampleAPIInvalidOS"],
},
+ // As above. Do not change this flag to stable, as it exists solely to
+ // generate code used by the origin trials sample API implementation.
{
name: "OriginTrialsSampleAPIInvalidOS",
origin_trial_feature_name: "FrobulateInvalidOS",
origin_trial_os: ["invalid"],
},
+ // As above. Do not change this flag to stable, as it exists solely to
+ // generate code used by the origin trials sample API implementation.
{
name: "OriginTrialsSampleAPINavigation",
origin_trial_feature_name: "FrobulateNavigation",
@@ -1171,10 +1213,6 @@
name: "OverflowIconsForMediaControls",
},
{
- name: "OverlayScrollbars",
- settable_from_internals: true,
- },
- {
name: "OverscrollCustomization",
settable_from_internals: true,
status: "experimental",
@@ -1185,12 +1223,10 @@
{
name: "PageFreezeOptIn",
origin_trial_feature_name: "PageFreezeOptIn",
- status: "experimental",
},
{
name: "PageFreezeOptOut",
origin_trial_feature_name: "PageFreezeOptOut",
- status: "experimental",
},
{
name: "PagePopup",
@@ -1212,6 +1248,11 @@
{
name: "PassPaintVisualRectToCompositor",
},
+ // This is to add an option to enable the Reveal button on password inputs while waiting ::reveal gets standardized.
+ {
+ name: "PasswordReveal",
+ depends_on: ["FormControlsRefresh"],
+ },
{
name: "PaymentApp",
status: "experimental",
@@ -1222,7 +1263,7 @@
},
{
name: "PaymentHandlerHandlesShippingAndContact",
- status: "experimental",
+ status: "stable",
},
{
name: "PaymentMethodChangeEvent",
@@ -1253,9 +1294,7 @@
},
{
name: "PeriodicBackgroundSync",
- origin_trial_feature_name: "PeriodicBackgroundSync",
- settable_from_internals: true,
- status: "test",
+ status: "stable",
},
{
name: "PerMethodCanMakePaymentQuota",
@@ -1344,6 +1383,10 @@
status: "experimental",
},
{
+ name: "QuicTransport",
+ status: "experimental",
+ },
+ {
name: "ReducedReferrerGranularity",
},
{
@@ -1415,6 +1458,7 @@
// Spec: https://w3c.github.io/webrtc-svc/
{
name: "RTCSvcScalabilityMode",
+ status: "experimental",
},
// Enables the use of |RTCConfiguration::sdpSemantics| to override the
// default SDP semantics at RTCPeerConnection construction.
@@ -1429,7 +1473,7 @@
},
{
name: "SameSiteByDefaultCookies",
- status: "experimental",
+ status: "test",
},
// Exposes the displays connected to the device and provides the display
// properties needed for window placement features.
@@ -1454,6 +1498,10 @@
name: "ScrollCustomization",
},
{
+ name: "ScrollSnapAfterLayout",
+ status: "experimental",
+ },
+ {
name: "ScrollTimeline",
status: "experimental",
origin_trial_feature_name: "AnimationWorklet",
@@ -1479,6 +1527,7 @@
},
{
name: "Serial",
+ origin_trial_feature_name: "Serial",
status: {"Android": "", "default": "experimental"},
},
{
@@ -1486,15 +1535,21 @@
status: "experimental",
},
{
+ name: "ServiceWorkerFetchEventWorkerTiming",
+ status: "experimental",
+ },
+ {
name: "SetRootScroller",
status: "experimental",
},
- // Introduced this flag as stable so web developers can test their sites
- // without native Shadow DOM v0 support
+ // TODO(937746): Web Components v0 is disabled by default, and will be
+ // removed after M87.
{
name: "ShadowDOMV0",
origin_trial_feature_name: "WebComponentsV0",
- status: "stable",
+ origin_trial_type: "deprecation",
+ origin_trial_allows_insecure: true,
+ status: "test",
},
{
name: "ShadowPiercingDescendantCombinator",
@@ -1540,7 +1595,8 @@
{
name: "SmsReceiver",
origin_trial_feature_name: "SmsReceiver",
- status: {"Android": "experimental", "default": "test"},
+ origin_trial_os: ["android"],
+ status: {"default": "experimental"},
},
// Used as argument in attribute of stable-release functions/interfaces
// where a runtime-enabled feature name is required for correct IDL syntax.
@@ -1563,6 +1619,10 @@
status: "stable"
},
{
+ name: "StrictMimeTypesForWorkers",
+ status: "experimental"
+ },
+ {
name: "SurfaceEmbeddingFeatures",
status: "stable",
},
@@ -1645,10 +1705,6 @@
name: "UserActivationSameOriginVisibility",
},
{
- name: "UserActivationV2",
- status: "stable",
- },
- {
name: "UserAgentClientHint",
status: "experimental"
},
@@ -1672,6 +1728,15 @@
name: "VideoFullscreenOrientationLock",
},
{
+ name: "VideoPlaybackQuality",
+ status: "stable",
+ },
+ {
+ // See https://crbug.com/1012063
+ name: "VideoRequestAnimationFrame",
+ status: "experimental",
+ },
+ {
name: "VideoRotateToFullscreen",
},
{
@@ -1700,8 +1765,14 @@
origin_trial_feature_name: "WebAssemblyThreads",
status: "experimental",
},
+ // WebAuth is disabled on Android versions prior to N (7.0) due to lack of
+ // supporting APIs, see runtime_features.cc.
{
name: "WebAuth",
+ status: "stable",
+ },
+ {
+ name: "WebAuthenticationFeaturePolicy",
status: "experimental",
},
// WebBluetooth is enabled by default on Android, ChromeOS and Mac.
@@ -1779,11 +1850,6 @@
depends_on: ["WebUSB"],
},
{
- name: "WebVR",
- origin_trial_feature_name: "WebVR1.1M62",
- status: "experimental",
- },
- {
name: "WebVTTRegions",
status: "experimental",
},
@@ -1819,6 +1885,11 @@
name: "WebXRPlaneDetection",
// depends_on: ["WebXRARModule"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
},
+ // Extends window placement functionality for multi-screen devices.
+ {
+ name: "WindowPlacement",
+ status: "experimental",
+ },
{
name: "XSLT",
status: "stable",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
index 6812a3a5f3d..751e13bde93 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -40,6 +40,7 @@ blink_platform_sources("scheduler") {
"common/thread_load_tracker.h",
"common/thread_scheduler.cc",
"common/thread_scheduler_impl.h",
+ "common/thread_type.cc",
"common/throttling/budget_pool.cc",
"common/throttling/budget_pool.h",
"common/throttling/budget_pool_controller.h",
@@ -60,14 +61,14 @@ blink_platform_sources("scheduler") {
"common/web_resource_loading_task_runner_handle.cc",
"common/web_thread_scheduler.cc",
"common/worker_pool.cc",
+ "main_thread/agent_interference_recorder.cc",
+ "main_thread/agent_interference_recorder.h",
"main_thread/auto_advancing_virtual_time_domain.cc",
"main_thread/auto_advancing_virtual_time_domain.h",
"main_thread/compositor_priority_experiments.cc",
"main_thread/compositor_priority_experiments.h",
"main_thread/deadline_task_runner.cc",
"main_thread/deadline_task_runner.h",
- "main_thread/frame_interference_recorder.cc",
- "main_thread/frame_interference_recorder.h",
"main_thread/frame_origin_type.cc",
"main_thread/frame_origin_type.h",
"main_thread/frame_scheduler_impl.cc",
@@ -131,6 +132,7 @@ blink_platform_sources("scheduler") {
"public/thread.h",
"public/thread_cpu_throttler.h",
"public/thread_scheduler.h",
+ "public/thread_type.h",
"public/web_scheduling_priority.h",
"public/web_scheduling_task_queue.h",
"public/worker_pool.h",
@@ -215,9 +217,9 @@ jumbo_source_set("unit_tests") {
"common/tracing_helper_unittest.cc",
"common/ukm_task_sampler_unittest.cc",
"common/worker_pool_unittest.cc",
+ "main_thread/agent_interference_recorder_unittest.cc",
"main_thread/auto_advancing_virtual_time_domain_unittest.cc",
"main_thread/deadline_task_runner_unittest.cc",
- "main_thread/frame_interference_recorder_unittest.cc",
"main_thread/frame_scheduler_impl_unittest.cc",
"main_thread/frame_task_queue_controller_unittest.cc",
"main_thread/idle_time_estimator_unittest.cc",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.cc
index 5abf5604a38..07b9db7ffd3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.cc
@@ -11,7 +11,7 @@ CancelableClosureHolder::CancelableClosureHolder() = default;
CancelableClosureHolder::~CancelableClosureHolder() = default;
-void CancelableClosureHolder::Reset(const base::Closure& callback) {
+void CancelableClosureHolder::Reset(const base::RepeatingClosure& callback) {
callback_ = callback;
cancelable_callback_.Reset(callback_);
}
@@ -21,7 +21,7 @@ void CancelableClosureHolder::Cancel() {
cancelable_callback_.Reset(callback_);
}
-base::Closure CancelableClosureHolder::GetCallback() const {
+base::RepeatingClosure CancelableClosureHolder::GetCallback() const {
DCHECK(!callback_.is_null());
return cancelable_callback_.callback();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h b/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h
index 8ac08a0cf66..fccee47080b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h
@@ -12,8 +12,8 @@
namespace blink {
namespace scheduler {
-// A CancelableClosureHolder is a CancelableCallback which resets its wrapped
-// callback with a cached closure whenever it is canceled.
+// A CancelableClosureHolder is a CancelableRepeatingClosure which resets its
+// wrapped callback with a cached closure whenever it is canceled.
class CancelableClosureHolder {
DISALLOW_NEW();
@@ -23,18 +23,18 @@ class CancelableClosureHolder {
// Resets the closure to be wrapped by the cancelable callback. Cancels any
// outstanding callbacks.
- void Reset(const base::Closure& callback);
+ void Reset(const base::RepeatingClosure& callback);
// Cancels any outstanding closures returned by callback().
void Cancel();
// Returns a callback that will be disabled by calling Cancel(). Callback
// must have been set using Reset() before calling this function.
- base::Closure GetCallback() const;
+ base::RepeatingClosure GetCallback() const;
private:
- base::Closure callback_;
- base::CancelableClosure cancelable_callback_;
+ base::RepeatingClosure callback_;
+ base::CancelableRepeatingClosure cancelable_callback_;
DISALLOW_COPY_AND_ASSIGN(CancelableClosureHolder);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index ce590849c50..4633243ee58 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -121,6 +121,11 @@ class DummyPageScheduler : public PageScheduler {
return false;
}
bool RequestBeginMainFrameNotExpected(bool) override { return false; }
+ WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+ const String& name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration) override {
+ return WebScopedVirtualTimePauser();
+ }
private:
DISALLOW_COPY_AND_ASSIGN(DummyPageScheduler);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/features.h b/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
index 73eab66aaf2..b65ab55a0a4 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -103,6 +103,16 @@ constexpr base::FeatureParam<double> kCompositorBudgetRecoveryRate{
&kVeryHighPriorityForCompositingBudget, "CompositorBudgetRecoveryRate",
0.25};
+// This feature functions as an experiment parameter for the
+// VeryHighPriorityForCompositing alternating, delay, and budget experiments.
+// When enabled, it does nothing unless one of these experiments is also
+// enabled. If one of these experiments is enabled it will change the behavior
+// of that experiment such that the stop signal for prioritzation of the
+// compositor is a BeginMainFrame task instead of any compositor task.
+const base::Feature kPrioritizeCompositingUntilBeginMainFrame{
+ "BlinkSchedulerPrioritizeCompositingUntilBeginMainFrame",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// LOAD PRIORITY EXPERIMENT CONTROLS
// Enables setting the priority of background (with no audio) pages'
@@ -211,7 +221,7 @@ extern const char PLATFORM_EXPORT kFreezableTaskTypesListParam[];
// enabled.
const base::Feature kBlinkSchedulerDisableAntiStarvationForPriorities{
"BlinkSchedulerDisableAntiStarvationForPriorities",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Enable setting high priority database task type from field trial parameters.
const base::Feature kHighPriorityDatabaseTaskType{
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
index ff28ddb4637..23246956a95 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
@@ -217,7 +217,8 @@ void IdleHelper::EndIdlePeriod() {
base::TimeTicks());
}
-void IdleHelper::WillProcessTask(const base::PendingTask& pending_task) {
+void IdleHelper::WillProcessTask(const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) {
DCHECK(!is_shutdown_);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
index 49c86110083..aa80c6a2e39 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
@@ -146,7 +146,8 @@ class PLATFORM_EXPORT IdleHelper : public base::TaskObserver,
base::TimeTicks NowTicks() override;
// base::TaskObserver implementation:
- void WillProcessTask(const base::PendingTask& pending_task) override;
+ void WillProcessTask(const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) override;
void DidProcessTask(const base::PendingTask& pending_task) override;
IdlePeriodState SchedulerIdlePeriodState() const;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
index dbeb2c6f925..8d6f03efff5 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
@@ -9,7 +9,6 @@
#include "base/bind.h"
#include "base/callback.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/task/sequence_manager/sequence_manager.h"
@@ -450,72 +449,6 @@ TEST_F(IdleHelperTestWithIdlePeriodObserver, TestEnterAndExitIdlePeriod) {
idle_helper_->EndIdlePeriod();
}
-class IdleHelperWithMessageLoopTest : public BaseIdleHelperTest {
- public:
- IdleHelperWithMessageLoopTest()
- : BaseIdleHelperTest(std::make_unique<base::MessageLoop>(),
- base::TimeDelta()) {}
- ~IdleHelperWithMessageLoopTest() override = default;
-
- void PostFromNestedRunloop(
- Vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
- for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
- if (pair.second) {
- idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first));
- } else {
- idle_task_runner_->PostNonNestableIdleTask(FROM_HERE,
- std::move(pair.first));
- }
- }
- idle_helper_->StartIdlePeriod(
- IdleHelper::IdlePeriodState::kInShortIdlePeriod,
- test_task_runner_->NowTicks(),
- test_task_runner_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
- base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
- }
-
- void SetUp() override {
- EXPECT_CALL(*idle_helper_, OnIdlePeriodStarted()).Times(AnyNumber());
- EXPECT_CALL(*idle_helper_, OnIdlePeriodEnded()).Times(AnyNumber());
- EXPECT_CALL(*idle_helper_, OnPendingTasksChanged(_)).Times(AnyNumber());
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(IdleHelperWithMessageLoopTest);
-};
-
-TEST_F(IdleHelperWithMessageLoopTest,
- NonNestableIdleTaskDoesntExecuteInNestedLoop) {
- Vector<String> order;
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::BindOnce(&AppendToVectorIdleTestTask, &order, "1"));
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::BindOnce(&AppendToVectorIdleTestTask, &order, "2"));
-
- Vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>
- tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "3"), false));
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "4"), true));
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "5"), true));
-
- default_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&IdleHelperWithMessageLoopTest::PostFromNestedRunloop,
- base::Unretained(this),
- base::Unretained(&tasks_to_post_from_nested_loop)));
-
- idle_helper_->StartIdlePeriod(
- IdleHelper::IdlePeriodState::kInShortIdlePeriod,
- test_task_runner_->NowTicks(),
- test_task_runner_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
- base::RunLoop().RunUntilIdle();
- // Note we expect task 3 to run last because it's non-nestable.
- EXPECT_THAT(order, testing::ElementsAre("1", "2", "4", "5", "3"));
-}
-
TEST_F(IdleHelperTestWithIdlePeriodObserver, TestLongIdlePeriod) {
base::TimeTicks expected_deadline =
test_task_runner_->NowTicks() + maximum_idle_period_duration();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
index c46bd551600..81071cdb3ac 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
@@ -17,31 +17,30 @@ namespace {
constexpr base::TimeDelta kLongTaskDiscardingThreshold =
base::TimeDelta::FromSeconds(30);
-scheduling_metrics::ThreadType ConvertBlinkThreadType(
- WebThreadType thread_type) {
+scheduling_metrics::ThreadType ConvertBlinkThreadType(ThreadType thread_type) {
switch (thread_type) {
- case WebThreadType::kMainThread:
+ case ThreadType::kMainThread:
return scheduling_metrics::ThreadType::kRendererMainThread;
- case WebThreadType::kCompositorThread:
+ case ThreadType::kCompositorThread:
return scheduling_metrics::ThreadType::kRendererCompositorThread;
- case WebThreadType::kDedicatedWorkerThread:
+ case ThreadType::kDedicatedWorkerThread:
return scheduling_metrics::ThreadType::kRendererDedicatedWorkerThread;
- case WebThreadType::kServiceWorkerThread:
+ case ThreadType::kServiceWorkerThread:
return scheduling_metrics::ThreadType::kRendererServiceWorkerThread;
- case WebThreadType::kAnimationAndPaintWorkletThread:
- case WebThreadType::kAudioWorkletThread:
- case WebThreadType::kDatabaseThread:
- case WebThreadType::kFileThread:
- case WebThreadType::kHRTFDatabaseLoaderThread:
- case WebThreadType::kOfflineAudioRenderThread:
- case WebThreadType::kReverbConvolutionBackgroundThread:
- case WebThreadType::kSharedWorkerThread:
- case WebThreadType::kUnspecifiedWorkerThread:
- case WebThreadType::kTestThread:
- case WebThreadType::kAudioEncoderThread:
- case WebThreadType::kVideoEncoderThread:
+ case ThreadType::kAnimationAndPaintWorkletThread:
+ case ThreadType::kAudioWorkletThread:
+ case ThreadType::kDatabaseThread:
+ case ThreadType::kFileThread:
+ case ThreadType::kHRTFDatabaseLoaderThread:
+ case ThreadType::kOfflineAudioRenderThread:
+ case ThreadType::kReverbConvolutionBackgroundThread:
+ case ThreadType::kSharedWorkerThread:
+ case ThreadType::kUnspecifiedWorkerThread:
+ case ThreadType::kTestThread:
+ case ThreadType::kAudioEncoderThread:
+ case ThreadType::kVideoEncoderThread:
return scheduling_metrics::ThreadType::kRendererOtherBlinkThread;
- case WebThreadType::kCount:
+ case ThreadType::kCount:
NOTREACHED();
return scheduling_metrics::ThreadType::kCount;
}
@@ -49,7 +48,7 @@ scheduling_metrics::ThreadType ConvertBlinkThreadType(
} // namespace
-MetricsHelper::MetricsHelper(WebThreadType thread_type,
+MetricsHelper::MetricsHelper(ThreadType thread_type,
bool has_cpu_timing_for_each_task)
: thread_type_(thread_type),
thread_metrics_(ConvertBlinkThreadType(thread_type),
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
index 88764362672..2ea7c88e158 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
@@ -11,8 +11,8 @@
#include "components/scheduling_metrics/task_duration_metric_reporter.h"
#include "components/scheduling_metrics/thread_metrics.h"
#include "components/scheduling_metrics/total_duration_metric_reporter.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace base {
@@ -39,7 +39,7 @@ class PLATFORM_EXPORT MetricsHelper {
DISALLOW_NEW();
public:
- MetricsHelper(WebThreadType thread_type, bool has_cpu_timing_for_each_task);
+ MetricsHelper(ThreadType thread_type, bool has_cpu_timing_for_each_task);
~MetricsHelper();
protected:
@@ -55,22 +55,22 @@ class PLATFORM_EXPORT MetricsHelper {
const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
protected:
- const WebThreadType thread_type_;
+ const ThreadType thread_type_;
private:
scheduling_metrics::ThreadMetrics thread_metrics_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
thread_task_duration_reporter_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
thread_task_cpu_duration_reporter_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
foreground_thread_task_duration_reporter_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
foreground_thread_task_cpu_duration_reporter_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
background_thread_task_duration_reporter_;
- scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<ThreadType>
background_thread_task_cpu_duration_reporter_;
DISALLOW_COPY_AND_ASSIGN(MetricsHelper);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
index 5af9e4ed515..ed75e6df603 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
@@ -22,7 +22,7 @@ using base::sequence_manager::FakeTaskTiming;
class MetricsHelperForTest : public MetricsHelper {
public:
- MetricsHelperForTest(WebThreadType thread_type,
+ MetricsHelperForTest(ThreadType thread_type,
bool has_cpu_timing_for_each_task)
: MetricsHelper(thread_type, has_cpu_timing_for_each_task) {}
~MetricsHelperForTest() = default;
@@ -44,11 +44,10 @@ TEST(MetricsHelperTest, TaskDurationPerThreadType) {
base::HistogramTester histogram_tester;
MetricsHelperForTest main_thread_metrics(
- WebThreadType::kMainThread, false /* has_cpu_timing_for_each_task */);
+ ThreadType::kMainThread, false /* has_cpu_timing_for_each_task */);
MetricsHelperForTest compositor_metrics(
- WebThreadType::kCompositorThread,
- false /* has_cpu_timing_for_each_task */);
- MetricsHelperForTest worker_metrics(WebThreadType::kUnspecifiedWorkerThread,
+ ThreadType::kCompositorThread, false /* has_cpu_timing_for_each_task */);
+ MetricsHelperForTest worker_metrics(ThreadType::kUnspecifiedWorkerThread,
false /* has_cpu_timing_for_each_task */);
main_thread_metrics.RecordCommonTaskMetrics(
@@ -70,19 +69,19 @@ TEST(MetricsHelperTest, TaskDurationPerThreadType) {
histogram_tester.GetAllSamples(
"RendererScheduler.TaskDurationPerThreadType2"),
testing::UnorderedElementsAre(
- base::Bucket(static_cast<int>(WebThreadType::kMainThread), 40),
- base::Bucket(static_cast<int>(WebThreadType::kCompositorThread), 170),
- base::Bucket(
- static_cast<int>(WebThreadType::kUnspecifiedWorkerThread), 115)));
+ base::Bucket(static_cast<int>(ThreadType::kMainThread), 40),
+ base::Bucket(static_cast<int>(ThreadType::kCompositorThread), 170),
+ base::Bucket(static_cast<int>(ThreadType::kUnspecifiedWorkerThread),
+ 115)));
EXPECT_THAT(
histogram_tester.GetAllSamples(
"RendererScheduler.TaskCPUDurationPerThreadType2"),
testing::UnorderedElementsAre(
- base::Bucket(static_cast<int>(WebThreadType::kMainThread), 15),
- base::Bucket(static_cast<int>(WebThreadType::kCompositorThread), 5),
- base::Bucket(
- static_cast<int>(WebThreadType::kUnspecifiedWorkerThread), 25)));
+ base::Bucket(static_cast<int>(ThreadType::kMainThread), 15),
+ base::Bucket(static_cast<int>(ThreadType::kCompositorThread), 5),
+ base::Bucket(static_cast<int>(ThreadType::kUnspecifiedWorkerThread),
+ 25)));
}
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc
index fad56ee1a94..dd7838db9da 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc
@@ -143,4 +143,33 @@ TaskHandle PostDelayedCancellableTask(base::SequencedTaskRunner& task_runner,
return TaskHandle(runner);
}
+TaskHandle PostNonNestableCancellableTask(
+ base::SequencedTaskRunner& task_runner,
+ const base::Location& location,
+ base::OnceClosure task) {
+ DCHECK(task_runner.RunsTasksInCurrentSequence());
+ scoped_refptr<TaskHandle::Runner> runner =
+ base::AdoptRef(new TaskHandle::Runner(std::move(task)));
+ task_runner.PostNonNestableTask(
+ location, WTF::Bind(&TaskHandle::Runner::Run, runner->AsWeakPtr(),
+ TaskHandle(runner)));
+ return TaskHandle(runner);
+}
+
+TaskHandle PostNonNestableDelayedCancellableTask(
+ base::SequencedTaskRunner& task_runner,
+ const base::Location& location,
+ base::OnceClosure task,
+ base::TimeDelta delay) {
+ DCHECK(task_runner.RunsTasksInCurrentSequence());
+ scoped_refptr<TaskHandle::Runner> runner =
+ base::AdoptRef(new TaskHandle::Runner(std::move(task)));
+ task_runner.PostNonNestableDelayedTask(
+ location,
+ WTF::Bind(&TaskHandle::Runner::Run, runner->AsWeakPtr(),
+ TaskHandle(runner)),
+ delay);
+ return TaskHandle(runner);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task_unittest.cc
index e66748b78d4..cf2485bc6e9 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task_unittest.cc
@@ -66,6 +66,25 @@ TEST(WebTaskRunnerTest, PostCancellableTaskTest) {
EXPECT_EQ(1, count);
EXPECT_FALSE(handle.IsActive());
+ count = 0;
+ handle = PostNonNestableCancellableTask(
+ *task_runner, FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)));
+ EXPECT_EQ(0, count);
+ EXPECT_TRUE(handle.IsActive());
+ task_runner->RunUntilIdle();
+ EXPECT_EQ(1, count);
+ EXPECT_FALSE(handle.IsActive());
+
+ count = 0;
+ handle = PostNonNestableDelayedCancellableTask(
+ *task_runner, FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)),
+ base::TimeDelta::FromMilliseconds(1));
+ EXPECT_EQ(0, count);
+ EXPECT_TRUE(handle.IsActive());
+ task_runner->RunUntilIdle();
+ EXPECT_EQ(1, count);
+ EXPECT_FALSE(handle.IsActive());
+
// Cancel a task.
count = 0;
handle = PostCancellableTask(*task_runner, FROM_HERE,
@@ -76,6 +95,35 @@ TEST(WebTaskRunnerTest, PostCancellableTaskTest) {
task_runner->RunUntilIdle();
EXPECT_EQ(0, count);
+ count = 0;
+ handle = PostDelayedCancellableTask(
+ *task_runner, FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)),
+ base::TimeDelta::FromMilliseconds(1));
+ handle.Cancel();
+ EXPECT_EQ(0, count);
+ EXPECT_FALSE(handle.IsActive());
+ task_runner->RunUntilIdle();
+ EXPECT_EQ(0, count);
+
+ count = 0;
+ handle = PostNonNestableCancellableTask(
+ *task_runner, FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)));
+ handle.Cancel();
+ EXPECT_EQ(0, count);
+ EXPECT_FALSE(handle.IsActive());
+ task_runner->RunUntilIdle();
+ EXPECT_EQ(0, count);
+
+ count = 0;
+ handle = PostNonNestableDelayedCancellableTask(
+ *task_runner, FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)),
+ base::TimeDelta::FromMilliseconds(1));
+ handle.Cancel();
+ EXPECT_EQ(0, count);
+ EXPECT_FALSE(handle.IsActive());
+ task_runner->RunUntilIdle();
+ EXPECT_EQ(0, count);
+
// The task should be cancelled when the handle is dropped.
{
count = 0;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
index c751d9ccc24..ef55b44c5ee 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
@@ -41,7 +41,7 @@ void SchedulerHelper::InitDefaultQueues(
DCHECK(sequence_manager_);
sequence_manager_->SetDefaultTaskRunner(default_task_runner_);
- simple_task_executor_.emplace(default_task_runner_);
+ blink_task_executor_.emplace(default_task_runner_, sequence_manager_);
}
SchedulerHelper::~SchedulerHelper() {
@@ -182,5 +182,18 @@ bool SchedulerHelper::HasCPUTimingForEachTask() const {
return false;
}
+SchedulerHelper::BlinkTaskExecutor::BlinkTaskExecutor(
+ scoped_refptr<base::SingleThreadTaskRunner> default_task_queue,
+ base::sequence_manager::SequenceManager* sequence_manager)
+ : base::SimpleTaskExecutor(sequence_manager, std::move(default_task_queue)),
+ sequence_manager_(sequence_manager) {}
+
+SchedulerHelper::BlinkTaskExecutor::~BlinkTaskExecutor() = default;
+
+const scoped_refptr<base::SequencedTaskRunner>&
+SchedulerHelper::BlinkTaskExecutor::GetContinuationTaskRunner() {
+ return sequence_manager_->GetTaskRunnerForCurrentTask();
+}
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
index 3f2267ef8ec..52b84746c4b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
@@ -130,12 +130,29 @@ class PLATFORM_EXPORT SchedulerHelper
private:
friend class SchedulerHelperTest;
+ // Like SimpleTaskExecutor except it knows how to get the current task runner
+ // from the SequenceManager to implement GetContinuationTaskRunner.
+ class BlinkTaskExecutor : public base::SimpleTaskExecutor {
+ public:
+ BlinkTaskExecutor(
+ scoped_refptr<base::SingleThreadTaskRunner> default_task_queue,
+ base::sequence_manager::SequenceManager* sequence_manager);
+
+ ~BlinkTaskExecutor() override;
+
+ // base::TaskExecutor implementation.
+ const scoped_refptr<base::SequencedTaskRunner>& GetContinuationTaskRunner()
+ override;
+
+ private:
+ base::sequence_manager::SequenceManager* sequence_manager_; // NOT OWNED
+ };
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
Observer* observer_; // NOT OWNED
UkmTaskSampler ukm_task_sampler_;
- base::Optional<base::SimpleTaskExecutor> simple_task_executor_;
+ base::Optional<BlinkTaskExecutor> blink_task_executor_;
DISALLOW_COPY_AND_ASSIGN(SchedulerHelper);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
index 4879cbb79c7..bbc84ed3f64 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
@@ -141,7 +141,9 @@ namespace {
class MockTaskObserver : public base::TaskObserver {
public:
MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
- MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
+ MOCK_METHOD2(WillProcessTask,
+ void(const base::PendingTask& task,
+ bool was_blocked_or_low_priority));
};
void NopTask() {}
@@ -154,7 +156,7 @@ TEST_F(SchedulerHelperTest, ObserversNotifiedFor_DefaultTaskRunner) {
scheduler_helper_->DefaultTaskRunner()->PostTask(FROM_HERE,
base::BindOnce(&NopTask));
- EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
+ EXPECT_CALL(observer, WillProcessTask(_, _)).Times(1);
EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
task_environment_.RunUntilIdle();
}
@@ -166,7 +168,7 @@ TEST_F(SchedulerHelperTest, ObserversNotNotifiedFor_ControlTaskQueue) {
scheduler_helper_->ControlNonMainThreadTaskQueue()->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&NopTask));
- EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
+ EXPECT_CALL(observer, WillProcessTask(_, _)).Times(0);
EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
task_environment_.RunUntilIdle();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
index ceabb45254b..24d577ddcd3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
@@ -41,7 +41,7 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kRequestedMIDIPermission:
case Feature::kRequestedAudioCapturePermission:
case Feature::kRequestedVideoCapturePermission:
- case Feature::kRequestedSensorsPermission:
+ case Feature::kRequestedBackForwardCacheBlockedSensors:
case Feature::kRequestedBackgroundWorkPermission:
case Feature::kWebLocks:
return true;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/thread.cc
index b657a3c80c1..013326b9a51 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/thread.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread.cc
@@ -53,7 +53,7 @@ void Thread::UpdateThreadTLS(Thread* thread) {
ThreadTLSSlot() = thread;
}
-ThreadCreationParams::ThreadCreationParams(WebThreadType thread_type)
+ThreadCreationParams::ThreadCreationParams(ThreadType thread_type)
: thread_type(thread_type),
name(GetNameForThreadType(thread_type)),
frame_or_worker_scheduler(nullptr),
@@ -83,25 +83,10 @@ std::unique_ptr<Thread> Thread::CreateThread(
return std::move(thread);
}
-std::unique_ptr<Thread> Thread::CreateWebAudioThread() {
- ThreadCreationParams params(WebThreadType::kAudioWorkletThread);
- params.supports_gc = true;
-
- // WebAudio uses a thread with |DISPLAY| priority to avoid glitch when the
- // system is under the high pressure. Note that the main browser thread also
- // runs with same priority. (see: crbug.com/734539)
- params.thread_priority =
- base::FeatureList::IsEnabled(features::kAudioWorkletRealtimeThread)
- ? base::ThreadPriority::REALTIME_AUDIO
- : base::ThreadPriority::DISPLAY;
-
- return CreateThread(params);
-}
-
void Thread::CreateAndSetCompositorThread() {
DCHECK(!GetCompositorThread());
- ThreadCreationParams params(WebThreadType::kCompositorThread);
+ ThreadCreationParams params(ThreadType::kCompositorThread);
if (base::FeatureList::IsEnabled(
features::kBlinkCompositorUseDisplayThreadPriority))
params.thread_priority = base::ThreadPriority::DISPLAY;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_thread_type.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_type.cc
index 053cf328ece..9aed8b7aabe 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_thread_type.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_type.cc
@@ -2,48 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/web_thread_type.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "base/logging.h"
namespace blink {
-const char* GetNameForThreadType(WebThreadType thread_type) {
+const char* GetNameForThreadType(ThreadType thread_type) {
switch (thread_type) {
- case WebThreadType::kMainThread:
+ case ThreadType::kMainThread:
return "Main thread";
- case WebThreadType::kUnspecifiedWorkerThread:
+ case ThreadType::kUnspecifiedWorkerThread:
return "unspecified worker thread";
- case WebThreadType::kCompositorThread:
+ case ThreadType::kCompositorThread:
// Some benchmarks depend on this value.
return "Compositor";
- case WebThreadType::kDedicatedWorkerThread:
+ case ThreadType::kDedicatedWorkerThread:
return "DedicatedWorker thread";
- case WebThreadType::kSharedWorkerThread:
+ case ThreadType::kSharedWorkerThread:
return "SharedWorker thread";
- case WebThreadType::kAnimationAndPaintWorkletThread:
+ case ThreadType::kAnimationAndPaintWorkletThread:
return "AnimationWorklet thread";
- case WebThreadType::kServiceWorkerThread:
+ case ThreadType::kServiceWorkerThread:
return "ServiceWorker thread";
- case WebThreadType::kAudioWorkletThread:
+ case ThreadType::kAudioWorkletThread:
return "AudioWorklet thread";
- case WebThreadType::kFileThread:
+ case ThreadType::kFileThread:
return "File thread";
- case WebThreadType::kDatabaseThread:
+ case ThreadType::kDatabaseThread:
return "Database thread";
- case WebThreadType::kOfflineAudioRenderThread:
+ case ThreadType::kOfflineAudioRenderThread:
return "OfflineAudioRender thread";
- case WebThreadType::kReverbConvolutionBackgroundThread:
+ case ThreadType::kReverbConvolutionBackgroundThread:
return "Reverb convolution background thread";
- case WebThreadType::kHRTFDatabaseLoaderThread:
+ case ThreadType::kHRTFDatabaseLoaderThread:
return "HRTF database loader thread";
- case WebThreadType::kTestThread:
+ case ThreadType::kTestThread:
return "test thread";
- case WebThreadType::kAudioEncoderThread:
+ case ThreadType::kAudioEncoderThread:
return "Audio encoder thread";
- case WebThreadType::kVideoEncoderThread:
+ case ThreadType::kVideoEncoderThread:
return "Video encoder thread";
- case WebThreadType::kCount:
+ case ThreadType::kCount:
NOTREACHED();
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
index b79d3bee1e8..3b70bd9d942 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -185,7 +185,7 @@ class TaskQueueThrottlerWithAutoAdvancingTimeTest
DISALLOW_COPY_AND_ASSIGN(TaskQueueThrottlerWithAutoAdvancingTimeTest);
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
TaskQueueThrottlerWithAutoAdvancingTimeTest,
testing::Bool());
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
index 74e6c82b9af..ac27cae4d42 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
@@ -200,13 +200,6 @@ void WebThreadScheduler::SetRendererProcessType(WebRendererProcessType type) {
NOTREACHED();
}
-WebScopedVirtualTimePauser WebThreadScheduler::CreateWebScopedVirtualTimePauser(
- const char* name,
- WebScopedVirtualTimePauser::VirtualTaskDuration duration) {
- NOTREACHED();
- return WebScopedVirtualTimePauser();
-}
-
void WebThreadScheduler::OnMainFrameRequestedForInput() {
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
index 1a7c7124d1a..c6346ce85bb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
@@ -15,7 +15,7 @@ specific_include_rules = {
"+base/task/sequence_manager/task_queue_impl.h",
"+net/base/request_priority.h"
],
- "frame_interference_recorder.h": [
+ "agent_interference_recorder.h": [
"+base/task/sequence_manager/enqueue_order.h"
],
"frame_scheduler_impl.h": [
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.cc
new file mode 100644
index 00000000000..54866e13af5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.cc
@@ -0,0 +1,319 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h"
+
+#include <algorithm>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/rand_util.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+
+// Park–Miller random number generator. Not secure, used only for sampling.
+// https://en.wikipedia.org/wiki/Lehmer_random_number_generator
+uint32_t GetNextRandomNumber(uint32_t previous_value) {
+ constexpr uint32_t kModulo = (1U << 31) - 1;
+ return 48271 * static_cast<int64_t>(previous_value) % kModulo;
+}
+
+} // namespace
+
+AgentInterferenceRecorder::AgentInterferenceRecorder(int sampling_rate)
+ : sampling_rate_(sampling_rate),
+ random_value_(static_cast<uint32_t>(base::RandUint64())) {}
+
+AgentInterferenceRecorder::~AgentInterferenceRecorder() = default;
+
+void AgentInterferenceRecorder::OnTaskReady(
+ const void* frame_scheduler,
+ base::sequence_manager::EnqueueOrder enqueue_order,
+ base::sequence_manager::LazyNow* lazy_now) {
+ if (!ShouldSampleNextReadyTask())
+ return;
+
+ if (!frame_scheduler)
+ return;
+
+ base::AutoLock auto_lock(lock_);
+
+ DCHECK(!base::Contains(ready_tasks_, enqueue_order));
+ ReadyTask& ready_task = ready_tasks_[enqueue_order];
+ ready_task.time_for_all_agents_when_ready = time_for_all_agents_;
+ ready_task.agent_data_when_ready = agent_data_;
+#if DCHECK_IS_ON()
+ ready_task.frame_scheduler = frame_scheduler;
+#endif
+
+ // If the currently running task is associated with an agent, adjust the
+ // clock readings in |ready_task| to include its execution time.
+ if (!agent_cluster_id_for_current_task_)
+ return;
+
+ base::TimeDelta running_time = GetCurrentAgentTaskRunningTime(lazy_now);
+ // Clamp the value above zero to handle the case where the time in |lazy_now|
+ // was captured after the current main thread task started running.
+ running_time = std::max(base::TimeDelta(), running_time);
+
+ ready_task.time_for_all_agents_when_ready += running_time;
+ auto agent_data_it =
+ ready_task.agent_data_when_ready.find(agent_cluster_id_for_current_task_);
+ // The agent may have been destroyed before the task completes.
+ if (agent_data_it != ready_task.agent_data_when_ready.end()) {
+ agent_data_it->second.accumulated_running_time += running_time;
+ }
+}
+
+void AgentInterferenceRecorder::OnTaskStarted(
+ MainThreadTaskQueue* queue,
+ base::sequence_manager::EnqueueOrder enqueue_order,
+ base::TimeTicks start_time) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::AutoLock auto_lock(lock_);
+ DCHECK(current_task_start_time_.is_null());
+ DCHECK(!agent_cluster_id_for_current_task_);
+
+ const FrameScheduler* frame_scheduler =
+ queue ? GetFrameSchedulerForQueue(queue) : nullptr;
+ const base::UnguessableToken agent_cluster_id =
+ queue ? GetAgentClusterIdForQueue(queue) : base::UnguessableToken();
+
+ // Insert a default AgentData if there's no value for |agent_cluster_id|.
+ if (agent_cluster_id)
+ agent_data_.emplace(agent_cluster_id, AgentData{});
+
+ auto ready_task_it = ready_tasks_.find(enqueue_order);
+ if (ready_task_it != ready_tasks_.end()) {
+ RecordHistogramForReadyTask(ready_task_it->second, queue, frame_scheduler,
+ agent_cluster_id, enqueue_order);
+ ready_tasks_.erase(ready_task_it);
+ }
+
+ current_task_start_time_ = start_time;
+ agent_cluster_id_for_current_task_ = agent_cluster_id;
+
+ if (!frame_scheduler)
+ return;
+
+ // Maintain the mapping from frame to agent cluster id.
+ auto frame_to_agent_it = frame_to_agent_cluster_id_.find(frame_scheduler);
+ // If the frame is already tracked and has the same agent as before.
+ if (frame_to_agent_it != frame_to_agent_cluster_id_.end() &&
+ frame_to_agent_it->value == agent_cluster_id) {
+ return;
+ }
+ // If the frame is already tracked, but has a new agent.
+ if (frame_to_agent_it != frame_to_agent_cluster_id_.end()) {
+ DecrementNumFramesForAgent(frame_to_agent_it->value);
+ frame_to_agent_it->value = agent_cluster_id;
+ } else {
+ // If the frame was not tracked before.
+ frame_to_agent_cluster_id_.insert(frame_scheduler, agent_cluster_id);
+ }
+ DCHECK_EQ(frame_to_agent_cluster_id_.find(frame_scheduler)->value,
+ agent_cluster_id);
+ // If the frame was not tracked before, or was tracked but has a new agent.
+ if (agent_cluster_id)
+ ++agent_data_.at(agent_cluster_id).frame_count;
+}
+
+void AgentInterferenceRecorder::OnTaskCompleted(MainThreadTaskQueue* queue,
+ base::TimeTicks end_time) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::AutoLock auto_lock(lock_);
+ DCHECK(!end_time.is_null());
+
+ base::sequence_manager::LazyNow lazy_now(end_time);
+ AccumulateCurrentTaskRunningTime(&lazy_now);
+ current_task_start_time_ = base::TimeTicks();
+ agent_cluster_id_for_current_task_ = base::UnguessableToken();
+}
+
+void AgentInterferenceRecorder::OnFrameSchedulerDestroyed(
+ const FrameScheduler* frame_scheduler) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::AutoLock auto_lock(lock_);
+
+ auto frame_to_agent_it = frame_to_agent_cluster_id_.find(frame_scheduler);
+ if (frame_to_agent_it == frame_to_agent_cluster_id_.end())
+ return;
+ DecrementNumFramesForAgent(frame_to_agent_it->value);
+ frame_to_agent_cluster_id_.erase(frame_to_agent_it);
+}
+
+void AgentInterferenceRecorder::AccumulateCurrentTaskRunningTime(
+ base::sequence_manager::LazyNow* lazy_now) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!current_task_start_time_.is_null());
+
+ if (!agent_cluster_id_for_current_task_)
+ return;
+
+ // Update clocks.
+ const base::TimeDelta running_time = GetCurrentAgentTaskRunningTime(lazy_now);
+ DCHECK_GE(running_time, base::TimeDelta());
+
+ time_for_all_agents_ += running_time;
+
+ auto agent_data_it = agent_data_.find(agent_cluster_id_for_current_task_);
+ // The agent may have been destroyed before the task completes.
+ if (agent_data_it != agent_data_.end()) {
+ agent_data_it->second.accumulated_running_time += running_time;
+ DCHECK_GE(time_for_all_agents_,
+ agent_data_it->second.accumulated_running_time);
+ }
+}
+
+base::TimeDelta AgentInterferenceRecorder::GetCurrentAgentTaskRunningTime(
+ base::sequence_manager::LazyNow* lazy_now) const {
+ DCHECK(agent_cluster_id_for_current_task_);
+ DCHECK(!current_task_start_time_.is_null());
+ return lazy_now->Now() - current_task_start_time_;
+}
+
+uint32_t AgentInterferenceRecorder::ShouldSampleNextReadyTask() {
+ uint32_t previous_random_value =
+ random_value_.load(std::memory_order_relaxed);
+ uint32_t next_random_value;
+ do {
+ next_random_value = GetNextRandomNumber(previous_random_value);
+ } while (!random_value_.compare_exchange_weak(
+ previous_random_value, next_random_value, std::memory_order_relaxed));
+ return next_random_value % sampling_rate_ == 0;
+}
+
+void AgentInterferenceRecorder::RecordHistogramForReadyTask(
+ const ReadyTask& ready_task,
+ const MainThreadTaskQueue* queue,
+ const FrameScheduler* frame_scheduler,
+ const base::UnguessableToken& agent_cluster_id,
+ base::sequence_manager::EnqueueOrder enqueue_order) {
+ // Record the histogram if the task is associated with an agent and wasn't
+ // blocked by a fence or by the TaskQueue being disabled.
+ if (agent_cluster_id.is_empty() ||
+ enqueue_order < queue->GetEnqueueOrderAtWhichWeBecameUnblocked()) {
+ return;
+ }
+
+#if DCHECK_IS_ON()
+ DCHECK_EQ(frame_scheduler, ready_task.frame_scheduler);
+#endif
+
+ // |time_for_all_agents_since_ready| and |time_for_this_agent_since_ready| are
+ // clamped above zero to mitigate this problem:
+ //
+ // X = initial |time_for_all_agents_|.
+ //
+ // Thread 1: Captures time T1.
+ // Invokes OnTaskStarted with T1.
+ // Captures time T2.
+ // Thread 2: Captures time T3.
+ // Invokes OnTaskReady with T3. [*]
+ // |time_for_all_agents_when_ready| = X + T3 - T1
+ // (Ready task is from the same agent as the running task)
+ // Thread 1: Invokes OnTaskCompleted with T2.
+ // |time_for_all_agents_| += T2 - T1
+ // Invokes OnTaskStarted for the next task.
+ // |time_for_all_agent_since_ready|
+ // = |time_for_all_agents_| - |time_for_all_agents_when_ready|
+ // = (X + T2 - T1) - (X + T3 - T1)
+ // = T2 - T3
+ // Which is a negative value.
+ //
+ // |time_for_other_agents_since_ready| is clamped above zero for the case
+ // where the ready and running tasks are not from the same agent at [*]. In
+ // that case, |ready_task.time_for_all_agents_when_ready| was incremented with
+ // the current task's running time, but not
+ // |ready_task.time_for_this_agents_when_ready|, which can cause
+ // |time_for_this_agent_since_ready| to be greater than
+ // |time_for_all_agents_since_ready|.
+ //
+ // Note: These problem exists because OnTask*() methods use times captured
+ // outside the scope of |lock_|.
+ auto time_for_this_agent_when_ready_it =
+ ready_task.agent_data_when_ready.find(agent_cluster_id);
+ const base::TimeDelta time_for_this_agent_when_ready =
+ time_for_this_agent_when_ready_it ==
+ ready_task.agent_data_when_ready.end()
+ ? base::TimeDelta()
+ : time_for_this_agent_when_ready_it->second.accumulated_running_time;
+
+ DCHECK_GE(ready_task.time_for_all_agents_when_ready,
+ time_for_this_agent_when_ready);
+ const base::TimeDelta time_for_all_agents_since_ready = std::max(
+ base::TimeDelta(),
+ time_for_all_agents_ - ready_task.time_for_all_agents_when_ready);
+
+ auto agent_data_it = agent_data_.find(agent_cluster_id);
+ DCHECK(agent_data_it != agent_data_.end());
+ const base::TimeDelta time_for_agent =
+ agent_data_it->second.accumulated_running_time;
+ const base::TimeDelta time_for_this_agent_since_ready = std::max(
+ base::TimeDelta(), time_for_agent - time_for_this_agent_when_ready);
+
+ const base::TimeDelta time_for_other_agents_since_ready =
+ std::max(base::TimeDelta(), time_for_all_agents_since_ready -
+ time_for_this_agent_since_ready);
+ RecordHistogram(queue, time_for_other_agents_since_ready);
+}
+
+void AgentInterferenceRecorder::DecrementNumFramesForAgent(
+ const base::UnguessableToken& agent_cluster_id) {
+ if (!agent_cluster_id)
+ return;
+ auto agent_data_it = agent_data_.find(agent_cluster_id);
+ DCHECK(agent_data_it != agent_data_.end());
+ DCHECK_GT(agent_data_it->second.frame_count, 0U);
+ // If |frame_count| reaches 0, the data for this agent is cleared as it's
+ // no longer useful.
+ if (--agent_data_it->second.frame_count == 0)
+ agent_data_.erase(agent_data_it);
+}
+
+void AgentInterferenceRecorder::RecordHistogram(
+ const MainThreadTaskQueue* queue,
+ base::TimeDelta sample) {
+ // Histogram should only be recorded for queue types that can be associated
+ // with agents.
+ DCHECK(GetAgentClusterIdForQueue(queue));
+ const MainThreadTaskQueue::QueueType queue_type = queue->queue_type();
+ DCHECK(MainThreadTaskQueue::IsPerFrameTaskQueue(queue_type));
+
+ const std::string histogram_name =
+ std::string("RendererScheduler.TimeRunningOtherAgentsWhileTaskReady.") +
+ (GetFrameSchedulerForQueue(queue)->IsFrameVisible() ? "Visible"
+ : "Hidden");
+ base::UmaHistogramCustomMicrosecondsTimes(
+ histogram_name, sample, base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromSeconds(1), 100);
+ const std::string histogram_name_with_queue_type =
+ histogram_name + "." + MainThreadTaskQueue::NameForQueueType(queue_type);
+ base::UmaHistogramCustomMicrosecondsTimes(
+ histogram_name_with_queue_type, sample,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(1),
+ 100);
+}
+
+const FrameScheduler* AgentInterferenceRecorder::GetFrameSchedulerForQueue(
+ const MainThreadTaskQueue* queue) {
+ return queue->GetFrameScheduler();
+}
+
+const base::UnguessableToken&
+AgentInterferenceRecorder::GetAgentClusterIdForQueue(
+ const MainThreadTaskQueue* queue) {
+ const FrameSchedulerImpl* frame_scheduler = queue->GetFrameScheduler();
+ return frame_scheduler ? frame_scheduler->GetAgentClusterId()
+ : base::UnguessableToken::Null();
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h
index 1e0e3e98318..acdef00b9dc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h
@@ -2,20 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_INTERFERENCE_RECORDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_INTERFERENCE_RECORDER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_INTERFERENCE_RECORDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_INTERFERENCE_RECORDER_H_
#include <atomic>
+#include <map>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/task/sequence_manager/enqueue_order.h"
#include "base/task/sequence_manager/lazy_now.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -25,63 +28,61 @@ namespace scheduler {
class MainThreadTaskQueue;
-// Records the RendererScheduler.TimeRunningOtherFramesWhileTaskReady histogram,
-// which tracks how much time is spent running tasks from other frames between
-// when a frame task becomes ready to run and when it starts running.
+// Records the RendererScheduler.TimeRunningOtherAgentsWhileTaskReady histogram,
+// which tracks how much time is spent running tasks from other agents between
+// when an agent task becomes ready to run and when it starts running.
//
// Implementation details
// ----------------------
//
-// The time running tasks from other frames while a task is ready is defined as:
+// The time running tasks from other agents while a task is ready is defined as:
//
-// ([Time running tasks for all frames between thread start and task start] -
-// [Time running tasks for all frames between thread start and task ready]) -
-// ([Time running tasks for same frame between thread start and task start] -
-// [Time running tasks for same frame between thread start and task ready]) -
+// ([Time running tasks for all agents between thread start and task start] -
+// [Time running tasks for all agents between thread start and task ready]) -
+// ([Time running tasks for same agent between thread start and task start] -
+// [Time running tasks for same agent between thread start and task ready]) -
//
// To get these values, we maintain the following state:
//
-// A) For the task currently running at each nesting level:
+// A) For the task that is currently running:
// A1) Start time
-// A2) Associated frame
-// B) For each frame, an accumulator of time running tasks for that frame since
+// A2) Associated agent
+// B) For each agent, an accumulator of time running tasks for that agent since
// thread start.
-// C) An accumulator of time running tasks for any frame since thread start.
+// C) An accumulator of time running tasks for any agent since thread start.
// D) For each queued task for which we want to record the histogram:
-// D1) Time running tasks for all frames between thread start and task
+// D1) Time running tasks for all agents between thread start and task
// queued.
-// D2) Time running tasks for same frame between thread start and task
+// D2) Time running tasks for each agent between thread start and task
// queued.
//
// At any given time, we can compute:
//
-// E) The time running tasks for a specific FRAME since thread start:
-// Read the FRAME's accumulator in B. Add [Current Time] - A1 if the
-// task at the highest nesting level is associated with FRAME.
-// F) The time running tasks for any frame since thread start:
-// Read C. Add [Current Time] - A1 if the task at highest nesting level is
-// associated with any frame.
+// E) The time running tasks for a specific AGENT since thread start:
+// Read the AGENT's accumulator in B. Add [Current Time] - A1 if A2 is
+// equal to AGENT.
+// F) The time running tasks for any agent since thread start:
+// Read C. Add [Current Time] - A1 if A2 is non-null.
//
// When a task becomes ready, we decide whether we want to record the histogram
// for it. If so, we use E and F to add an entry to D.
//
// When a task starts running, we check whether it is in D. If so, we use D1,
// D2, E and F to compute the value to record to the histogram. Then, we update
-// the entry at the top of A. When a task finishes running, we update B and C
-// and we clear the entry at the top of A. Note that even though we sample the
-// tasks for which we record the histogram, we need to accumulate the time all
-// tasks in B and C since it can contribute to the value recorded for a sampled
-// task.
+// A. When a task finishes running, we update B and C and we clear A. Note that
+// even though we sample the tasks for which we record the histogram, we need to
+// accumulate the time all tasks in B and C since it can contribute to the value
+// recorded for a sampled task.
//
// Entering a nested loop is equivalent to finishing the current task. Exiting a
// nested loop is equivalent to resuming the task that was finished when the
// nested loop was entered (no histogram is recorded when resuming an existing
// task).
-class PLATFORM_EXPORT FrameInterferenceRecorder {
+class PLATFORM_EXPORT AgentInterferenceRecorder {
public:
// The histogram is recorded for 1 out of |sampling_rate| tasks.
- explicit FrameInterferenceRecorder(int sampling_rate = 1000);
- ~FrameInterferenceRecorder();
+ explicit AgentInterferenceRecorder(int sampling_rate = 1000);
+ ~AgentInterferenceRecorder();
// Invoked when a task becomes ready. For a non-delayed task, this is at post
// time. For a delayed task, this is when the task's delay expires.
@@ -110,14 +111,28 @@ class PLATFORM_EXPORT FrameInterferenceRecorder {
void OnFrameSchedulerDestroyed(const FrameScheduler* frame_scheduler);
private:
+ // Information about an agent.
+ struct AgentData {
+ AgentData() = default;
+
+ // Time running tasks for agent since thread start.
+ base::TimeDelta accumulated_running_time;
+
+ // Number of frames associated with this agent.
+ size_t frame_count = 0;
+ };
+
+ using AgentDataMap = std::map<base::UnguessableToken, AgentData>;
+
// Information about a ready task for which the histogram will be recorded.
struct ReadyTask {
- // The time read from |time_for_all_frames_| when the task became ready.
- base::TimeDelta time_for_all_frames_when_ready;
+ // Time running tasks for all agents when the task became ready (corresponds
+ // to D1 above).
+ base::TimeDelta time_for_all_agents_when_ready;
- // The time read from |time_for_frame_[task's frame]| when the task became
- // ready.
- base::TimeDelta time_for_this_frame_when_ready;
+ // Time running tasks for each agent when the task became ready (corresponds
+ // to D2 above).
+ AgentDataMap agent_data_when_ready;
#if DCHECK_IS_ON()
// The FrameScheduler associated with the task. Stored in a void* because
@@ -127,15 +142,16 @@ class PLATFORM_EXPORT FrameInterferenceRecorder {
#endif
};
- // Updates |time_for_all_frames_| and |time_for_frame_[current frame]| so that
- // they reflect current running time.
+ // Updates |time_for_all_agents_| and
+ // |agent_data_[current_task_agent_cluster_id_]| so that they reflect current
+ // running time.
void AccumulateCurrentTaskRunningTime(
base::sequence_manager::LazyNow* lazy_now)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
- // Returns the running time of the current frame task. Cannot be called if the
- // task running at the highest nesting level isn't a frame task.
- base::TimeDelta GetCurrentFrameTaskRunningTime(
+ // Returns the running time of the current agent task. Cannot be called if
+ // currently running task isn't an agent task.
+ base::TimeDelta GetCurrentAgentTaskRunningTime(
base::sequence_manager::LazyNow* lazy_now) const
EXCLUSIVE_LOCKS_REQUIRED(lock_);
@@ -144,17 +160,26 @@ class PLATFORM_EXPORT FrameInterferenceRecorder {
const ReadyTask& ready_task,
const MainThreadTaskQueue* queue,
const FrameScheduler* frame_scheduler,
+ const base::UnguessableToken& agent_cluster_id,
base::sequence_manager::EnqueueOrder enqueue_order)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Returns true if the next ready task should be sampled. Thread-safe.
uint32_t ShouldSampleNextReadyTask();
+ void DecrementNumFramesForAgent(
+ const base::UnguessableToken& agent_cluster_id)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
+
// Virtual for testing.
virtual void RecordHistogram(const MainThreadTaskQueue* queue,
base::TimeDelta sample);
virtual const FrameScheduler* GetFrameSchedulerForQueue(
const MainThreadTaskQueue* queue);
+ virtual const base::UnguessableToken& GetAgentClusterIdForQueue(
+ const MainThreadTaskQueue* queue);
+
+ SEQUENCE_CHECKER(sequence_checker_);
// Sampling rate. The histogram is recorded for 1/|sampling_rate_| tasks.
const int sampling_rate_;
@@ -171,26 +196,31 @@ class PLATFORM_EXPORT FrameInterferenceRecorder {
// running.
base::TimeTicks current_task_start_time_ GUARDED_BY(lock_);
- // FrameScheduler of the currently running task, or nullptr if no task is
- // running. Stored as a void* because it's only used a key and FrameScheduler
- // isn't thread-safe (so void prevents undesired access).
- const void* current_task_frame_scheduler_ GUARDED_BY(lock_) = nullptr;
+ // Agent cluster id of the currently running task, or Null if the task is not
+ // agent-bound or if no task is running.
+ base::UnguessableToken agent_cluster_id_for_current_task_ GUARDED_BY(lock_);
+
+ // Time spent running tasks for all agents since thread start.
+ base::TimeDelta time_for_all_agents_ GUARDED_BY(lock_);
- // Time spent running tasks for all frames since thread start.
- base::TimeDelta time_for_all_frames_ GUARDED_BY(lock_);
+ AgentDataMap agent_data_ GUARDED_BY(lock_);
- // Time running tasks for each frame since thread start.
- WTF::HashMap<const void*, base::TimeDelta> time_for_frame_ GUARDED_BY(lock_);
+ // Association between frames and agents. Frame is stored as a void* because
+ // it's only used a key and FrameScheduler isn't thread-safe (so void prevents
+ // undesired access). The mapping from frame to agent cluster id is maintained
+ // to allow efficiently maintaining the frame count in AgentData. Protected by
+ // |sequence_checker_|.
+ WTF::HashMap<const void*, base::UnguessableToken> frame_to_agent_cluster_id_;
// Information about ready tasks for which the histogram will be recorded. Key
// is the task's sequence number.
base::flat_map<base::sequence_manager::EnqueueOrder, ReadyTask> ready_tasks_
GUARDED_BY(lock_);
- DISALLOW_COPY_AND_ASSIGN(FrameInterferenceRecorder);
+ DISALLOW_COPY_AND_ASSIGN(AgentInterferenceRecorder);
};
} // namespace scheduler
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_INTERFERENCE_RECORDER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_INTERFERENCE_RECORDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder_unittest.cc
new file mode 100644
index 00000000000..5f7fc3563d9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder_unittest.cc
@@ -0,0 +1,565 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h"
+
+#include "base/task/sequence_manager/task_queue.h"
+#include "base/test/task_environment.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
+
+namespace blink {
+namespace scheduler {
+namespace agent_interference_recorder_test {
+
+using base::sequence_manager::LazyNow;
+using base::sequence_manager::Task;
+
+constexpr base::TimeDelta kDelay = base::TimeDelta::FromSeconds(10);
+
+class AgentInterferenceRecorderTest : public testing::Test {
+ public:
+ class MockAgentInterferenceRecorder : public AgentInterferenceRecorder {
+ public:
+ MockAgentInterferenceRecorder(AgentInterferenceRecorderTest* outer)
+ : AgentInterferenceRecorder(/* sampling_rate */ 1), outer_(outer) {}
+
+ void RecordHistogram(const MainThreadTaskQueue* queue,
+ base::TimeDelta sample) override {
+ MockRecordHistogram(queue, sample);
+ }
+
+ FrameScheduler* GetFrameSchedulerForQueue(
+ const MainThreadTaskQueue* queue) override {
+ if (queue == outer_->queue_frame_agent_a_ ||
+ queue == outer_->other_queue_frame_agent_a_)
+ return outer_->frame_agent_a_.get();
+ if (queue == outer_->queue_frame_agent_b_)
+ return outer_->frame_agent_b_.get();
+ if (queue == outer_->queue_frame_agent_c_)
+ return outer_->frame_agent_c_.get();
+ if (queue == outer_->queue_other_frame_agent_c_)
+ return outer_->other_frame_agent_c_.get();
+ return nullptr;
+ }
+ const base::UnguessableToken& GetAgentClusterIdForQueue(
+ const MainThreadTaskQueue* queue) override {
+ if (queue == outer_->queue_frame_agent_a_ ||
+ queue == outer_->other_queue_frame_agent_a_)
+ return outer_->agent_a_;
+ if (queue == outer_->queue_frame_agent_b_)
+ return outer_->agent_b_;
+ if (queue == outer_->queue_frame_agent_c_ ||
+ queue == outer_->queue_other_frame_agent_c_)
+ return outer_->agent_c_;
+ return base::UnguessableToken::Null();
+ }
+
+ MOCK_METHOD2(MockRecordHistogram,
+ void(const MainThreadTaskQueue*, base::TimeDelta));
+
+ private:
+ AgentInterferenceRecorderTest* const outer_;
+ };
+
+ class ScopedExpectSample {
+ public:
+ ScopedExpectSample(AgentInterferenceRecorderTest* test,
+ MainThreadTaskQueue* queue,
+ base::TimeDelta expected)
+ : test_(test) {
+ EXPECT_CALL(test_->recorder_, MockRecordHistogram(queue, expected));
+ }
+ ~ScopedExpectSample() { testing::Mock::VerifyAndClear(&test_->recorder_); }
+
+ private:
+ AgentInterferenceRecorderTest* const test_;
+ };
+
+ AgentInterferenceRecorderTest() = default;
+
+ static base::sequence_manager::EnqueueOrder EnqueueOrder(int enqueue_order) {
+ return base::sequence_manager::EnqueueOrder::FromIntForTesting(
+ enqueue_order);
+ }
+
+ void FastForwardBy(base::TimeDelta delta) {
+ task_environment_.FastForwardBy(delta);
+ }
+
+ base::TimeTicks NowTicks() const { return task_environment_.NowTicks(); }
+
+ void OnTaskReady(FrameScheduler* frame_scheduler,
+ base::sequence_manager::EnqueueOrder enqueue_order) {
+ base::sequence_manager::LazyNow lazy_now(GetMockTickClock());
+ recorder_.OnTaskReady(frame_scheduler, enqueue_order, &lazy_now);
+ }
+
+ const base::TickClock* GetMockTickClock() const {
+ return task_environment_.GetMockTickClock();
+ }
+
+ testing::StrictMock<MockAgentInterferenceRecorder> recorder_{this};
+
+ base::UnguessableToken agent_a_ = base::UnguessableToken::Create();
+ base::UnguessableToken agent_b_ = base::UnguessableToken::Create();
+ base::UnguessableToken agent_c_ = base::UnguessableToken::Create();
+
+ std::unique_ptr<FrameScheduler> frame_agent_a_ = CreateDummyFrameScheduler();
+ std::unique_ptr<FrameScheduler> frame_agent_b_ = CreateDummyFrameScheduler();
+ std::unique_ptr<FrameScheduler> frame_agent_c_ = CreateDummyFrameScheduler();
+ std::unique_ptr<FrameScheduler> other_frame_agent_c_ =
+ CreateDummyFrameScheduler();
+
+ scoped_refptr<MainThreadTaskQueue> queue_frame_agent_a_ =
+ CreateMainThreadTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> other_queue_frame_agent_a_ =
+ CreateMainThreadTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> queue_frame_agent_b_ =
+ CreateMainThreadTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> queue_frame_agent_c_ =
+ CreateMainThreadTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> queue_other_frame_agent_c_ =
+ CreateMainThreadTaskQueue();
+
+ // GetFrameSchedulerForQueue() will return nullptr for this queue.
+ scoped_refptr<MainThreadTaskQueue> queue_no_frame_ =
+ CreateMainThreadTaskQueue();
+
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+ private:
+ scoped_refptr<MainThreadTaskQueue> CreateMainThreadTaskQueue() {
+ return WrapRefCounted(new MainThreadTaskQueue(
+ nullptr, base::sequence_manager::TaskQueue::Spec(""),
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kDefault),
+ nullptr));
+ }
+};
+
+// Verify that zero interference is recorded if no task runs between when a
+// frame task is posted and when it runs.
+TEST_F(AgentInterferenceRecorderTest, NoInterferenceSingleTask) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+}
+
+// Verify that zero interference is recorded when tasks from the same queue run.
+TEST_F(AgentInterferenceRecorderTest, NoInterferenceMultipleTasksSameQueue) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+}
+
+// Verify that zero interference is recorded when tasks from different queues
+// associated with the same frame run.
+TEST_F(AgentInterferenceRecorderTest, NoInterferenceMultipleQueuesSameAgent) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, other_queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(other_queue_frame_agent_a_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(other_queue_frame_agent_a_.get(), end);
+ }
+}
+
+// Verify that zero interference is recorded when tasks from different frame
+// associated with the same agent run.
+TEST_F(AgentInterferenceRecorderTest, NoInterferenceMultipleFramesSameAgent) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_c_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(other_frame_agent_c_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_c_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_c_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_c_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_other_frame_agent_c_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_other_frame_agent_c_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_other_frame_agent_c_.get(), end);
+ }
+}
+
+// Verify that zero interference is recorded when a non-frame task runs between
+// when a frame task is ready and when it runs.
+TEST_F(AgentInterferenceRecorderTest, NoInterferenceNoAgentQueue) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(nullptr, EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ recorder_.OnTaskStarted(queue_no_frame_.get(), EnqueueOrder(1), start);
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_no_frame_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, other_queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(other_queue_frame_agent_a_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(other_queue_frame_agent_a_.get(), end);
+ }
+}
+
+// Verify that interference is recorded when a task from another agent runs
+// between when a agent task becomes ready and when it runs.
+TEST_F(AgentInterferenceRecorderTest, InterferenceFromOneOtherAgent) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_b_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_b_.get(),
+ kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_b_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_b_.get(), end);
+ }
+}
+
+// Verify that interference is recorded correctly when tasks from multiple
+// agents run.
+TEST_F(AgentInterferenceRecorderTest, InterferenceFromManyOtherFrames) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ // Add FastForwardBy()'s in between; those shouldn't matter.
+ FastForwardBy(kDelay * 32);
+ OnTaskReady(frame_agent_b_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay * 64);
+ OnTaskReady(frame_agent_c_.get(), EnqueueOrder(3));
+ FastForwardBy(kDelay * 128);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(4));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ // Had to wait for task 1.
+ ScopedExpectSample expect_sample(this, queue_frame_agent_b_.get(),
+ kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_b_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(2 * kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_b_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ // Had to wait for tasks 1 and 2.
+ ScopedExpectSample expect_sample(this, queue_frame_agent_c_.get(),
+ 3 * kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_c_.get(), EnqueueOrder(3),
+ start);
+ }
+ FastForwardBy(4 * kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_c_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ // Had to wait for tasks 2 and 3.
+ ScopedExpectSample expect_sample(this, other_queue_frame_agent_a_.get(),
+ 6 * kDelay);
+ recorder_.OnTaskStarted(other_queue_frame_agent_a_.get(), EnqueueOrder(4),
+ start);
+ }
+ FastForwardBy(8 * kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(other_queue_frame_agent_a_.get(), end);
+ }
+}
+
+// Verify that interference is recorded correctly when there are nested tasks.
+TEST_F(AgentInterferenceRecorderTest, Nesting) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_b_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+ OnTaskReady(frame_agent_b_.get(), EnqueueOrder(3));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+
+ // Run task 2 nested.
+ {
+ // When a nested loop is entered, complete the current task.
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), NowTicks());
+
+ const base::TimeTicks nested_start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_b_.get(),
+ kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_b_.get(), EnqueueOrder(2),
+ nested_start);
+ }
+ FastForwardBy(8 * kDelay);
+ const base::TimeTicks nested_end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_b_.get(), nested_end);
+
+ // When a nested loop is exited, resume the task that was running when the
+ // nested loop was entered.
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(),
+ base::sequence_manager::EnqueueOrder::none(),
+ NowTicks());
+ }
+
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ // Only includes the execution time of task 1, not the nested execution
+ // time of task 2, which is from the same frame.
+ ScopedExpectSample expect_sample(this, queue_frame_agent_b_.get(),
+ 2 * kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_b_.get(), EnqueueOrder(3),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_b_.get(), end);
+ }
+}
+
+// Verify that interference is recorded correctly when a task becomes ready
+// while another task is running.
+TEST_F(AgentInterferenceRecorderTest, ReadyDuringRun) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_a_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_a_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_a_.get(), EnqueueOrder(1),
+ start);
+ }
+
+ FastForwardBy(kDelay);
+ // Post task 2 in the middle of running task 1.
+ OnTaskReady(frame_agent_b_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_a_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_b_.get(),
+ kDelay);
+ recorder_.OnTaskStarted(queue_frame_agent_b_.get(), EnqueueOrder(2),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_b_.get(), end);
+ }
+}
+
+// Verify that OnFrameSchedulerDestroyed doesn't clear data associated to an
+// agent that is referred to by other frames.
+TEST_F(AgentInterferenceRecorderTest, OnFrameSchedulerDestroyed) {
+ SCOPED_TRACE(NowTicks());
+
+ OnTaskReady(frame_agent_c_.get(), EnqueueOrder(1));
+ FastForwardBy(kDelay);
+ OnTaskReady(other_frame_agent_c_.get(), EnqueueOrder(2));
+ FastForwardBy(kDelay);
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_frame_agent_c_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_frame_agent_c_.get(), EnqueueOrder(1),
+ start);
+ }
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_frame_agent_c_.get(), end);
+ }
+
+ {
+ const base::TimeTicks start = NowTicks();
+ {
+ ScopedExpectSample expect_sample(this, queue_other_frame_agent_c_.get(),
+ base::TimeDelta());
+ recorder_.OnTaskStarted(queue_other_frame_agent_c_.get(), EnqueueOrder(2),
+ start);
+ }
+ // This should not clear data associated with |agent_c_|.
+ recorder_.OnFrameSchedulerDestroyed(frame_agent_c_.get());
+
+ FastForwardBy(kDelay);
+ const base::TimeTicks end = NowTicks();
+ recorder_.OnTaskCompleted(queue_other_frame_agent_c_.get(), end);
+ }
+}
+
+} // namespace agent_interference_recorder_test
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc
index e5fe5b02985..95be1b6d37e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc
@@ -161,7 +161,8 @@ const char* AutoAdvancingVirtualTimeDomain::GetName() const {
}
void AutoAdvancingVirtualTimeDomain::WillProcessTask(
- const base::PendingTask& pending_task) {}
+ const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) {}
void AutoAdvancingVirtualTimeDomain::DidProcessTask(
const base::PendingTask& pending_task) {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h
index 5e031285836..9a629698395 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h
@@ -54,7 +54,8 @@ class PLATFORM_EXPORT AutoAdvancingVirtualTimeDomain
bool MaybeAdvanceVirtualTime(base::TimeTicks new_virtual_time);
// base::PendingTask implementation:
- void WillProcessTask(const base::PendingTask& pending_task) override;
+ void WillProcessTask(const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) override;
void DidProcessTask(const base::PendingTask& pending_task) override;
int task_starvation_count() const { return task_starvation_count_; }
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
index fa9a882b29b..8564cbca5b1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
@@ -16,7 +16,11 @@ CompositorPriorityExperiments::CompositorPriorityExperiments(
: scheduler_(scheduler),
experiment_(GetExperimentFromFeatureList()),
prioritize_compositing_after_delay_length_(
- base::TimeDelta::FromMilliseconds(kCompositingDelayLength.Get())) {
+ base::TimeDelta::FromMilliseconds(kCompositingDelayLength.Get())),
+ stop_signal_(base::FeatureList::IsEnabled(
+ kPrioritizeCompositingUntilBeginMainFrame)
+ ? StopSignalType::kBeginMainFrameTask
+ : StopSignalType::kAnyCompositorTask) {
do_prioritize_compositing_after_delay_callback_.Reset(base::BindRepeating(
&CompositorPriorityExperiments::DoPrioritizeCompositingAfterDelay,
base::Unretained(this)));
@@ -94,6 +98,10 @@ void CompositorPriorityExperiments::OnMainThreadSchedulerShutdown() {
budget_pool_controller_.reset();
}
+void CompositorPriorityExperiments::OnWillBeginMainFrame() {
+ will_begin_main_frame_ = true;
+}
+
void CompositorPriorityExperiments::PostPrioritizeCompositingAfterDelayTask() {
DCHECK_EQ(experiment_, Experiment::kVeryHighPriorityForCompositingAfterDelay);
@@ -109,6 +117,16 @@ void CompositorPriorityExperiments::OnTaskCompleted(
if (!queue)
return;
+ bool have_seen_stop_signal = false;
+ if (queue->queue_type() == MainThreadTaskQueue::QueueType::kCompositor) {
+ if (stop_signal_ == StopSignalType::kAnyCompositorTask) {
+ have_seen_stop_signal = true;
+ } else if (will_begin_main_frame_) {
+ have_seen_stop_signal = true;
+ will_begin_main_frame_ = false;
+ }
+ }
+
switch (experiment_) {
case Experiment::kVeryHighPriorityForCompositingAlways:
return;
@@ -119,9 +137,8 @@ void CompositorPriorityExperiments::OnTaskCompleted(
// compositor if another task has run regardless of its priority. This
// prevents starving the compositor while allowing other work to run
// in-between.
- if (queue->queue_type() == MainThreadTaskQueue::QueueType::kCompositor &&
- alternating_compositor_priority_ ==
- QueuePriority::kVeryHighPriority) {
+ if (have_seen_stop_signal && alternating_compositor_priority_ ==
+ QueuePriority::kVeryHighPriority) {
alternating_compositor_priority_ = QueuePriority::kNormalPriority;
scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority();
} else if (alternating_compositor_priority_ ==
@@ -131,7 +148,7 @@ void CompositorPriorityExperiments::OnTaskCompleted(
}
return;
case Experiment::kVeryHighPriorityForCompositingAfterDelay:
- if (queue->queue_type() == MainThreadTaskQueue::QueueType::kCompositor) {
+ if (have_seen_stop_signal) {
delay_compositor_priority_ = QueuePriority::kNormalPriority;
do_prioritize_compositing_after_delay_callback_.Cancel();
PostPrioritizeCompositingAfterDelayTask();
@@ -141,7 +158,8 @@ void CompositorPriorityExperiments::OnTaskCompleted(
}
return;
case Experiment::kVeryHighPriorityForCompositingBudget:
- budget_pool_controller_->OnTaskCompleted(queue, task_timing);
+ budget_pool_controller_->OnTaskCompleted(queue, task_timing,
+ have_seen_stop_signal);
return;
case Experiment::kNone:
return;
@@ -207,8 +225,9 @@ void CompositorPriorityExperiments::CompositorBudgetPoolController::
void CompositorPriorityExperiments::CompositorBudgetPoolController::
OnTaskCompleted(MainThreadTaskQueue* queue,
- MainThreadTaskQueue::TaskTiming* task_timing) {
- if (queue->queue_type() == MainThreadTaskQueue::QueueType::kCompositor) {
+ MainThreadTaskQueue::TaskTiming* task_timing,
+ bool have_seen_stop_signal) {
+ if (have_seen_stop_signal) {
compositor_budget_pool_->RecordTaskRunTime(queue, task_timing->start_time(),
task_timing->end_time());
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
index 1cb8789fcdf..bb034bf4713 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
@@ -52,6 +52,8 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
return alternating_compositor_priority_;
}
+ void OnWillBeginMainFrame();
+
void OnMainThreadSchedulerInitialized();
void OnMainThreadSchedulerShutdown();
@@ -76,7 +78,8 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
void UpdateCompositorBudgetState(base::TimeTicks now);
void OnTaskCompleted(MainThreadTaskQueue* queue,
- MainThreadTaskQueue::TaskTiming* task_timing);
+ MainThreadTaskQueue::TaskTiming* task_timing,
+ bool have_seen_stop_signal);
// Unimplemented methods.
void AddQueueToBudgetPool(TaskQueue* queue,
@@ -94,14 +97,16 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
const base::TickClock* tick_clock_; // Not owned.
};
- MainThreadSchedulerImpl* scheduler_; // Not owned.
-
static Experiment GetExperimentFromFeatureList();
void DoPrioritizeCompositingAfterDelay();
void PostPrioritizeCompositingAfterDelayTask();
+ enum class StopSignalType { kAnyCompositorTask, kBeginMainFrameTask };
+
+ MainThreadSchedulerImpl* scheduler_; // Not owned.
+
const Experiment experiment_;
QueuePriority alternating_compositor_priority_ =
@@ -113,6 +118,9 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
QueuePriority budget_compositor_priority_ = QueuePriority::kVeryHighPriority;
std::unique_ptr<CompositorBudgetPoolController> budget_pool_controller_;
+
+ const StopSignalType stop_signal_;
+ bool will_begin_main_frame_ = false;
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc
deleted file mode 100644
index 7c682ce0e6c..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h"
-
-#include <algorithm>
-
-#include "base/metrics/histogram_functions.h"
-#include "base/rand_util.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
-
-namespace blink {
-namespace scheduler {
-
-namespace {
-
-// Park–Miller random number generator. Not secure, used only for sampling.
-// https://en.wikipedia.org/wiki/Lehmer_random_number_generator
-uint32_t GetNextRandomNumber(uint32_t previous_value) {
- constexpr uint32_t kModulo = (1U << 31) - 1;
- return 48271 * static_cast<int64_t>(previous_value) % kModulo;
-}
-
-} // namespace
-
-FrameInterferenceRecorder::FrameInterferenceRecorder(int sampling_rate)
- : sampling_rate_(sampling_rate),
- random_value_(static_cast<uint32_t>(base::RandUint64())) {}
-
-FrameInterferenceRecorder::~FrameInterferenceRecorder() = default;
-
-void FrameInterferenceRecorder::OnTaskReady(
- const void* frame_scheduler,
- base::sequence_manager::EnqueueOrder enqueue_order,
- base::sequence_manager::LazyNow* lazy_now) {
- if (!ShouldSampleNextReadyTask())
- return;
-
- if (!frame_scheduler)
- return;
-
- base::AutoLock auto_lock(lock_);
-
- DCHECK(!base::Contains(ready_tasks_, enqueue_order));
- ReadyTask& ready_task = ready_tasks_[enqueue_order];
- ready_task.time_for_all_frames_when_ready = time_for_all_frames_;
- auto time_for_frame_it = time_for_frame_.find(frame_scheduler);
- if (time_for_frame_it != time_for_frame_.end())
- ready_task.time_for_this_frame_when_ready = time_for_frame_it->value;
-#if DCHECK_IS_ON()
- ready_task.frame_scheduler = frame_scheduler;
-#endif
-
- // If the currently running time is associated with a frame, adjust the
- // clock readings in |ready_task| to include its execution time.
- if (!current_task_frame_scheduler_)
- return;
-
- base::TimeDelta running_time = GetCurrentFrameTaskRunningTime(lazy_now);
- // Clamp the value above zero to handle the case where the time in |lazy_now|
- // was captured after the current main thread task started running.
- running_time = std::max(base::TimeDelta(), running_time);
-
- ready_task.time_for_all_frames_when_ready += running_time;
- if (current_task_frame_scheduler_ == frame_scheduler)
- ready_task.time_for_this_frame_when_ready += running_time;
-}
-
-void FrameInterferenceRecorder::OnTaskStarted(
- MainThreadTaskQueue* queue,
- base::sequence_manager::EnqueueOrder enqueue_order,
- base::TimeTicks start_time) {
- base::AutoLock auto_lock(lock_);
- DCHECK(current_task_start_time_.is_null());
- DCHECK(!current_task_frame_scheduler_);
-
- const FrameScheduler* frame_scheduler =
- queue ? GetFrameSchedulerForQueue(queue) : nullptr;
-
- auto ready_task_it = ready_tasks_.find(enqueue_order);
- if (ready_task_it != ready_tasks_.end()) {
- RecordHistogramForReadyTask(ready_task_it->second, queue, frame_scheduler,
- enqueue_order);
- ready_tasks_.erase(ready_task_it);
- }
-
- current_task_start_time_ = start_time;
- current_task_frame_scheduler_ = frame_scheduler;
-}
-
-void FrameInterferenceRecorder::OnTaskCompleted(MainThreadTaskQueue* queue,
- base::TimeTicks end_time) {
- base::AutoLock auto_lock(lock_);
- DCHECK(!end_time.is_null());
- if (queue)
- DCHECK_EQ(GetFrameSchedulerForQueue(queue), current_task_frame_scheduler_);
-
- base::sequence_manager::LazyNow lazy_now(end_time);
- AccumulateCurrentTaskRunningTime(&lazy_now);
- current_task_start_time_ = base::TimeTicks();
- current_task_frame_scheduler_ = nullptr;
-}
-
-void FrameInterferenceRecorder::OnFrameSchedulerDestroyed(
- const FrameScheduler* frame_scheduler) {
- base::AutoLock auto_lock(lock_);
- time_for_frame_.erase(frame_scheduler);
- if (current_task_frame_scheduler_ == frame_scheduler)
- current_task_frame_scheduler_ = nullptr;
-}
-
-void FrameInterferenceRecorder::AccumulateCurrentTaskRunningTime(
- base::sequence_manager::LazyNow* lazy_now) {
- DCHECK(!current_task_start_time_.is_null());
-
- if (!current_task_frame_scheduler_)
- return;
-
- // Update clocks.
- const base::TimeDelta running_time = GetCurrentFrameTaskRunningTime(lazy_now);
- DCHECK_GE(running_time, base::TimeDelta());
-
- time_for_all_frames_ += running_time;
-
- auto time_for_frame_it = time_for_frame_.find(current_task_frame_scheduler_);
- if (time_for_frame_it == time_for_frame_.end())
- time_for_frame_.insert(current_task_frame_scheduler_, running_time);
- else
- time_for_frame_it->value += running_time;
-
- DCHECK_GE(time_for_all_frames_,
- time_for_frame_.find(current_task_frame_scheduler_)->value);
-}
-
-base::TimeDelta FrameInterferenceRecorder::GetCurrentFrameTaskRunningTime(
- base::sequence_manager::LazyNow* lazy_now) const {
- DCHECK(current_task_frame_scheduler_);
- DCHECK(!current_task_start_time_.is_null());
- return lazy_now->Now() - current_task_start_time_;
-}
-
-uint32_t FrameInterferenceRecorder::ShouldSampleNextReadyTask() {
- uint32_t previous_random_value =
- random_value_.load(std::memory_order_relaxed);
- uint32_t next_random_value;
- do {
- next_random_value = GetNextRandomNumber(previous_random_value);
- } while (!random_value_.compare_exchange_weak(
- previous_random_value, next_random_value, std::memory_order_relaxed));
- return next_random_value % sampling_rate_ == 0;
-}
-
-void FrameInterferenceRecorder::RecordHistogramForReadyTask(
- const ReadyTask& ready_task,
- const MainThreadTaskQueue* queue,
- const FrameScheduler* frame_scheduler,
- base::sequence_manager::EnqueueOrder enqueue_order) {
- // Record the histogram if the task is associated with a frame and wasn't
- // blocked by a fence or by the TaskQueue being disabled.
- if (!frame_scheduler || enqueue_order < queue->GetLastUnblockEnqueueOrder())
- return;
-
-#if DCHECK_IS_ON()
- DCHECK_EQ(frame_scheduler, ready_task.frame_scheduler);
-#endif
-
- // |time_for_all_frames_since_ready| and |time_for_this_frame_since_ready| are
- // clamped above zero to mitigate this problem:
- //
- // X = initial |time_for_all_frames_|.
- //
- // Thread 1: Captures time T1.
- // Invokes OnTaskStarted with T1.
- // Captures time T2.
- // Thread 2: Captures time T3.
- // Invokes OnTaskReady with T3. [*]
- // |time_for_all_frames_when_ready| = X + T3 - T1
- // (Ready task is from the same frame as the running task)
- // Thread 1: Invokes OnTaskCompleted with T2.
- // |time_for_all_frames_| += T2 - T1
- // Invokes OnTaskStarted for the next task.
- // |time_for_all_frames_since_ready|
- // = |time_for_all_frames_| - |time_for_all_frames_when_ready|
- // = (X + T2 - T1) - (X + T3 - T1)
- // = T2 - T3
- // Which is a negative value.
- //
- // |time_for_other_frames_since_ready| is clamped above zero for the case
- // where the ready and running tasks are not from the same frame at [*]. In
- // that case, |ready_task.time_for_all_frames_when_ready| was incremented with
- // the current task's running time, but not
- // |ready_task.time_for_this_frames_when_ready|, which can cause
- // |time_for_this_frame_since_ready| to be greater than
- // |time_for_all_frames_since_ready|.
- //
- // Note: These problem exists because OnTask*() methods use times captured
- // outside the scope of |lock_|.
- DCHECK_GE(ready_task.time_for_all_frames_when_ready,
- ready_task.time_for_this_frame_when_ready);
- const base::TimeDelta time_for_all_frames_since_ready = std::max(
- base::TimeDelta(),
- time_for_all_frames_ - ready_task.time_for_all_frames_when_ready);
-
- auto time_for_frame_it = time_for_frame_.find(frame_scheduler);
- const base::TimeDelta time_for_frame =
- time_for_frame_it == time_for_frame_.end() ? base::TimeDelta()
- : time_for_frame_it->value;
- const base::TimeDelta time_for_this_frame_since_ready =
- std::max(base::TimeDelta(),
- time_for_frame - ready_task.time_for_this_frame_when_ready);
-
- const base::TimeDelta time_for_other_frames_since_ready =
- std::max(base::TimeDelta(), time_for_all_frames_since_ready -
- time_for_this_frame_since_ready);
- RecordHistogram(queue, time_for_other_frames_since_ready);
-}
-
-void FrameInterferenceRecorder::RecordHistogram(
- const MainThreadTaskQueue* queue,
- base::TimeDelta sample) {
- // Histogram should only be recorded for queue types that can be associated
- // with frames.
- DCHECK(GetFrameSchedulerForQueue(queue));
- const MainThreadTaskQueue::QueueType queue_type = queue->queue_type();
- DCHECK(MainThreadTaskQueue::IsPerFrameTaskQueue(queue_type));
-
- const std::string histogram_name =
- std::string("RendererScheduler.TimeRunningOtherFramesWhileTaskReady.") +
- (GetFrameSchedulerForQueue(queue)->IsFrameVisible() ? "Visible"
- : "Hidden");
- base::UmaHistogramCustomMicrosecondsTimes(
- histogram_name, sample, base::TimeDelta::FromMicroseconds(1),
- base::TimeDelta::FromSeconds(1), 100);
- const std::string histogram_name_with_queue_type =
- histogram_name + "." + MainThreadTaskQueue::NameForQueueType(queue_type);
- base::UmaHistogramCustomMicrosecondsTimes(
- histogram_name_with_queue_type, sample,
- base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(1),
- 100);
-}
-
-const FrameScheduler* FrameInterferenceRecorder::GetFrameSchedulerForQueue(
- const MainThreadTaskQueue* queue) {
- return queue->GetFrameScheduler();
-}
-
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc
deleted file mode 100644
index e2962a676d9..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc
+++ /dev/null
@@ -1,437 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h"
-
-#include "base/task/sequence_manager/task_queue.h"
-#include "base/test/task_environment.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
-#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
-
-namespace blink {
-namespace scheduler {
-namespace frame_interference_recorder_test {
-
-using base::sequence_manager::LazyNow;
-using base::sequence_manager::Task;
-
-constexpr base::TimeDelta kDelay = base::TimeDelta::FromSeconds(10);
-
-class FrameInterferenceRecorderTest : public testing::Test {
- public:
- class MockFrameInterferenceRecorder : public FrameInterferenceRecorder {
- public:
- MockFrameInterferenceRecorder(FrameInterferenceRecorderTest* outer)
- : FrameInterferenceRecorder(/* sampling_rate */ 1), outer_(outer) {}
-
- void RecordHistogram(const MainThreadTaskQueue* queue,
- base::TimeDelta sample) override {
- MockRecordHistogram(queue, sample);
- }
-
- FrameScheduler* GetFrameSchedulerForQueue(
- const MainThreadTaskQueue* queue) override {
- if (queue == outer_->queue_a1_ || queue == outer_->queue_a2_)
- return outer_->frame_a_.get();
- if (queue == outer_->queue_b1_)
- return outer_->frame_b_.get();
- if (queue == outer_->queue_c1_)
- return outer_->frame_c_.get();
- return nullptr;
- }
-
- MOCK_METHOD2(MockRecordHistogram,
- void(const MainThreadTaskQueue*, base::TimeDelta));
-
- private:
- FrameInterferenceRecorderTest* const outer_;
- };
-
- class ScopedExpectSample {
- public:
- ScopedExpectSample(FrameInterferenceRecorderTest* test,
- MainThreadTaskQueue* queue,
- base::TimeDelta expected)
- : test_(test) {
- EXPECT_CALL(test_->recorder_, MockRecordHistogram(queue, expected));
- }
- ~ScopedExpectSample() { testing::Mock::VerifyAndClear(&test_->recorder_); }
-
- private:
- FrameInterferenceRecorderTest* const test_;
- };
-
- FrameInterferenceRecorderTest() = default;
-
- static base::sequence_manager::EnqueueOrder EnqueueOrder(int enqueue_order) {
- return base::sequence_manager::EnqueueOrder::FromIntForTesting(
- enqueue_order);
- }
-
- void FastForwardBy(base::TimeDelta delta) {
- task_environment_.FastForwardBy(delta);
- }
-
- base::TimeTicks NowTicks() const { return task_environment_.NowTicks(); }
-
- void OnTaskReady(FrameScheduler* frame_scheduler,
- base::sequence_manager::EnqueueOrder enqueue_order) {
- base::sequence_manager::LazyNow lazy_now(GetMockTickClock());
- recorder_.OnTaskReady(frame_scheduler, enqueue_order, &lazy_now);
- }
-
- const base::TickClock* GetMockTickClock() const {
- return task_environment_.GetMockTickClock();
- }
-
- testing::StrictMock<MockFrameInterferenceRecorder> recorder_{this};
-
- std::unique_ptr<FrameScheduler> frame_a_ = CreateDummyFrameScheduler();
- std::unique_ptr<FrameScheduler> frame_b_ = CreateDummyFrameScheduler();
- std::unique_ptr<FrameScheduler> frame_c_ = CreateDummyFrameScheduler();
-
- scoped_refptr<MainThreadTaskQueue> queue_a1_ = CreateMainThreadTaskQueue();
- scoped_refptr<MainThreadTaskQueue> queue_a2_ = CreateMainThreadTaskQueue();
- scoped_refptr<MainThreadTaskQueue> queue_b1_ = CreateMainThreadTaskQueue();
- scoped_refptr<MainThreadTaskQueue> queue_c1_ = CreateMainThreadTaskQueue();
-
- // GetFrameSchedulerForQueue() will return nullptr for this queue.
- scoped_refptr<MainThreadTaskQueue> queue_no_frame_ =
- CreateMainThreadTaskQueue();
-
- base::test::TaskEnvironment task_environment_{
- base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-
- private:
- scoped_refptr<MainThreadTaskQueue> CreateMainThreadTaskQueue() {
- return WrapRefCounted(new MainThreadTaskQueue(
- nullptr, base::sequence_manager::TaskQueue::Spec(""),
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kDefault),
- nullptr));
- }
-};
-
-// Verify that zero interference is recorded if no task runs between when a
-// frame task is posted and when it runs.
-TEST_F(FrameInterferenceRecorderTest, NoInterferenceSingleTask) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-}
-
-// Verify that zero interference is recorded when tasks from the same queue run.
-TEST_F(FrameInterferenceRecorderTest, NoInterferenceMultipleTasksSameQueue) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
- OnTaskReady(frame_a_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-}
-
-// Verify that zero interference is recorded when tasks from different queues
-// associated with the same frame run.
-TEST_F(FrameInterferenceRecorderTest, NoInterferenceMultipleQueuesSameFrame) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
- OnTaskReady(frame_a_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a2_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a2_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a2_.get(), end);
- }
-}
-
-// Verify that zero interference is recorded when a non-frame task runs between
-// when a frame task is ready and when it runs.
-TEST_F(FrameInterferenceRecorderTest, NoInterferenceNoFrameQueue) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(nullptr, EnqueueOrder(1));
- FastForwardBy(kDelay);
- OnTaskReady(frame_a_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- recorder_.OnTaskStarted(queue_no_frame_.get(), EnqueueOrder(1), start);
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_no_frame_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a2_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a2_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a2_.get(), end);
- }
-}
-
-// Verify that interference is recorded when a task from another frame runs
-// between when a frame task becomes ready and when it runs.
-TEST_F(FrameInterferenceRecorderTest, InterferenceFromOneOtherFrame) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
- OnTaskReady(frame_b_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_b1_.get(), kDelay);
- recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_b1_.get(), end);
- }
-}
-
-// Verify that interference is recorded correctly when tasks from multiple
-// frames run.
-TEST_F(FrameInterferenceRecorderTest, InterferenceFromManyOtherFrames) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- // Add FastForwardBy()'s in between; those shouldn't matter.
- FastForwardBy(kDelay * 32);
- OnTaskReady(frame_b_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay * 64);
- OnTaskReady(frame_c_.get(), EnqueueOrder(3));
- FastForwardBy(kDelay * 128);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(4));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- // Had to wait for task 1.
- ScopedExpectSample expect_sample(this, queue_b1_.get(), kDelay);
- recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(2 * kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_b1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- // Had to wait for tasks 1 and 2.
- ScopedExpectSample expect_sample(this, queue_c1_.get(), 3 * kDelay);
- recorder_.OnTaskStarted(queue_c1_.get(), EnqueueOrder(3), start);
- }
- FastForwardBy(4 * kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_c1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- // Had to wait for tasks 2 and 3.
- ScopedExpectSample expect_sample(this, queue_a2_.get(), 6 * kDelay);
- recorder_.OnTaskStarted(queue_a2_.get(), EnqueueOrder(4), start);
- }
- FastForwardBy(8 * kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a2_.get(), end);
- }
-}
-
-// Verify that interference is recorded correctly when there are nested tasks.
-TEST_F(FrameInterferenceRecorderTest, Nesting) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
- OnTaskReady(frame_b_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
- OnTaskReady(frame_b_.get(), EnqueueOrder(3));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
- FastForwardBy(kDelay);
-
- // Run task 2 nested.
- {
- // When a nested loop is entered, complete the current task.
- recorder_.OnTaskCompleted(queue_a1_.get(), NowTicks());
-
- const base::TimeTicks nested_start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_b1_.get(), kDelay);
- recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), nested_start);
- }
- FastForwardBy(8 * kDelay);
- const base::TimeTicks nested_end = NowTicks();
- recorder_.OnTaskCompleted(queue_b1_.get(), nested_end);
-
- // When a nested loop is exited, resume the task that was running when the
- // nested loop was entered.
- recorder_.OnTaskStarted(queue_a1_.get(),
- base::sequence_manager::EnqueueOrder::none(),
- NowTicks());
- }
-
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- // Only includes the execution time of task 1, not the nested execution
- // time of task 2, which is from the same frame.
- ScopedExpectSample expect_sample(this, queue_b1_.get(), 2 * kDelay);
- recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(3), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_b1_.get(), end);
- }
-}
-
-// Verify that interference is recorded correctly when a task becomes ready
-// while another task is running.
-TEST_F(FrameInterferenceRecorderTest, ReadyDuringRun) {
- SCOPED_TRACE(NowTicks());
-
- OnTaskReady(frame_a_.get(), EnqueueOrder(1));
- FastForwardBy(kDelay);
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_a1_.get(),
- base::TimeDelta());
- recorder_.OnTaskStarted(queue_a1_.get(), EnqueueOrder(1), start);
- }
-
- FastForwardBy(kDelay);
- // Post task 2 in the middle of running task 1.
- OnTaskReady(frame_b_.get(), EnqueueOrder(2));
- FastForwardBy(kDelay);
-
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_a1_.get(), end);
- }
-
- {
- const base::TimeTicks start = NowTicks();
- {
- ScopedExpectSample expect_sample(this, queue_b1_.get(), kDelay);
- recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), start);
- }
- FastForwardBy(kDelay);
- const base::TimeTicks end = NowTicks();
- recorder_.OnTaskCompleted(queue_b1_.get(), end);
- }
-}
-
-} // namespace frame_interference_recorder_test
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index be332f683dd..0e52953485d 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -474,15 +474,15 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
} else {
return PausableTaskQueueTraits();
}
- case TaskType::kInternalFreezableIPC:
+ case TaskType::kInternalNavigationAssociated:
return FreezableTaskQueueTraits();
- case TaskType::kInternalIPC:
// Some tasks in the tests need to run when objects are paused e.g. to hook
// when recovering from debugger JavaScript statetment.
case TaskType::kInternalTest:
// kWebLocks can be frozen if for entire page, but not for individual
// frames. See https://crrev.com/c/1687716
case TaskType::kWebLocks:
+ case TaskType::kInternalFrameLifecycleControl:
return UnpausableTaskQueueTraits();
case TaskType::kInternalTranslation:
return ForegroundOnlyTaskQueueTraits();
@@ -491,7 +491,7 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
// time is paused.
case TaskType::kInternalInspector:
// Navigation IPCs do not run using virtual time to avoid hanging.
- case TaskType::kInternalNavigationAssociated:
+ case TaskType::kInternalNavigationAssociatedUnfreezable:
return DoesNotUseVirtualTimeTaskQueueTraits();
case TaskType::kDeprecatedNone:
case TaskType::kMainThreadTaskQueueV8:
@@ -1142,8 +1142,19 @@ FrameSchedulerImpl::CreateWebSchedulingTaskQueue(
scoped_refptr<MainThreadTaskQueue> task_queue =
frame_task_queue_controller_->NewWebSchedulingTaskQueue(
PausableTaskQueueTraits(), priority);
- return std::make_unique<WebSchedulingTaskQueueImpl>(priority,
- task_queue.get());
+ return std::make_unique<WebSchedulingTaskQueueImpl>(task_queue->AsWeakPtr());
+}
+
+void FrameSchedulerImpl::OnWebSchedulingTaskQueuePriorityChanged(
+ MainThreadTaskQueue* queue) {
+ UpdateQueuePolicy(queue,
+ frame_task_queue_controller_->GetQueueEnabledVoter(queue));
+}
+
+const base::UnguessableToken& FrameSchedulerImpl::GetAgentClusterId() const {
+ if (!delegate_)
+ return base::UnguessableToken::Null();
+ return delegate_->GetAgentClusterId();
}
// static
@@ -1154,7 +1165,7 @@ FrameSchedulerImpl::ThrottleableTaskQueueTraits() {
.SetCanBeFrozen(true)
.SetCanBeDeferred(true)
.SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true);
+ .SetCanRunWhenVirtualTimePaused(false);
}
// static
@@ -1165,7 +1176,7 @@ FrameSchedulerImpl::DeferrableTaskQueueTraits() {
.SetCanBeFrozen(base::FeatureList::IsEnabled(
blink::features::kStopNonTimersInBackground))
.SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true);
+ .SetCanRunWhenVirtualTimePaused(false);
}
// static
@@ -1175,7 +1186,7 @@ FrameSchedulerImpl::PausableTaskQueueTraits() {
.SetCanBeFrozen(base::FeatureList::IsEnabled(
blink::features::kStopNonTimersInBackground))
.SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true);
+ .SetCanRunWhenVirtualTimePaused(false);
}
// static
@@ -1189,19 +1200,19 @@ FrameSchedulerImpl::FreezableTaskQueueTraits() {
// static
MainThreadTaskQueue::QueueTraits
FrameSchedulerImpl::UnpausableTaskQueueTraits() {
- return QueueTraits().SetCanRunWhenVirtualTimePaused(true);
+ return QueueTraits().SetCanRunWhenVirtualTimePaused(false);
}
MainThreadTaskQueue::QueueTraits
FrameSchedulerImpl::ForegroundOnlyTaskQueueTraits() {
return ThrottleableTaskQueueTraits()
.SetCanRunInBackground(false)
- .SetCanRunWhenVirtualTimePaused(true);
+ .SetCanRunWhenVirtualTimePaused(false);
}
MainThreadTaskQueue::QueueTraits
FrameSchedulerImpl::DoesNotUseVirtualTimeTaskQueueTraits() {
- return QueueTraits().SetCanRunWhenVirtualTimePaused(false);
+ return QueueTraits().SetCanRunWhenVirtualTimePaused(true);
}
void FrameSchedulerImpl::SetPreemptedForCooperativeScheduling(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index 9f9eef3782e..860cd684172 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -186,6 +186,9 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
std::unique_ptr<WebSchedulingTaskQueue> CreateWebSchedulingTaskQueue(
WebSchedulingPriority) override;
+ void OnWebSchedulingTaskQueuePriorityChanged(MainThreadTaskQueue*);
+
+ const base::UnguessableToken& GetAgentClusterId() const;
protected:
FrameSchedulerImpl(MainThreadSchedulerImpl* main_thread_scheduler,
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index 891ed7a9c6e..43efd83327e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -17,6 +17,7 @@
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
+#include "base/unguessable_token.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
@@ -54,6 +55,10 @@ class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate {
update_task_time_calls_++;
}
+ const base::UnguessableToken& GetAgentClusterId() const override {
+ return base::UnguessableToken::Null();
+ }
+
MOCK_METHOD1(UpdateActiveSchedulerTrackedFeatures, void(uint64_t));
int update_task_time_calls_ = 0;
@@ -1774,7 +1779,7 @@ TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
EXPECT_EQ(GetTaskQueue(TaskType::kWebSocket), DeferrableTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kDatabaseAccess), PausableTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kPostedMessage), PausableTaskQueue());
- EXPECT_EQ(GetTaskQueue(TaskType::kInternalIPC), UnpausableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kWebLocks), UnpausableTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kNetworking), LoadingTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kNetworkingControl),
LoadingControlTaskQueue());
@@ -1812,41 +1817,47 @@ TEST_F(ThrottleableAndFreezableTaskTypesTest, QueueTraitsFromFieldTrialParams) {
// Check that the overrides work.
auto task_queue = GetTaskQueue(TaskType::kPostedMessage);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBeFrozen(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBeFrozen(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeFrozen(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kDOMManipulation);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeFrozen(true)
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
// Test some task types that were not configured through field trial
// parameters.
- task_queue = GetTaskQueue(TaskType::kInternalIPC);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanRunWhenVirtualTimePaused(true));
+ task_queue = GetTaskQueue(TaskType::kWebLocks);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
}
@@ -1892,7 +1903,7 @@ TEST_F(FreezableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
// Test some task types that were not configured through field trial
// parameters.
- task_queue = GetTaskQueue(TaskType::kInternalIPC);
+ task_queue = GetTaskQueue(TaskType::kWebLocks);
EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits());
task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
@@ -1921,38 +1932,44 @@ TEST_F(ThrottleableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
// Check that the overrides work.
auto task_queue = GetTaskQueue(TaskType::kPostedMessage);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kDOMManipulation);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
// Test some task types that were not configured through field trial
// parameters.
- task_queue = GetTaskQueue(TaskType::kInternalIPC);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanRunWhenVirtualTimePaused(true));
+ task_queue = GetTaskQueue(TaskType::kWebLocks);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false));
task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits()
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
}
class FrameSchedulerImplDatabaseAccessWithoutHighPriority
@@ -2283,6 +2300,7 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
std::unique_ptr<WebSchedulingTaskQueue> task_queue =
frame_scheduler_->CreateWebSchedulingTaskQueue(priority);
web_scheduling_task_runners_.push_back(task_queue->GetTaskRunner());
+ task_queues_.push_back(std::move(task_queue));
}
}
@@ -2336,6 +2354,8 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
Vector<scoped_refptr<base::SingleThreadTaskRunner>>
web_scheduling_task_runners_;
+
+ Vector<std::unique_ptr<WebSchedulingTaskQueue>> task_queues_;
};
TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) {
@@ -2348,6 +2368,18 @@ TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) {
"D2", "L1", "L2", "E1", "E2"));
}
+TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) {
+ Vector<String> run_order;
+
+ PostWebSchedulingTestTasks(&run_order, "E1 E2 D1 D2 I1 I2");
+ task_queues_[static_cast<int>(WebSchedulingPriority::kImmediatePriority)]
+ ->SetPriority(WebSchedulingPriority::kLowPriority);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order,
+ testing::ElementsAre("D1", "D2", "I1", "I2", "E1", "E2"));
+}
+
} // namespace frame_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
index c1542650192..18f4199534c 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
@@ -90,12 +90,13 @@ class FrameTaskQueueControllerTest : public testing::Test,
}
scoped_refptr<MainThreadTaskQueue> ThrottleableTaskQueue() const {
- return frame_task_queue_controller_->GetTaskQueue(QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBeFrozen(true)
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ return frame_task_queue_controller_->GetTaskQueue(
+ QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBeFrozen(true)
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
}
scoped_refptr<MainThreadTaskQueue> GetTaskQueue(
@@ -140,32 +141,31 @@ TEST_F(FrameTaskQueueControllerTest, CreateAllTaskQueues) {
// Create the 4 default task queues used by FrameSchedulerImpl.
task_queue = GetTaskQueue(QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBeDeferred(true)
- .SetCanBeFrozen(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ .SetCanBeThrottled(true)
+ .SetCanBeDeferred(true)
+ .SetCanBeFrozen(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
task_queue = GetTaskQueue(QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true)
+ .SetCanRunWhenVirtualTimePaused(false));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = GetTaskQueue(QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(true));
+ task_queue = GetTaskQueue(
+ QueueTraits().SetCanBePaused(true).SetCanRunWhenVirtualTimePaused(false));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = GetTaskQueue(QueueTraits()
- .SetCanRunWhenVirtualTimePaused(true));
+ task_queue =
+ GetTaskQueue(QueueTraits().SetCanRunWhenVirtualTimePaused(false));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
@@ -334,15 +334,15 @@ class TaskQueueCreationFromQueueTraitsTest :
public FrameTaskQueueControllerTest,
public testing::WithParamInterface<QueueTraits::PrioritisationType> {};
-INSTANTIATE_TEST_SUITE_P(,
- TaskQueueCreationFromQueueTraitsTest,
- ::testing::Values(
- QueueTraits::PrioritisationType::kVeryHigh,
- QueueTraits::PrioritisationType::kHigh,
- QueueTraits::PrioritisationType::kBestEffort,
- QueueTraits::PrioritisationType::kRegular,
- QueueTraits::PrioritisationType::kLoading,
- QueueTraits::PrioritisationType::kLoadingControl));
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ TaskQueueCreationFromQueueTraitsTest,
+ ::testing::Values(QueueTraits::PrioritisationType::kVeryHigh,
+ QueueTraits::PrioritisationType::kHigh,
+ QueueTraits::PrioritisationType::kBestEffort,
+ QueueTraits::PrioritisationType::kRegular,
+ QueueTraits::PrioritisationType::kLoading,
+ QueueTraits::PrioritisationType::kLoadingControl));
TEST_P(TaskQueueCreationFromQueueTraitsTest,
AddAndRetrieveAllTaskQueues) {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
index 48bb7f4d028..93b1d0f0c36 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
@@ -51,7 +51,8 @@ void IdleTimeEstimator::Clear() {
did_commit_ = false;
}
-void IdleTimeEstimator::WillProcessTask(const base::PendingTask& pending_task) {
+void IdleTimeEstimator::WillProcessTask(const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) {
nesting_level_++;
if (nesting_level_ == 1)
task_start_time_ = time_source_->NowTicks();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
index 1d726c34438..d83e5889358 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
@@ -36,7 +36,8 @@ class PLATFORM_EXPORT IdleTimeEstimator : public base::TaskObserver {
void Clear();
// TaskObserver implementation:
- void WillProcessTask(const base::PendingTask& pending_task) override;
+ void WillProcessTask(const base::PendingTask& pending_task,
+ bool was_blocked_or_low_priority) override;
void DidProcessTask(const base::PendingTask& pending_task) override;
private:
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
index 3fe2c879d17..5861836fbad 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
@@ -58,8 +58,8 @@ class IdleTimeEstimatorTest : public testing::Test {
void SimulateFrameWithOneCompositorTask(int compositor_time) {
base::TimeDelta non_idle_time =
base::TimeDelta::FromMilliseconds(compositor_time);
- base::PendingTask task(FROM_HERE, base::Closure());
- estimator_->WillProcessTask(task);
+ base::PendingTask task(FROM_HERE, base::OnceClosure());
+ estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
task_environment_.FastForwardBy(non_idle_time);
estimator_->DidCommitFrameToCompositor();
estimator_->DidProcessTask(task);
@@ -73,12 +73,12 @@ class IdleTimeEstimatorTest : public testing::Test {
base::TimeDelta::FromMilliseconds(compositor_time1);
base::TimeDelta non_idle_time2 =
base::TimeDelta::FromMilliseconds(compositor_time2);
- base::PendingTask task(FROM_HERE, base::Closure());
- estimator_->WillProcessTask(task);
+ base::PendingTask task(FROM_HERE, base::OnceClosure());
+ estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
task_environment_.FastForwardBy(non_idle_time1);
estimator_->DidProcessTask(task);
- estimator_->WillProcessTask(task);
+ estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
task_environment_.FastForwardBy(non_idle_time2);
estimator_->DidCommitFrameToCompositor();
estimator_->DidProcessTask(task);
@@ -151,8 +151,8 @@ TEST_F(IdleTimeEstimatorTest, IgnoresNestedTasks) {
SimulateFrameWithOneCompositorTask(5);
SimulateFrameWithOneCompositorTask(5);
- base::PendingTask task(FROM_HERE, base::Closure());
- estimator_->WillProcessTask(task);
+ base::PendingTask task(FROM_HERE, base::OnceClosure());
+ estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
SimulateFrameWithTwoCompositorTasks(4, 4);
SimulateFrameWithTwoCompositorTasks(4, 4);
SimulateFrameWithTwoCompositorTasks(4, 4);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
index 8b7f6d3fced..6a382c287f8 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_H_
#include "base/memory/scoped_refptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
index eed841a5929..a2b273e3c75 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -98,7 +98,7 @@ MainThreadMetricsHelper::MainThreadMetricsHelper(
bool has_cpu_timing_for_each_task,
base::TimeTicks now,
bool renderer_backgrounded)
- : MetricsHelper(WebThreadType::kMainThread, has_cpu_timing_for_each_task),
+ : MetricsHelper(ThreadType::kMainThread, has_cpu_timing_for_each_task),
main_thread_scheduler_(main_thread_scheduler),
renderer_shutting_down_(false),
main_thread_load_tracker_(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
index a3c75d5004b..23c338787a4 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
@@ -11,13 +11,13 @@
#include "components/scheduling_metrics/task_duration_metric_reporter.h"
#include "components/scheduling_metrics/total_duration_metric_reporter.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_load_tracker.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_status.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
namespace blink {
namespace scheduler {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 2dc7430c95a..1c1a13067ab 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -97,7 +97,7 @@ const char* BackgroundStateToString(bool is_backgrounded) {
if (is_backgrounded) {
return "renderer_backgrounded";
} else {
- return "renderer_visible";
+ return "renderer_foregrounded";
}
}
@@ -371,12 +371,12 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
&main_thread_scheduler_impl->tracing_controller_,
RAILModeToString),
renderer_hidden(false,
- "Scheduler.Hidden",
+ "RendererVisibility",
main_thread_scheduler_impl,
&main_thread_scheduler_impl->tracing_controller_,
HiddenStateToString),
renderer_backgrounded(kLaunchingProcessIsBackgrounded,
- "RendererVisibility",
+ "RendererPriority",
main_thread_scheduler_impl,
&main_thread_scheduler_impl->tracing_controller_,
BackgroundStateToString),
@@ -761,7 +761,7 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTaskQueue(
// they're not supposed to.
if (main_thread_only().virtual_time_stopped &&
main_thread_only().use_virtual_time &&
- task_queue->ShouldUseVirtualTime()) {
+ !task_queue->CanRunWhenVirtualTimePaused()) {
task_queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
}
@@ -792,7 +792,7 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTimerTaskQueue(
.SetCanBeDeferred(true)
.SetCanBeThrottled(true)
.SetFrameScheduler(frame_scheduler)
- .SetCanRunWhenVirtualTimePaused(true));
+ .SetCanRunWhenVirtualTimePaused(false));
}
std::unique_ptr<WebRenderWidgetSchedulingState>
@@ -844,6 +844,7 @@ void MainThreadSchedulerImpl::WillBeginFrame(const viz::BeginFrameArgs& args) {
any_thread().begin_main_frame_on_critical_path = args.on_critical_path;
}
main_thread_only().compositing_experiment.OnWillBeginMainFrame();
+ main_thread_only().compositor_priority_experiments.OnWillBeginMainFrame();
}
void MainThreadSchedulerImpl::DidCommitFrameToCompositor() {
@@ -1833,7 +1834,7 @@ void MainThreadSchedulerImpl::SetVirtualTimeStopped(bool virtual_time_stopped) {
void MainThreadSchedulerImpl::VirtualTimePaused() {
for (const auto& pair : task_runners_) {
- if (!pair.first->ShouldUseVirtualTime())
+ if (pair.first->CanRunWhenVirtualTimePaused())
continue;
DCHECK(!task_queue_throttler_->IsThrottled(pair.first.get()));
pair.first->InsertFence(TaskQueue::InsertFencePosition::kNow);
@@ -1842,7 +1843,7 @@ void MainThreadSchedulerImpl::VirtualTimePaused() {
void MainThreadSchedulerImpl::VirtualTimeResumed() {
for (const auto& pair : task_runners_) {
- if (!pair.first->ShouldUseVirtualTime())
+ if (pair.first->CanRunWhenVirtualTimePaused())
continue;
DCHECK(!task_queue_throttler_->IsThrottled(pair.first.get()));
DCHECK(pair.first->HasActiveFence());
@@ -2286,14 +2287,6 @@ void MainThreadSchedulerImpl::SetRendererProcessType(
main_thread_only().process_type = type;
}
-WebScopedVirtualTimePauser
-MainThreadSchedulerImpl::CreateWebScopedVirtualTimePauser(
- const char* name,
- WebScopedVirtualTimePauser::VirtualTaskDuration duration) {
- return WebScopedVirtualTimePauser(this, duration,
- WebString(WTF::String(name)));
-}
-
PendingUserInputInfo MainThreadSchedulerImpl::GetPendingUserInputInfo() const {
base::AutoLock lock(any_thread_lock_);
return any_thread().pending_input_monitor.Info();
@@ -2416,7 +2409,7 @@ void MainThreadSchedulerImpl::OnTaskReady(
const void* frame_scheduler,
const base::sequence_manager::Task& task,
base::sequence_manager::LazyNow* lazy_now) {
- frame_interference_recorder_.OnTaskReady(frame_scheduler,
+ agent_interference_recorder_.OnTaskReady(frame_scheduler,
task.enqueue_order(), lazy_now);
}
@@ -2426,7 +2419,7 @@ void MainThreadSchedulerImpl::OnTaskStarted(
const TaskQueue::TaskTiming& task_timing) {
main_thread_only().running_queues.push(queue);
queueing_time_estimator_.OnExecutionStarted(task_timing.start_time());
- frame_interference_recorder_.OnTaskStarted(queue, task.enqueue_order(),
+ agent_interference_recorder_.OnTaskStarted(queue, task.enqueue_order(),
task_timing.start_time());
if (main_thread_only().nested_runloop)
return;
@@ -2462,7 +2455,7 @@ void MainThreadSchedulerImpl::OnTaskCompleted(
queue->GetFrameScheduler()->AddTaskTime(task_timing->wall_duration());
main_thread_only().running_queues.pop();
queueing_time_estimator_.OnExecutionStopped(task_timing->end_time());
- frame_interference_recorder_.OnTaskCompleted(queue.get(),
+ agent_interference_recorder_.OnTaskCompleted(queue.get(),
task_timing->end_time());
if (main_thread_only().nested_runloop)
return;
@@ -2613,7 +2606,7 @@ void MainThreadSchedulerImpl::OnBeginNestedRunLoop() {
// When a nested loop is entered, simulate completing the current task. It
// will be resumed when the run loop is exited.
queueing_time_estimator_.OnExecutionStopped(now);
- frame_interference_recorder_.OnTaskCompleted(
+ agent_interference_recorder_.OnTaskCompleted(
main_thread_only().running_queues.top().get(), now);
main_thread_only().nested_runloop = true;
ApplyVirtualTimePolicy();
@@ -2625,7 +2618,7 @@ void MainThreadSchedulerImpl::OnExitNestedRunLoop() {
queueing_time_estimator_.OnExecutionStarted(now);
// When a nested loop is exited, resume the task that was running when the
// nested loop was entered.
- frame_interference_recorder_.OnTaskStarted(
+ agent_interference_recorder_.OnTaskStarted(
main_thread_only().running_queues.top().get(),
base::sequence_manager::EnqueueOrder::none(), now);
main_thread_only().nested_runloop = false;
@@ -2832,7 +2825,7 @@ void MainThreadSchedulerImpl::ExecuteAfterCurrentTask(
void MainThreadSchedulerImpl::OnFrameSchedulerDestroyed(
FrameSchedulerImpl* frame_scheduler) {
- frame_interference_recorder_.OnFrameSchedulerDestroyed(frame_scheduler);
+ agent_interference_recorder_.OnFrameSchedulerDestroyed(frame_scheduler);
}
void MainThreadSchedulerImpl::DispatchOnTaskCompletionCallbacks() {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index 968935ee12b..612cd8ea852 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -28,10 +28,10 @@
#include "third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h"
@@ -215,9 +215,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void AddRAILModeObserver(RAILModeObserver* observer) override;
void RemoveRAILModeObserver(RAILModeObserver const* observer) override;
void SetRendererProcessType(WebRendererProcessType type) override;
- WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
- const char* name,
- WebScopedVirtualTimePauser::VirtualTaskDuration duration) override;
PendingUserInputInfo GetPendingUserInputInfo() const override;
bool IsBeginMainFrameScheduled() const override;
@@ -839,7 +836,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
QueueingTimeEstimator queueing_time_estimator_;
- FrameInterferenceRecorder frame_interference_recorder_;
+ AgentInterferenceRecorder agent_interference_recorder_;
// We have decided to improve thread safety at the cost of some boilerplate
// (the accessors) for the following data members.
@@ -865,7 +862,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
renderer_pause_count; // Renderer is paused if non-zero.
TraceableState<RAILMode, TracingCategoryName::kInfo>
rail_mode_for_tracing; // Don't use except for tracing.
- TraceableState<bool, TracingCategoryName::kDebug> renderer_hidden;
+ TraceableState<bool, TracingCategoryName::kTopLevel> renderer_hidden;
TraceableState<bool, TracingCategoryName::kTopLevel> renderer_backgrounded;
TraceableState<bool, TracingCategoryName::kDefault>
keep_active_fetch_or_worker;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index ae4606816ef..807506d92e1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/callback.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/task/post_task.h"
@@ -19,6 +18,7 @@
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/task_executor.h"
#include "base/test/bind_test_util.h"
+#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
@@ -46,6 +46,7 @@ namespace scheduler {
// To avoid symbol collisions in jumbo builds.
namespace main_thread_scheduler_impl_unittest {
+using testing::IsNull;
using testing::Mock;
using testing::NotNull;
using InputEventState = WebThreadScheduler::InputEventState;
@@ -860,7 +861,7 @@ class MainThreadSchedulerImplTest
DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplTest);
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
MainThreadSchedulerImplTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -1335,7 +1336,7 @@ class DefaultUseCaseTest : public MainThreadSchedulerImplTest {
}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
DefaultUseCaseTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -2135,83 +2136,23 @@ TEST_P(MainThreadSchedulerImplTest, CurrentThread) {
{base::CurrentThread(), base::TaskPriority::BEST_EFFORT}));
}
-class MainThreadSchedulerImplWithMessageLoopTest
- : public MainThreadSchedulerImplTest {
- public:
- MainThreadSchedulerImplWithMessageLoopTest()
- : message_loop_(new base::MessageLoop()) {}
- ~MainThreadSchedulerImplWithMessageLoopTest() override = default;
-
- void SetUp() override {
- clock_.Advance(base::TimeDelta::FromMilliseconds(5));
- Initialize(std::make_unique<MainThreadSchedulerImplForTest>(
- base::sequence_manager::SequenceManagerForTest::CreateOnCurrentThread(
- base::sequence_manager::SequenceManager::Settings::Builder()
- .SetTickClock(&clock_)
- .SetAntiStarvationLogicForPrioritiesDisabled(
- GetParam() == AntiStarvationLogic::kDisabled)
- .Build()),
- base::nullopt));
- }
-
- // Needed for EnableIdleTasks().
- base::TimeTicks Now() override { return clock_.NowTicks(); }
-
- void PostFromNestedRunloop(
- Vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
- for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
- if (pair.second) {
- idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first));
- } else {
- idle_task_runner_->PostNonNestableIdleTask(FROM_HERE,
- std::move(pair.first));
- }
- }
- EnableIdleTasks();
- base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
- }
-
- private:
- std::unique_ptr<base::MessageLoop> message_loop_;
- base::SimpleTestTickClock clock_;
-
- DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplWithMessageLoopTest);
-};
-
-INSTANTIATE_TEST_SUITE_P(,
- MainThreadSchedulerImplWithMessageLoopTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(MainThreadSchedulerImplWithMessageLoopTest,
- NonNestableIdleTaskDoesntExecuteInNestedLoop) {
- Vector<String> order;
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::BindOnce(&AppendToVectorIdleTestTask, &order, "1"));
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::BindOnce(&AppendToVectorIdleTestTask, &order, "2"));
-
- Vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>
- tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "3"), false));
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "4"), true));
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::BindOnce(&AppendToVectorIdleTestTask, &order, "5"), true));
+TEST_P(MainThreadSchedulerImplTest, GetContinuationTaskRunner) {
+ scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+ auto task_runner = timer_tq->CreateTaskRunner(TaskType::kJavascriptTimer);
- default_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &MainThreadSchedulerImplWithMessageLoopTest::PostFromNestedRunloop,
- base::Unretained(this),
- base::Unretained(&tasks_to_post_from_nested_loop)));
+ base::RunLoop run_loop;
+ task_runner->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() {
+ EXPECT_EQ(task_runner,
+ base::GetContinuationTaskRunner());
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+}
- EnableIdleTasks();
- base::RunLoop().RunUntilIdle();
- // Note we expect task 3 to run last because it's non-nestable.
- EXPECT_THAT(order, testing::ElementsAre("1", "2", "4", "5", "3"));
+TEST_P(MainThreadSchedulerImplTest,
+ GetContinuationTaskRunnerWithNoTaskRunning) {
+ EXPECT_DCHECK_DEATH(base::GetContinuationTaskRunner());
}
TEST_P(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
@@ -3213,9 +3154,9 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauser) {
scheduler_->SetVirtualTimePolicy(
PageSchedulerImpl::VirtualTimePolicy::kDeterministicLoading);
- WebScopedVirtualTimePauser pauser =
- scheduler_->CreateWebScopedVirtualTimePauser(
- "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant);
+ WebScopedVirtualTimePauser pauser(
+ scheduler_.get(),
+ WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant, "test");
base::TimeTicks before = scheduler_->GetVirtualTimeDomain()->Now();
EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance());
@@ -3234,9 +3175,9 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) {
scheduler_->SetVirtualTimePolicy(
PageSchedulerImpl::VirtualTimePolicy::kDeterministicLoading);
- WebScopedVirtualTimePauser pauser =
- scheduler_->CreateWebScopedVirtualTimePauser(
- "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
+ WebScopedVirtualTimePauser pauser(
+ scheduler_.get(),
+ WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant, "test");
base::TimeTicks before = scheduler_->GetVirtualTimeDomain()->Now();
pauser.PauseVirtualTime();
@@ -3254,9 +3195,9 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) {
scheduler_->SetVirtualTimePolicy(
PageSchedulerImpl::VirtualTimePolicy::kDeterministicLoading);
- WebScopedVirtualTimePauser pauser =
- scheduler_->CreateWebScopedVirtualTimePauser(
- "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
+ WebScopedVirtualTimePauser pauser(
+ scheduler_.get(),
+ WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant, "test");
// Test will pass if the queue without virtual is the last one in the
// iteration order. Create 100 of them and ensure that it is created in the
@@ -3268,7 +3209,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) {
task_queues.push_back(scheduler_->NewTaskQueue(
MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kFrameThrottleable)
- .SetCanRunWhenVirtualTimePaused(i != 42)));
+ .SetCanRunWhenVirtualTimePaused(i == 42)));
}
// This should install a fence on all queues with virtual time.
@@ -3514,7 +3455,7 @@ class MainThreadSchedulerImplWithInitalVirtualTimeTest
}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
MainThreadSchedulerImplWithInitalVirtualTimeTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3538,7 +3479,7 @@ class CompositingExperimentWithExplicitSignalsTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
CompositingExperimentWithExplicitSignalsTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3580,7 +3521,7 @@ class CompositingExperimentWithImplicitSignalsTest
kUseWillBeginMainFrameForCompositingPrioritization}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
CompositingExperimentWithImplicitSignalsTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3705,7 +3646,7 @@ class VeryHighPriorityForCompositingAlwaysExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
VeryHighPriorityForCompositingAlwaysExperimentTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3731,7 +3672,7 @@ class VeryHighPriorityForCompositingWhenFastExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
VeryHighPriorityForCompositingWhenFastExperimentTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3787,7 +3728,7 @@ class VeryHighPriorityForCompositingAlternatingExperimentTest
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
VeryHighPriorityForCompositingAlternatingExperimentTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3828,7 +3769,7 @@ class VeryHighPriorityForCompositingAfterDelayExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
VeryHighPriorityForCompositingAfterDelayExperimentTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3848,7 +3789,7 @@ TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) {
- // 1.5ms task to complete the countdown and prioritze compositing.
+ // 150ms task to complete the countdown and prioritze compositing.
AdvanceTimeWithTask(0.15);
Vector<String> run_order;
@@ -3884,7 +3825,7 @@ class VeryHighPriorityForCompositingBudgetExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
VeryHighPriorityForCompositingBudgetExperimentTest,
testing::Values(AntiStarvationLogic::kEnabled,
AntiStarvationLogic::kDisabled),
@@ -3947,6 +3888,126 @@ TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
+class VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest
+ : public MainThreadSchedulerImplTest {
+ public:
+ VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest()
+ : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingAlternating,
+ kPrioritizeCompositingUntilBeginMainFrame},
+ {}) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
+ testing::Values(AntiStarvationLogic::kEnabled,
+ AntiStarvationLogic::kDisabled),
+ GetTestNameSuffix);
+
+TEST_P(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
+ TestCompositorPolicy_AlternatingCompositorTasks) {
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "C1 D1 C2 D2");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+
+ // Next compositor task is the BeginMainFrame. Compositor priority is set
+ // to normal for a single task before being prioritized again.
+ DoMainFrame();
+
+ run_order.clear();
+ PostTestTasks(&run_order, "C1 D1 D2 C2");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("C1", "D1", "C2", "D2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+}
+
+class VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest
+ : public MainThreadSchedulerImplTest {
+ public:
+ VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest()
+ : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingAfterDelay,
+ kPrioritizeCompositingUntilBeginMainFrame},
+ {}) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest,
+ testing::Values(AntiStarvationLogic::kEnabled,
+ AntiStarvationLogic::kDisabled),
+ GetTestNameSuffix);
+
+TEST_P(
+ VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest,
+ TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) {
+ // 150ms task to complete the countdown and prioritze compositing.
+ AdvanceTimeWithTask(0.15);
+
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "C2", "D1", "D2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+
+ // Next compositor task is the BeginMainFrame.
+ DoMainFrame();
+ run_order.clear();
+ PostTestTasks(&run_order, "C1 D1 D2 C2 P1");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "D1", "D2", "C2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+}
+
+class VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest
+ : public MainThreadSchedulerImplTest {
+ public:
+ VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest()
+ : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingBudget,
+ kPrioritizeCompositingUntilBeginMainFrame},
+ {}) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
+ testing::Values(AntiStarvationLogic::kEnabled,
+ AntiStarvationLogic::kDisabled),
+ GetTestNameSuffix);
+
+TEST_P(
+ VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
+ TestCompositorPolicy_CompositorPriorityNonBeginMainFrameDoesntExhaustBudget) {
+ // 1000ms compositor task will not exhaust the budget.
+ RunSlowCompositorTask();
+
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "C2", "D1", "D2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+}
+
+TEST_P(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
+ TestCompositorPolicy_CompositorPriorityBeginMainFrameExhaustsBudget) {
+ // 1000ms BeginMainFrame will exhaust the budget.
+ DoMainFrame();
+ RunSlowCompositorTask();
+
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "D1", "C1", "D2", "C2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+}
+
} // namespace main_thread_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
index e4d579aabab..d008643dc43 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@@ -251,6 +252,14 @@ base::Optional<net::RequestPriority> MainThreadTaskQueue::net_request_priority()
return net_request_priority_;
}
+void MainThreadTaskQueue::SetWebSchedulingPriority(
+ WebSchedulingPriority priority) {
+ if (web_scheduling_priority_ == priority)
+ return;
+ web_scheduling_priority_ = priority;
+ frame_scheduler_->OnWebSchedulingTaskQueuePriorityChanged(this);
+}
+
base::Optional<WebSchedulingPriority>
MainThreadTaskQueue::web_scheduling_priority() const {
return web_scheduling_priority_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
index 4348ecfccf9..c1ea93cd184 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -27,8 +27,8 @@ namespace main_thread_scheduler_impl_unittest {
class MainThreadSchedulerImplTest;
}
-namespace frame_interference_recorder_test {
-class FrameInterferenceRecorderTest;
+namespace agent_interference_recorder_test {
+class AgentInterferenceRecorderTest;
}
class FrameSchedulerImpl;
@@ -118,7 +118,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
can_be_paused(false),
can_be_frozen(false),
can_run_in_background(true),
- can_run_when_virtual_time_paused(false) {}
+ can_run_when_virtual_time_paused(true) {}
// Separate enum class for handling prioritisation decisions in task queues.
enum class PrioritisationType {
@@ -345,7 +345,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
return queue_traits_.can_run_in_background;
}
- bool ShouldUseVirtualTime() const {
+ bool CanRunWhenVirtualTimePaused() const {
return queue_traits_.can_run_when_virtual_time_paused;
}
@@ -384,8 +384,13 @@ class PLATFORM_EXPORT MainThreadTaskQueue
void SetNetRequestPriority(net::RequestPriority net_request_priority);
base::Optional<net::RequestPriority> net_request_priority() const;
+ void SetWebSchedulingPriority(WebSchedulingPriority priority);
base::Optional<WebSchedulingPriority> web_scheduling_priority() const;
+ base::WeakPtr<MainThreadTaskQueue> AsWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
protected:
void SetFrameSchedulerForTest(FrameSchedulerImpl* frame_scheduler);
@@ -400,7 +405,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
friend class base::sequence_manager::SequenceManager;
friend class blink::scheduler::main_thread_scheduler_impl_unittest::
MainThreadSchedulerImplTest;
- friend class frame_interference_recorder_test::FrameInterferenceRecorderTest;
+ friend class agent_interference_recorder_test::AgentInterferenceRecorderTest;
// Clear references to main thread scheduler and frame scheduler and dispatch
// appropriate notifications. This is the common part of ShutdownTaskQueue and
@@ -424,10 +429,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
// |web_scheduling_priority_| is the priority of the task queue within the web
// scheduling API. This priority is used in conjunction with the frame
// scheduling policy to determine the task queue priority.
- //
- // For the initial prototype, we aren't allowing the priority to change since
- // we're only implementing a set of global task queues.
- const base::Optional<WebSchedulingPriority> web_scheduling_priority_;
+ base::Optional<WebSchedulingPriority> web_scheduling_priority_;
// Needed to notify renderer scheduler about completed tasks.
MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
index 741c0442f22..992fe514fdb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
@@ -41,7 +41,7 @@ class MockTask {
class MockTaskObserver : public Thread::TaskObserver {
public:
- MOCK_METHOD1(WillProcessTask, void(const base::PendingTask&));
+ MOCK_METHOD2(WillProcessTask, void(const base::PendingTask&, bool));
MOCK_METHOD1(DidProcessTask, void(const base::PendingTask&));
};
@@ -88,7 +88,8 @@ TEST_F(MainThreadTest, TestTaskObserver) {
{
testing::InSequence sequence;
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task, Run());
EXPECT_CALL(observer, DidProcessTask(_));
}
@@ -107,7 +108,8 @@ TEST_F(MainThreadTest, TestWorkBatchWithOneTask) {
SetWorkBatchSizeForTesting(kWorkBatchSize);
{
testing::InSequence sequence;
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task, Run());
EXPECT_CALL(observer, DidProcessTask(_));
}
@@ -127,11 +129,13 @@ TEST_F(MainThreadTest, TestWorkBatchWithTwoTasks) {
SetWorkBatchSizeForTesting(kWorkBatchSize);
{
testing::InSequence sequence;
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task1, Run());
EXPECT_CALL(observer, DidProcessTask(_));
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task2, Run());
EXPECT_CALL(observer, DidProcessTask(_));
}
@@ -154,15 +158,18 @@ TEST_F(MainThreadTest, TestWorkBatchWithThreeTasks) {
SetWorkBatchSizeForTesting(kWorkBatchSize);
{
testing::InSequence sequence;
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task1, Run());
EXPECT_CALL(observer, DidProcessTask(_));
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task2, Run());
EXPECT_CALL(observer, DidProcessTask(_));
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
EXPECT_CALL(task3, Run());
EXPECT_CALL(observer, DidProcessTask(_));
}
@@ -194,10 +201,12 @@ TEST_F(MainThreadTest, TestNestedRunLoop) {
testing::InSequence sequence;
// One callback for EnterRunLoop.
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
// A pair for ExitRunLoopTask.
- EXPECT_CALL(observer, WillProcessTask(_));
+ EXPECT_CALL(observer,
+ WillProcessTask(_, /* was_blocked_or_low_priority */ false));
EXPECT_CALL(observer, DidProcessTask(_));
// A final callback for EnterRunLoop.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index 1779e616c30..c565d53c085 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -768,6 +768,12 @@ FrameSchedulerImpl* PageSchedulerImpl::SelectFrameForUkmAttribution() {
return nullptr;
}
+WebScopedVirtualTimePauser PageSchedulerImpl::CreateWebScopedVirtualTimePauser(
+ const String& name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration duration) {
+ return WebScopedVirtualTimePauser(main_thread_scheduler_, duration, name);
+}
+
// static
const char PageSchedulerImpl::kHistogramPageLifecycleStateTransition[] =
"PageScheduler.PageLifecycleStateTransition";
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 4de806f047b..e1370f474b2 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -77,6 +77,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
bool IsExemptFromBudgetBasedThrottling() const override;
bool OptedOutFromAggressiveThrottlingForTest() const override;
bool RequestBeginMainFrameNotExpected(bool new_state) override;
+ WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+ const WTF::String& name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration) override;
// Virtual for testing.
virtual void ReportIntervention(const String& message);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc
deleted file mode 100644
index 6d7b3bf6331..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc
+++ /dev/null
@@ -1,74 +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 "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h"
-
-#include <memory>
-
-#include "base/test/simple_test_tick_clock.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-namespace scheduler {
-
-class TaskCostEstimatorTest : public testing::Test {
- public:
- TaskCostEstimatorTest() = default;
- ~TaskCostEstimatorTest() override = default;
-
- base::SimpleTestTickClock clock_;
-};
-
-class TaskCostEstimatorForTest : public TaskCostEstimator {
- public:
- TaskCostEstimatorForTest(const base::TickClock* clock,
- int sample_count,
- double estimation_percentile)
- : TaskCostEstimator(clock, sample_count, estimation_percentile) {}
-};
-
-TEST_F(TaskCostEstimatorTest, BasicEstimation) {
- TaskCostEstimatorForTest estimator(&clock_, 1, 100);
- base::PendingTask task(FROM_HERE, base::Closure());
-
- estimator.WillProcessTask(task);
- clock_.Advance(base::TimeDelta::FromMilliseconds(500));
- estimator.DidProcessTask(task);
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(500),
- estimator.expected_task_duration());
-}
-
-TEST_F(TaskCostEstimatorTest, Clear) {
- TaskCostEstimatorForTest estimator(&clock_, 1, 100);
- base::PendingTask task(FROM_HERE, base::Closure());
-
- estimator.WillProcessTask(task);
- clock_.Advance(base::TimeDelta::FromMilliseconds(500));
- estimator.DidProcessTask(task);
-
- estimator.Clear();
-
- EXPECT_EQ(base::TimeDelta(), estimator.expected_task_duration());
-}
-
-TEST_F(TaskCostEstimatorTest, NestedRunLoop) {
- TaskCostEstimatorForTest estimator(&clock_, 1, 100);
- base::PendingTask task(FROM_HERE, base::Closure());
-
- // Make sure we ignore the tasks inside the nested run loop.
- estimator.WillProcessTask(task);
- estimator.WillProcessTask(task);
- clock_.Advance(base::TimeDelta::FromMilliseconds(500));
- estimator.DidProcessTask(task);
- clock_.Advance(base::TimeDelta::FromMilliseconds(500));
- estimator.DidProcessTask(task);
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000),
- estimator.expected_task_duration());
-}
-
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
index a21f77ad9ab..46cbd2b9c41 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -85,8 +85,6 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
return "InternalMedia";
case TaskType::kInternalMediaRealTime:
return "InternalMediaRealTime";
- case TaskType::kInternalIPC:
- return "InternalIPC";
case TaskType::kInternalUserInteraction:
return "InternalUserInteraction";
case TaskType::kInternalInspector:
@@ -129,12 +127,14 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
return "InternalContentCapture";
case TaskType::kInternalNavigationAssociated:
return "InternalNavigationAssociated";
- case TaskType::kInternalFreezableIPC:
- return "InternalFreezableIPC";
+ case TaskType::kInternalNavigationAssociatedUnfreezable:
+ return "InternalNavigationAssociatedUnfreezable";
case TaskType::kInternalContinueScriptLoading:
return "InternalContinueScriptLoading";
case TaskType::kExperimentalWebScheduling:
return "ExperimentalWebScheduling";
+ case TaskType::kInternalFrameLifecycleControl:
+ return "InternalFrameLifecycleControl";
case TaskType::kCount:
return "Count";
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.cc
index a8a7ce32c6f..30b6e4b4ea3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.cc
@@ -11,11 +11,15 @@ namespace blink {
namespace scheduler {
WebSchedulingTaskQueueImpl::WebSchedulingTaskQueueImpl(
- WebSchedulingPriority priority,
- MainThreadTaskQueue* task_queue)
- : priority_(priority),
- task_runner_(
- task_queue->CreateTaskRunner(TaskType::kExperimentalWebScheduling)) {}
+ base::WeakPtr<MainThreadTaskQueue> task_queue)
+ : task_runner_(
+ task_queue->CreateTaskRunner(TaskType::kExperimentalWebScheduling)),
+ task_queue_(std::move(task_queue)) {}
+
+void WebSchedulingTaskQueueImpl::SetPriority(WebSchedulingPriority priority) {
+ if (task_queue_)
+ task_queue_->SetWebSchedulingPriority(priority);
+}
scoped_refptr<base::SingleThreadTaskRunner>
WebSchedulingTaskQueueImpl::GetTaskRunner() {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h
index 3dfba911764..a4da9eaf1af 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h"
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
@@ -20,16 +21,16 @@ class MainThreadTaskQueue;
class PLATFORM_EXPORT WebSchedulingTaskQueueImpl
: public WebSchedulingTaskQueue {
public:
- WebSchedulingTaskQueueImpl(WebSchedulingPriority, MainThreadTaskQueue*);
+ WebSchedulingTaskQueueImpl(base::WeakPtr<MainThreadTaskQueue>);
~WebSchedulingTaskQueueImpl() override = default;
- WebSchedulingPriority Priority() override { return priority_; }
+ void SetPriority(WebSchedulingPriority) override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
private:
- const WebSchedulingPriority priority_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ base::WeakPtr<MainThreadTaskQueue> task_queue_;
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
index a9b9b59b581..7aec66e6e0f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
+#include "base/unguessable_token.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
@@ -49,6 +50,8 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// accordingly.
virtual void UpdateActiveSchedulerTrackedFeatures(
uint64_t features_mask) = 0;
+
+ virtual const base::UnguessableToken& GetAgentClusterId() const = 0;
};
~FrameScheduler() override = default;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
index 43e6e766faa..3d7dde3229f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -7,6 +7,7 @@
#include <memory>
#include "third_party/blink/public/platform/blame_context.h"
+#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
@@ -140,6 +141,16 @@ class PLATFORM_EXPORT PageScheduler {
// Returns true if the request has been succcessfully relayed to the
// compositor.
virtual bool RequestBeginMainFrameNotExpected(bool new_state) = 0;
+
+ // Returns a WebScopedVirtualTimePauser which can be used to vote for pausing
+ // virtual time. Virtual time will be paused if any WebScopedVirtualTimePauser
+ // votes to pause it, and only unpaused only if all
+ // WebScopedVirtualTimePausers are either destroyed or vote to unpause. Note
+ // the WebScopedVirtualTimePauser returned by this method is initially
+ // unpaused.
+ virtual WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+ const String& name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration) = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h b/chromium/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h
index ae66c73c336..f5ae7fda80f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h
@@ -56,6 +56,15 @@ class PLATFORM_EXPORT TaskHandle {
const base::Location&,
base::OnceClosure,
base::TimeDelta delay) WARN_UNUSED_RESULT;
+ friend PLATFORM_EXPORT TaskHandle
+ PostNonNestableCancellableTask(base::SequencedTaskRunner&,
+ const base::Location&,
+ base::OnceClosure) WARN_UNUSED_RESULT;
+ friend PLATFORM_EXPORT TaskHandle PostNonNestableDelayedCancellableTask(
+ base::SequencedTaskRunner&,
+ const base::Location&,
+ base::OnceClosure,
+ base::TimeDelta delay) WARN_UNUSED_RESULT;
explicit TaskHandle(scoped_refptr<Runner>);
scoped_refptr<Runner> runner_;
@@ -72,6 +81,15 @@ PostDelayedCancellableTask(base::SequencedTaskRunner&,
const base::Location&,
base::OnceClosure,
base::TimeDelta delay) WARN_UNUSED_RESULT;
+PLATFORM_EXPORT TaskHandle
+PostNonNestableCancellableTask(base::SequencedTaskRunner&,
+ const base::Location&,
+ base::OnceClosure) WARN_UNUSED_RESULT;
+PLATFORM_EXPORT TaskHandle
+PostNonNestableDelayedCancellableTask(base::SequencedTaskRunner&,
+ const base::Location&,
+ base::OnceClosure,
+ base::TimeDelta delay) WARN_UNUSED_RESULT;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/thread.h b/chromium/third_party/blink/renderer/platform/scheduler/public/thread.h
index d02598fed23..6f6b57e5eef 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/thread.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/thread.h
@@ -31,8 +31,8 @@
#include "base/memory/scoped_refptr.h"
#include "base/task/task_observer.h"
#include "base/threading/thread.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace base {
@@ -53,7 +53,7 @@ class Platform;
typedef uintptr_t PlatformThreadId;
struct PLATFORM_EXPORT ThreadCreationParams {
- explicit ThreadCreationParams(WebThreadType);
+ explicit ThreadCreationParams(ThreadType);
ThreadCreationParams& SetThreadNameForTest(const char* name);
@@ -63,10 +63,14 @@ struct PLATFORM_EXPORT ThreadCreationParams {
ThreadCreationParams& SetSupportsGC(bool supports_gc);
- WebThreadType thread_type;
+ ThreadType thread_type;
const char* name;
FrameOrWorkerScheduler* frame_or_worker_scheduler; // NOT OWNED
+
+ // Do NOT set the thread priority for non-WebAudio usages. Please consult
+ // scheduler-dev@ first in order to use an elevated thread priority.
base::ThreadPriority thread_priority = base::ThreadPriority::NORMAL;
+
bool supports_gc = false;
};
@@ -91,10 +95,6 @@ class PLATFORM_EXPORT Thread {
// nested Web workers).
static std::unique_ptr<Thread> CreateThread(const ThreadCreationParams&);
- // Creates a WebAudio-specific thread with the elevated priority. Do NOT use
- // for any other purpose.
- static std::unique_ptr<Thread> CreateWebAudioThread();
-
// Create and save (as a global variable) the compositor thread. The thread
// will be accessible through CompositorThread().
static void CreateAndSetCompositorThread();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/thread_type.h b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_type.h
new file mode 100644
index 00000000000..9db498a836d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_type.h
@@ -0,0 +1,39 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_TYPE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_TYPE_H_
+
+#include "third_party/blink/public/platform/web_common.h"
+
+namespace blink {
+
+enum class ThreadType {
+ kMainThread = 0,
+ kUnspecifiedWorkerThread = 1,
+ kCompositorThread = 2,
+ kDedicatedWorkerThread = 3,
+ kSharedWorkerThread = 4,
+ kAnimationAndPaintWorkletThread = 5,
+ kServiceWorkerThread = 6,
+ kAudioWorkletThread = 7,
+ kFileThread = 8,
+ kDatabaseThread = 9,
+ // 10 was kWebAudioThread, which was deleted (crbug.com/965093)
+ // 11 was kScriptStreamerThread, which was deleted
+ kOfflineAudioRenderThread = 12,
+ kReverbConvolutionBackgroundThread = 13,
+ kHRTFDatabaseLoaderThread = 14,
+ kTestThread = 15,
+ kAudioEncoderThread = 16,
+ kVideoEncoderThread = 17,
+
+ kCount = 18
+};
+
+BLINK_PLATFORM_EXPORT const char* GetNameForThreadType(ThreadType);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_TYPE_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h
index 12f5f63a4c9..0f580027676 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h
@@ -19,7 +19,7 @@ class PLATFORM_EXPORT WebSchedulingTaskQueue {
public:
virtual ~WebSchedulingTaskQueue() = default;
- virtual WebSchedulingPriority Priority() = 0;
+ virtual void SetPriority(WebSchedulingPriority) = 0;
// Returns a task runner that is suitable with the web scheduling task type
// associated with the priority of this task queue.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc
index 77436eda6dd..df492a1ae43 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc
@@ -9,7 +9,7 @@ namespace scheduler {
CompositorMetricsHelper::CompositorMetricsHelper(
bool has_cpu_timing_for_each_task)
- : MetricsHelper(WebThreadType::kCompositorThread,
+ : MetricsHelper(ThreadType::kCompositorThread,
has_cpu_timing_for_each_task) {}
CompositorMetricsHelper::~CompositorMetricsHelper() {}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
index dbf2da6cac1..984cb2d01cc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
@@ -8,9 +8,9 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "components/scheduling_metrics/task_duration_metric_reporter.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h"
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
index 4c197588af2..9fa43c7996e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
@@ -22,7 +22,7 @@ NonMainThreadSchedulerImpl::~NonMainThreadSchedulerImpl() = default;
// static
std::unique_ptr<NonMainThreadSchedulerImpl> NonMainThreadSchedulerImpl::Create(
- WebThreadType thread_type,
+ ThreadType thread_type,
base::sequence_manager::SequenceManager* sequence_manager,
WorkerSchedulerProxy* proxy) {
return std::make_unique<WorkerThreadScheduler>(thread_type, sequence_manager,
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
index 22369c28708..451a002e4ae 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
@@ -11,12 +11,12 @@
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/task_queue.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h"
@@ -32,7 +32,7 @@ class PLATFORM_EXPORT NonMainThreadSchedulerImpl : public ThreadSchedulerImpl {
// |sequence_manager| and |proxy| must remain valid for the entire lifetime of
// this object.
static std::unique_ptr<NonMainThreadSchedulerImpl> Create(
- WebThreadType thread_type,
+ ThreadType thread_type,
base::sequence_manager::SequenceManager* sequence_manager,
WorkerSchedulerProxy* proxy);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.cc
index 553db17d9e2..2af89dfabd4 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.cc
@@ -9,7 +9,7 @@
namespace blink {
namespace scheduler {
-WorkerMetricsHelper::WorkerMetricsHelper(WebThreadType thread_type,
+WorkerMetricsHelper::WorkerMetricsHelper(ThreadType thread_type,
bool has_cpu_timing_for_each_task)
: MetricsHelper(thread_type, has_cpu_timing_for_each_task),
dedicated_worker_per_task_type_duration_reporter_(
@@ -39,7 +39,7 @@ void WorkerMetricsHelper::RecordTaskMetrics(
bool backgrounded = internal::ProcessState::Get()->is_process_backgrounded;
- if (thread_type_ == WebThreadType::kDedicatedWorkerThread) {
+ if (thread_type_ == ThreadType::kDedicatedWorkerThread) {
TaskType task_type = static_cast<TaskType>(task.task_type);
dedicated_worker_per_task_type_duration_reporter_.RecordTask(
task_type, task_timing.wall_duration());
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
index 56db0582bd0..10862bc917f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
@@ -16,7 +16,7 @@ namespace scheduler {
class PLATFORM_EXPORT WorkerMetricsHelper : public MetricsHelper {
public:
- explicit WorkerMetricsHelper(WebThreadType thread_type,
+ explicit WorkerMetricsHelper(ThreadType thread_type,
bool has_cpu_timing_for_each_task);
~WorkerMetricsHelper();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
index 6a24bff4d02..b9a44ecca6e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -169,7 +169,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kInternalMediaRealTime:
case TaskType::kInternalUserInteraction:
case TaskType::kInternalIntersectionObserver:
- case TaskType::kInternalFreezableIPC:
+ case TaskType::kInternalNavigationAssociated:
case TaskType::kInternalContinueScriptLoading:
// UnthrottledTaskRunner is generally discouraged in future.
// TODO(nhiroki): Identify which tasks can be throttled / suspendable and
@@ -177,10 +177,9 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
// Get(LocalFrame). (https://crbug.com/670534)
return pausable_task_queue_->CreateTaskRunner(type);
case TaskType::kDeprecatedNone:
- case TaskType::kInternalIPC:
case TaskType::kInternalInspector:
case TaskType::kInternalTest:
- case TaskType::kInternalNavigationAssociated:
+ case TaskType::kInternalNavigationAssociatedUnfreezable:
// kWebLocks can be frozen if for entire page, but not for individual
// frames. See https://crrev.com/c/1687716
case TaskType::kWebLocks:
@@ -207,6 +206,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kServiceWorkerClientMessage:
case TaskType::kInternalContentCapture:
case TaskType::kExperimentalWebScheduling:
+ case TaskType::kInternalFrameLifecycleControl:
case TaskType::kCount:
NOTREACHED();
break;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
index cb219585051..9322ff7e3dc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
@@ -28,7 +28,7 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
WorkerThreadSchedulerForTest(base::sequence_manager::SequenceManager* manager,
WorkerSchedulerProxy* proxy,
base::WaitableEvent* throtting_state_changed)
- : WorkerThreadScheduler(WebThreadType::kTestThread, manager, proxy),
+ : WorkerThreadScheduler(ThreadType::kTestThread, manager, proxy),
throtting_state_changed_(throtting_state_changed) {}
void OnLifecycleStateChanged(
@@ -48,7 +48,7 @@ class WorkerThreadForTest : public WorkerThread {
public:
WorkerThreadForTest(FrameScheduler* frame_scheduler,
base::WaitableEvent* throtting_state_changed)
- : WorkerThread(ThreadCreationParams(WebThreadType::kTestThread)
+ : WorkerThread(ThreadCreationParams(ThreadType::kTestThread)
.SetFrameOrWorkerScheduler(frame_scheduler)),
throtting_state_changed_(throtting_state_changed) {}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc
index f44dfcdd93f..e979188ee8f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc
@@ -62,7 +62,7 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
public:
// |manager| and |proxy| must remain valid for the entire lifetime of this
// object.
- WorkerThreadSchedulerForTest(WebThreadType thread_type,
+ WorkerThreadSchedulerForTest(ThreadType thread_type,
base::sequence_manager::SequenceManager* manager,
WorkerSchedulerProxy* proxy)
: WorkerThreadScheduler(thread_type, manager, proxy) {}
@@ -94,7 +94,7 @@ class WorkerSchedulerTest : public testing::Test {
nullptr,
mock_task_runner_,
mock_task_runner_->GetMockTickClock())),
- scheduler_(new WorkerThreadSchedulerForTest(WebThreadType::kTestThread,
+ scheduler_(new WorkerThreadSchedulerForTest(ThreadType::kTestThread,
sequence_manager_.get(),
nullptr /* proxy */)) {
mock_task_runner_->AdvanceMockTickClock(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread.h
index 108f1becf32..9625cd933a0 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_WORKER_THREAD_H_
#include "base/callback_forward.h"
-#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -141,7 +140,7 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
};
std::unique_ptr<SimpleThreadImpl> thread_;
- const WebThreadType thread_type_;
+ const ThreadType thread_type_;
std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_;
bool supports_gc_;
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
index 37a85c0d9e4..478c3cb030f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -89,7 +89,7 @@ base::Optional<base::TimeDelta> GetMaxThrottlingDelay() {
} // namespace
WorkerThreadScheduler::WorkerThreadScheduler(
- WebThreadType thread_type,
+ ThreadType thread_type,
base::sequence_manager::SequenceManager* sequence_manager,
WorkerSchedulerProxy* proxy)
: NonMainThreadSchedulerImpl(sequence_manager,
@@ -108,7 +108,7 @@ WorkerThreadScheduler::WorkerThreadScheduler(
ukm_source_id_(proxy ? proxy->ukm_source_id() : ukm::kInvalidSourceId) {
if (base::SequencedTaskRunnerHandle::IsSet()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> recorder;
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
recorder.InitWithNewPipeAndPassReceiver());
ukm_recorder_ = std::make_unique<ukm::MojoUkmRecorder>(std::move(recorder));
}
@@ -116,7 +116,7 @@ WorkerThreadScheduler::WorkerThreadScheduler(
if (proxy && proxy->parent_frame_type())
worker_metrics_helper_.SetParentFrameType(*proxy->parent_frame_type());
- if (thread_type == WebThreadType::kDedicatedWorkerThread &&
+ if (thread_type == ThreadType::kDedicatedWorkerThread &&
base::FeatureList::IsEnabled(kDedicatedWorkerThrottling)) {
CreateTaskQueueThrottler();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
index 0a7ae7a224c..fb26754d227 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
@@ -8,10 +8,10 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "components/scheduling_metrics/task_duration_metric_reporter.h"
-#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_status.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h"
@@ -41,7 +41,7 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadSchedulerImpl,
// |sequence_manager| and |proxy| must remain valid for the entire lifetime of
// this object.
WorkerThreadScheduler(
- WebThreadType thread_type,
+ ThreadType thread_type,
base::sequence_manager::SequenceManager* sequence_manager,
WorkerSchedulerProxy* proxy);
~WorkerThreadScheduler() override;
@@ -130,7 +130,7 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadSchedulerImpl,
const base::sequence_manager::Task& task,
const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
- const WebThreadType thread_type_;
+ const ThreadType thread_type_;
IdleHelper idle_helper_;
bool initialized_;
scoped_refptr<NonMainThreadTaskQueue> control_task_queue_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
index 8f00db8d856..d4142d207c2 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
@@ -78,7 +78,7 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
WorkerThreadSchedulerForTest(base::sequence_manager::SequenceManager* manager,
const base::TickClock* clock_,
Vector<String>* timeline)
- : WorkerThreadScheduler(WebThreadType::kTestThread, manager, nullptr),
+ : WorkerThreadScheduler(ThreadType::kTestThread, manager, nullptr),
clock_(clock_),
timeline_(timeline) {}
@@ -86,7 +86,7 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
const base::TickClock* clock_,
Vector<String>* timeline,
WorkerSchedulerProxy* proxy)
- : WorkerThreadScheduler(WebThreadType::kTestThread, manager, proxy),
+ : WorkerThreadScheduler(ThreadType::kTestThread, manager, proxy),
clock_(clock_),
timeline_(timeline) {}
@@ -464,6 +464,10 @@ class FrameSchedulerDelegateWithUkmSourceId : public FrameScheduler::Delegate {
void UpdateActiveSchedulerTrackedFeatures(uint64_t features_mask) override {}
+ const base::UnguessableToken& GetAgentClusterId() const override {
+ return base::UnguessableToken::Null();
+ }
+
private:
ukm::SourceId source_id_;
};
@@ -549,7 +553,7 @@ TEST_F(WorkerThreadSchedulerWithProxyTest, UkmTaskRecording) {
EXPECT_EQ(entries.size(), static_cast<size_t>(1));
ukm::TestUkmRecorder::ExpectEntryMetric(
- entries[0], "ThreadType", static_cast<int>(WebThreadType::kTestThread));
+ entries[0], "ThreadType", static_cast<int>(ThreadType::kTestThread));
ukm::TestUkmRecorder::ExpectEntryMetric(entries[0], "RendererBackgrounded",
true);
ukm::TestUkmRecorder::ExpectEntryMetric(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
index c394f642660..af4e41dd2a1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
@@ -41,7 +41,7 @@ class TestObserver : public Thread::TaskObserver {
~TestObserver() override = default;
- void WillProcessTask(const base::PendingTask&) override {
+ void WillProcessTask(const base::PendingTask&, bool) override {
calls_->Append(" willProcessTask");
}
@@ -77,7 +77,7 @@ class WorkerThreadTest : public testing::Test {
void SetUp() override {
thread_ =
- Thread::CreateThread(ThreadCreationParams(WebThreadType::kTestThread));
+ Thread::CreateThread(ThreadCreationParams(ThreadType::kTestThread));
}
void RunOnWorkerThread(const base::Location& from_here,
diff --git a/chromium/third_party/blink/renderer/platform/testing/DEPS b/chromium/third_party/blink/renderer/platform/testing/DEPS
index ad1509f9392..19b3458859d 100644
--- a/chromium/third_party/blink/renderer/platform/testing/DEPS
+++ b/chromium/third_party/blink/renderer/platform/testing/DEPS
@@ -32,6 +32,7 @@ include_rules = [
"+third_party/blink/renderer/platform/loader",
"+third_party/blink/renderer/platform/network",
"+third_party/blink/renderer/platform/platform_export.h",
+ "+third_party/blink/renderer/platform/peerconnection",
"+third_party/blink/renderer/platform/runtime_enabled_features.h",
"+third_party/blink/renderer/platform/scheduler",
"+third_party/blink/renderer/platform/scroll",
diff --git a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index cb234f8b88c..1322171e57a 100644
--- a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -28,6 +28,7 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
void Seek(double seconds) override {}
void SetRate(double) override {}
void SetVolume(double) override {}
+ void SetLatencyHint(double) override {}
void OnRequestPictureInPicture() override {}
SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
return SurfaceLayerMode::kNever;
diff --git a/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.cc b/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.cc
new file mode 100644
index 00000000000..a11b375339f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.cc
@@ -0,0 +1,70 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/testing/find_cc_layer.h"
+
+#include "cc/layers/layer.h"
+#include "cc/layers/scrollbar_layer_base.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/property_tree.h"
+#include "cc/trees/scroll_node.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace blink {
+
+Vector<const cc::Layer*> CcLayersByName(const cc::Layer* root,
+ const String& name_regex) {
+ Vector<const cc::Layer*> layers;
+ ::testing::Matcher<std::string> matcher(
+ ::testing::ContainsRegex(name_regex.Utf8()));
+ for (auto& layer : root->children()) {
+ if (matcher.Matches(layer->DebugName()))
+ layers.push_back(layer.get());
+ }
+ return layers;
+}
+
+Vector<const cc::Layer*> CcLayersByDOMElementId(const cc::Layer* root,
+ const String& dom_id) {
+ return CcLayersByName(root, String("id='") + dom_id + "'");
+}
+
+const cc::Layer* CcLayerByCcElementId(const cc::Layer* root,
+ const CompositorElementId& element_id) {
+ return root->layer_tree_host()->LayerByElementId(element_id);
+}
+
+const cc::Layer* ScrollingContentsCcLayerByScrollElementId(
+ const cc::Layer* root,
+ const CompositorElementId& scroll_element_id) {
+ const auto& scroll_tree =
+ root->layer_tree_host()->property_trees()->scroll_tree;
+ for (auto& layer : root->children()) {
+ const auto* scroll_node = scroll_tree.Node(layer->scroll_tree_index());
+ if (scroll_node && scroll_node->element_id == scroll_element_id &&
+ scroll_node->transform_id == layer->transform_tree_index())
+ return layer.get();
+ }
+ return nullptr;
+}
+
+const cc::ScrollbarLayerBase* ScrollbarLayerForScrollNode(
+ const cc::Layer* root,
+ const cc::ScrollNode* scroll_node,
+ cc::ScrollbarOrientation orientation) {
+ if (!scroll_node)
+ return nullptr;
+ for (auto& layer : root->children()) {
+ if (!layer->is_scrollbar())
+ continue;
+ const auto* scrollbar_layer =
+ static_cast<const cc::ScrollbarLayerBase*>(layer.get());
+ if (scrollbar_layer->scroll_element_id() == scroll_node->element_id &&
+ scrollbar_layer->orientation() == orientation)
+ return scrollbar_layer;
+ }
+ return nullptr;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.h b/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.h
new file mode 100644
index 00000000000..da91ced1ef9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/find_cc_layer.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FIND_CC_LAYER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FIND_CC_LAYER_H_
+
+#include <string>
+#include "cc/input/scrollbar.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace cc {
+class Layer;
+class ScrollbarLayerBase;
+struct ScrollNode;
+} // namespace cc
+
+namespace blink {
+
+// Finds all cc layers whose DebugName()s contain regular expression
+// |name_regex|.
+Vector<const cc::Layer*> CcLayersByName(const cc::Layer* root,
+ const String& name_regex);
+
+Vector<const cc::Layer*> CcLayersByDOMElementId(const cc::Layer* root,
+ const String& dom_id);
+
+const cc::Layer* CcLayerByCcElementId(const cc::Layer* root,
+ const CompositorElementId&);
+
+const cc::Layer* ScrollingContentsCcLayerByScrollElementId(
+ const cc::Layer* root,
+ const CompositorElementId& scroll_element_id);
+
+const cc::ScrollbarLayerBase* ScrollbarLayerForScrollNode(
+ const cc::Layer* root,
+ const cc::ScrollNode* scroll_node,
+ cc::ScrollbarOrientation orientation);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FIND_CC_LAYER_H_
diff --git a/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc b/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
index 1e40f8af786..08dc5f8c1b5 100644
--- a/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
@@ -57,6 +57,10 @@ class TestFontSelector : public FontSelector {
unsigned Version() const override { return 0; }
void FontCacheInvalidated() override {}
void ReportNotDefGlyph() const override {}
+ void ReportSuccessfulFontFamilyMatch(
+ const AtomicString& font_family_name) override {}
+ void ReportFailedFontFamilyMatch(
+ const AtomicString& font_family_name) override {}
ExecutionContext* GetExecutionContext() const override { return nullptr; }
FontFaceCache* GetFontFaceCache() override { return nullptr; }
diff --git a/chromium/third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.cc b/chromium/third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.cc
index 5ab33eca566..97b559da18a 100644
--- a/chromium/third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.cc
@@ -9,8 +9,9 @@
namespace blink {
IOTaskRunnerTestingPlatformSupport::IOTaskRunnerTestingPlatformSupport()
- : io_thread_(Thread::CreateThread(
- ThreadCreationParams(WebThreadType::kTestThread))) {}
+ : io_thread_(
+ Thread::CreateThread(ThreadCreationParams(ThreadType::kTestThread))) {
+}
scoped_refptr<base::SingleThreadTaskRunner>
IOTaskRunnerTestingPlatformSupport::GetIOTaskRunner() const {
diff --git a/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h b/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
index 2c582402b29..9738516ca21 100644
--- a/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
@@ -217,6 +217,15 @@ inline scoped_refptr<TransformPaintPropertyNode> CreateScrollTranslation(
return TransformPaintPropertyNode::Create(parent, std::move(state));
}
+inline scoped_refptr<TransformPaintPropertyNode>
+CreateCompositedScrollTranslation(const TransformPaintPropertyNode& parent,
+ float offset_x,
+ float offset_y,
+ const ScrollPaintPropertyNode& scroll) {
+ return CreateScrollTranslation(parent, offset_x, offset_y, scroll,
+ CompositingReason::kOverflowScrolling);
+}
+
inline PropertyTreeState DefaultPaintChunkProperties() {
return PropertyTreeState::Root();
}
diff --git a/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
index d125cb3038b..00b0da0c002 100644
--- a/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
+++ b/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -15,6 +15,7 @@ enum {
kCompositeAfterPaint = 1 << 0,
kUnderInvalidationChecking = 1 << 1,
kFastBorderRadius = 1 << 2,
+ kDoNotCompositeTrivial3D = 1 << 3,
};
class PaintTestConfigurations
@@ -51,6 +52,12 @@ class PaintTestConfigurations
INSTANTIATE_TEST_SUITE_P(All, test_class, \
::testing::Values(0, kCompositeAfterPaint))
+#define INSTANTIATE_DO_NOT_COMPOSITE_TRIVIAL_3D_P(test_class) \
+ INSTANTIATE_TEST_SUITE_P( \
+ All, test_class, \
+ ::testing::Values(0, kCompositeAfterPaint, kDoNotCompositeTrivial3D, \
+ kCompositeAfterPaint | kDoNotCompositeTrivial3D))
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_
diff --git a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
index a52c83f2509..1f0238b9157 100644
--- a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
@@ -96,8 +96,10 @@ TestPaintArtifact& TestPaintArtifact::RectDrawing(FakeDisplayItemClient& client,
TestPaintArtifact& TestPaintArtifact::ForeignLayer(
scoped_refptr<cc::Layer> layer,
const FloatPoint& offset) {
+ DEFINE_STATIC_LOCAL(LiteralDebugNameClient, client, ("ForeignLayer"));
display_item_list_.AllocateAndConstruct<ForeignLayerDisplayItem>(
- DisplayItem::kForeignLayerFirst, std::move(layer), offset);
+ client, DisplayItem::kForeignLayerFirst, std::move(layer), offset,
+ nullptr);
return *this;
}
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
deleted file mode 100644
index 598aa03d7fe..00000000000
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
+++ /dev/null
@@ -1,412 +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 "third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h"
-
-#include <utility>
-
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h"
-#include "third_party/blink/public/platform/web_rtc_rtp_source.h"
-#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
-#include "third_party/blink/public/platform/web_rtc_session_description.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/webrtc/api/stats/rtc_stats.h"
-
-namespace blink {
-
-namespace {
-
-// Having a refcounted helper class allows multiple DummyWebRTCRtpSender to
-// share the same internal states.
-class DummyRtpSenderInternal
- : public base::RefCountedThreadSafe<DummyRtpSenderInternal> {
- private:
- static uintptr_t last_id_;
-
- public:
- explicit DummyRtpSenderInternal(WebMediaStreamTrack track)
- : id_(++last_id_), track_(std::move(track)) {}
-
- uintptr_t id() const { return id_; }
- WebMediaStreamTrack track() const { return track_; }
- void set_track(WebMediaStreamTrack track) { track_ = std::move(track); }
-
- private:
- const uintptr_t id_;
- WebMediaStreamTrack track_;
-};
-
-uintptr_t DummyRtpSenderInternal::last_id_ = 0;
-
-class DummyWebRTCRtpSender : public WebRTCRtpSender {
- public:
- explicit DummyWebRTCRtpSender(WebMediaStreamTrack track)
- : internal_(new DummyRtpSenderInternal(std::move(track))) {}
- DummyWebRTCRtpSender(const DummyWebRTCRtpSender& other)
- : internal_(other.internal_) {}
- ~DummyWebRTCRtpSender() override {}
-
- scoped_refptr<DummyRtpSenderInternal> internal() const { return internal_; }
-
- std::unique_ptr<WebRTCRtpSender> ShallowCopy() const override {
- return nullptr;
- }
- uintptr_t Id() const override { return internal_->id(); }
- rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override {
- return nullptr;
- }
- webrtc::DtlsTransportInformation DtlsTransportInformation() override {
- static const webrtc::DtlsTransportInformation dummy(
- webrtc::DtlsTransportState::kNew);
- return dummy;
- }
- WebMediaStreamTrack Track() const override { return internal_->track(); }
- WebVector<WebString> StreamIds() const override {
- return std::vector<WebString>({WebString::FromUTF8("DummyStringId")});
- }
- void ReplaceTrack(WebMediaStreamTrack, WebRTCVoidRequest) override {}
- std::unique_ptr<WebRTCDTMFSenderHandler> GetDtmfSender() const override {
- return nullptr;
- }
- std::unique_ptr<webrtc::RtpParameters> GetParameters() const override {
- return std::unique_ptr<webrtc::RtpParameters>();
- }
- void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
- WebRTCVoidRequest) override {}
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override {}
- void SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) override {}
-
- private:
- scoped_refptr<DummyRtpSenderInternal> internal_;
-};
-
-class DummyWebRTCRtpReceiver : public WebRTCRtpReceiver {
- private:
- static uintptr_t last_id_;
-
- public:
- explicit DummyWebRTCRtpReceiver(WebMediaStreamSource::Type type)
- : id_(++last_id_), track_() {
- if (type == WebMediaStreamSource::Type::kTypeAudio) {
- WebMediaStreamSource web_source;
- web_source.Initialize(WebString::FromUTF8("remoteAudioId"),
- WebMediaStreamSource::Type::kTypeAudio,
- WebString::FromUTF8("remoteAudioName"),
- true /* remote */);
- track_.Initialize(web_source.Id(), web_source);
- } else {
- DCHECK_EQ(type, WebMediaStreamSource::Type::kTypeVideo);
- WebMediaStreamSource web_source;
- web_source.Initialize(WebString::FromUTF8("remoteVideoId"),
- WebMediaStreamSource::Type::kTypeVideo,
- WebString::FromUTF8("remoteVideoName"),
- true /* remote */);
- track_.Initialize(web_source.Id(), web_source);
- }
- }
- DummyWebRTCRtpReceiver(const DummyWebRTCRtpReceiver& other)
- : id_(other.id_), track_(other.track_) {}
- ~DummyWebRTCRtpReceiver() override {}
-
- std::unique_ptr<WebRTCRtpReceiver> ShallowCopy() const override {
- return nullptr;
- }
- uintptr_t Id() const override { return id_; }
- rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override {
- return nullptr;
- }
- webrtc::DtlsTransportInformation DtlsTransportInformation() override {
- static const webrtc::DtlsTransportInformation dummy(
- webrtc::DtlsTransportState::kNew);
- return dummy;
- }
- const WebMediaStreamTrack& Track() const override { return track_; }
- WebVector<WebString> StreamIds() const override {
- return WebVector<WebString>();
- }
- WebVector<std::unique_ptr<WebRTCRtpSource>> GetSources() override {
- return WebVector<std::unique_ptr<WebRTCRtpSource>>();
- }
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override {}
- std::unique_ptr<webrtc::RtpParameters> GetParameters() const override {
- return nullptr;
- }
-
- void SetJitterBufferMinimumDelay(
- base::Optional<double> delay_seconds) override {}
-
- private:
- const uintptr_t id_;
- WebMediaStreamTrack track_;
-};
-
-uintptr_t DummyWebRTCRtpReceiver::last_id_ = 0;
-
-// Having a refcounted helper class allows multiple DummyWebRTCRtpTransceivers
-// to share the same internal states.
-class DummyTransceiverInternal
- : public base::RefCountedThreadSafe<DummyTransceiverInternal> {
- private:
- static uintptr_t last_id_;
-
- public:
- DummyTransceiverInternal(WebMediaStreamSource::Type type,
- WebMediaStreamTrack sender_track)
- : id_(++last_id_),
- sender_(std::move(sender_track)),
- receiver_(type),
- direction_(webrtc::RtpTransceiverDirection::kSendRecv) {
- DCHECK(sender_.Track().IsNull() ||
- sender_.Track().Source().GetType() == type);
- }
-
- uintptr_t id() const { return id_; }
- DummyWebRTCRtpSender* sender() { return &sender_; }
- std::unique_ptr<DummyWebRTCRtpSender> Sender() const {
- return std::make_unique<DummyWebRTCRtpSender>(sender_);
- }
- DummyWebRTCRtpReceiver* receiver() { return &receiver_; }
- std::unique_ptr<DummyWebRTCRtpReceiver> Receiver() const {
- return std::make_unique<DummyWebRTCRtpReceiver>(receiver_);
- }
- webrtc::RtpTransceiverDirection direction() const { return direction_; }
- void set_direction(webrtc::RtpTransceiverDirection direction) {
- direction_ = direction;
- }
-
- private:
- const uintptr_t id_;
- DummyWebRTCRtpSender sender_;
- DummyWebRTCRtpReceiver receiver_;
- webrtc::RtpTransceiverDirection direction_;
-};
-
-uintptr_t DummyTransceiverInternal::last_id_ = 0;
-
-} // namespace
-
-class MockWebRTCPeerConnectionHandler::DummyWebRTCRtpTransceiver
- : public WebRTCRtpTransceiver {
- public:
- DummyWebRTCRtpTransceiver(WebMediaStreamSource::Type type,
- WebMediaStreamTrack track)
- : internal_(new DummyTransceiverInternal(type, track)) {}
- DummyWebRTCRtpTransceiver(const DummyWebRTCRtpTransceiver& other)
- : internal_(other.internal_) {}
- ~DummyWebRTCRtpTransceiver() override {}
-
- scoped_refptr<DummyTransceiverInternal> internal() const { return internal_; }
-
- WebRTCRtpTransceiverImplementationType ImplementationType() const override {
- return WebRTCRtpTransceiverImplementationType::kFullTransceiver;
- }
- uintptr_t Id() const override { return internal_->id(); }
- WebString Mid() const override { return WebString(); }
- std::unique_ptr<WebRTCRtpSender> Sender() const override {
- return internal_->Sender();
- }
- std::unique_ptr<WebRTCRtpReceiver> Receiver() const override {
- return internal_->Receiver();
- }
- bool Stopped() const override { return true; }
- webrtc::RtpTransceiverDirection Direction() const override {
- return internal_->direction();
- }
- void SetDirection(webrtc::RtpTransceiverDirection direction) override {
- internal_->set_direction(direction);
- }
- base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
- const override {
- return base::nullopt;
- }
- base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
- const override {
- return base::nullopt;
- }
-
- private:
- scoped_refptr<DummyTransceiverInternal> internal_;
-};
-
-MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() = default;
-
-MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() = default;
-
-bool MockWebRTCPeerConnectionHandler::Initialize(
- const webrtc::PeerConnectionInterface::RTCConfiguration&,
- const WebMediaConstraints&) {
- return true;
-}
-
-WebVector<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::CreateOffer(
- const WebRTCSessionDescriptionRequest&,
- const WebMediaConstraints&) {
- return {};
-}
-
-WebVector<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::CreateOffer(
- const WebRTCSessionDescriptionRequest&,
- const WebRTCOfferOptions&) {
- return {};
-}
-
-void MockWebRTCPeerConnectionHandler::CreateAnswer(
- const WebRTCSessionDescriptionRequest&,
- const WebMediaConstraints&) {}
-
-void MockWebRTCPeerConnectionHandler::CreateAnswer(
- const WebRTCSessionDescriptionRequest&,
- const WebRTCAnswerOptions&) {}
-
-void MockWebRTCPeerConnectionHandler::SetLocalDescription(
- const WebRTCVoidRequest&,
- const WebRTCSessionDescription&) {}
-
-void MockWebRTCPeerConnectionHandler::SetRemoteDescription(
- const WebRTCVoidRequest&,
- const WebRTCSessionDescription&) {}
-
-WebRTCSessionDescription MockWebRTCPeerConnectionHandler::LocalDescription() {
- return WebRTCSessionDescription();
-}
-
-WebRTCSessionDescription MockWebRTCPeerConnectionHandler::RemoteDescription() {
- return WebRTCSessionDescription();
-}
-
-WebRTCSessionDescription
-MockWebRTCPeerConnectionHandler::CurrentLocalDescription() {
- return WebRTCSessionDescription();
-}
-
-WebRTCSessionDescription
-MockWebRTCPeerConnectionHandler::CurrentRemoteDescription() {
- return WebRTCSessionDescription();
-}
-
-WebRTCSessionDescription
-MockWebRTCPeerConnectionHandler::PendingLocalDescription() {
- return WebRTCSessionDescription();
-}
-
-WebRTCSessionDescription
-MockWebRTCPeerConnectionHandler::PendingRemoteDescription() {
- return WebRTCSessionDescription();
-}
-
-const webrtc::PeerConnectionInterface::RTCConfiguration&
-MockWebRTCPeerConnectionHandler::GetConfiguration() const {
- static const webrtc::PeerConnectionInterface::RTCConfiguration configuration;
- return configuration;
-}
-
-webrtc::RTCErrorType MockWebRTCPeerConnectionHandler::SetConfiguration(
- const webrtc::PeerConnectionInterface::RTCConfiguration&) {
- return webrtc::RTCErrorType::NONE;
-}
-
-void MockWebRTCPeerConnectionHandler::RestartIce() {}
-
-void MockWebRTCPeerConnectionHandler::GetStats(const WebRTCStatsRequest&) {}
-
-void MockWebRTCPeerConnectionHandler::GetStats(
- blink::WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) {}
-
-webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::AddTransceiverWithTrack(
- const WebMediaStreamTrack& track,
- const webrtc::RtpTransceiverInit&) {
- transceivers_.push_back(std::unique_ptr<DummyWebRTCRtpTransceiver>(
- new DummyWebRTCRtpTransceiver(track.Source().GetType(), track)));
- std::unique_ptr<DummyWebRTCRtpTransceiver> copy(
- new DummyWebRTCRtpTransceiver(*transceivers_.back()));
- return std::unique_ptr<WebRTCRtpTransceiver>(std::move(copy));
-}
-
-webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::AddTransceiverWithKind(
- std::string kind,
- const webrtc::RtpTransceiverInit&) {
- transceivers_.push_back(
- std::unique_ptr<DummyWebRTCRtpTransceiver>(new DummyWebRTCRtpTransceiver(
- kind == "audio" ? WebMediaStreamSource::Type::kTypeAudio
- : WebMediaStreamSource::Type::kTypeVideo,
- WebMediaStreamTrack())));
- std::unique_ptr<DummyWebRTCRtpTransceiver> copy(
- new DummyWebRTCRtpTransceiver(*transceivers_.back()));
- return std::unique_ptr<WebRTCRtpTransceiver>(std::move(copy));
-}
-
-webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track,
- const WebVector<WebMediaStream>&) {
- transceivers_.push_back(std::unique_ptr<DummyWebRTCRtpTransceiver>(
- new DummyWebRTCRtpTransceiver(track.Source().GetType(), track)));
- std::unique_ptr<DummyWebRTCRtpTransceiver> copy(
- new DummyWebRTCRtpTransceiver(*transceivers_.back()));
- return std::unique_ptr<WebRTCRtpTransceiver>(std::move(copy));
-}
-
-webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
-MockWebRTCPeerConnectionHandler::RemoveTrack(WebRTCRtpSender* sender) {
- const DummyWebRTCRtpTransceiver* transceiver_of_sender = nullptr;
- for (const auto& transceiver : transceivers_) {
- if (transceiver->Sender()->Id() == sender->Id()) {
- transceiver_of_sender = transceiver.get();
- break;
- }
- }
- transceiver_of_sender->internal()->sender()->internal()->set_track(
- WebMediaStreamTrack());
- std::unique_ptr<DummyWebRTCRtpTransceiver> copy(
- new DummyWebRTCRtpTransceiver(*transceiver_of_sender));
- return std::unique_ptr<WebRTCRtpTransceiver>(std::move(copy));
-}
-
-scoped_refptr<webrtc::DataChannelInterface>
-MockWebRTCPeerConnectionHandler::CreateDataChannel(
- const WebString& label,
- const WebRTCDataChannelInit&) {
- return nullptr;
-}
-
-void MockWebRTCPeerConnectionHandler::Stop() {}
-
-webrtc::PeerConnectionInterface*
-MockWebRTCPeerConnectionHandler::NativePeerConnection() {
- return nullptr;
-}
-
-void MockWebRTCPeerConnectionHandler::
- RunSynchronousOnceClosureOnSignalingThread(base::OnceClosure closure,
- const char* trace_event_name) {}
-
-void MockWebRTCPeerConnectionHandler::
- RunSynchronousRepeatingClosureOnSignalingThread(
- const base::RepeatingClosure& closure,
- const char* trace_event_name) {}
-
-void MockWebRTCPeerConnectionHandler::TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
- webrtc::PeerConnectionInterface::IceConnectionState state) {}
-
-std::unique_ptr<WebRTCPeerConnectionHandler>
-TestingPlatformSupportWithWebRTC::CreateRTCPeerConnectionHandler(
- WebRTCPeerConnectionHandlerClient*,
- scoped_refptr<base::SingleThreadTaskRunner>) {
- return std::make_unique<MockWebRTCPeerConnectionHandler>();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
deleted file mode 100644
index 39d569dcc03..00000000000
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
+++ /dev/null
@@ -1,99 +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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_TESTING_PLATFORM_SUPPORT_WITH_WEB_RTC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_TESTING_PLATFORM_SUPPORT_WITH_WEB_RTC_H_
-
-#include <memory>
-#include <string>
-
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
-#include "third_party/webrtc/api/peer_connection_interface.h"
-#include "third_party/webrtc/api/stats/rtc_stats.h"
-
-namespace blink {
-
-// TODO(https://crbug.com/908461): This is currently implemented as NO-OPs or to
-// create dummy objects whose methods return default values. Consider renaming
-// the class, changing it to be GMOCK friendly or deleting it.
-class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
- public:
- MockWebRTCPeerConnectionHandler();
- ~MockWebRTCPeerConnectionHandler() override;
-
- bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&,
- const WebMediaConstraints&) override;
-
- WebVector<std::unique_ptr<WebRTCRtpTransceiver>> CreateOffer(
- const WebRTCSessionDescriptionRequest&,
- const WebMediaConstraints&) override;
- WebVector<std::unique_ptr<WebRTCRtpTransceiver>> CreateOffer(
- const WebRTCSessionDescriptionRequest&,
- const WebRTCOfferOptions&) override;
- void CreateAnswer(const WebRTCSessionDescriptionRequest&,
- const WebMediaConstraints&) override;
- void CreateAnswer(const WebRTCSessionDescriptionRequest&,
- const WebRTCAnswerOptions&) override;
- void SetLocalDescription(const WebRTCVoidRequest&,
- const WebRTCSessionDescription&) override;
- void SetRemoteDescription(const WebRTCVoidRequest&,
- const WebRTCSessionDescription&) override;
- WebRTCSessionDescription LocalDescription() override;
- WebRTCSessionDescription RemoteDescription() override;
- WebRTCSessionDescription CurrentLocalDescription() override;
- WebRTCSessionDescription CurrentRemoteDescription() override;
- WebRTCSessionDescription PendingLocalDescription() override;
- WebRTCSessionDescription PendingRemoteDescription() override;
- const webrtc::PeerConnectionInterface::RTCConfiguration& GetConfiguration()
- const override;
- webrtc::RTCErrorType SetConfiguration(
- const webrtc::PeerConnectionInterface::RTCConfiguration&) override;
- void RestartIce() override;
- void GetStats(const WebRTCStatsRequest&) override;
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override;
- webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
- AddTransceiverWithTrack(const WebMediaStreamTrack&,
- const webrtc::RtpTransceiverInit&) override;
- webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
- AddTransceiverWithKind(std::string kind,
- const webrtc::RtpTransceiverInit&) override;
- webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>> AddTrack(
- const WebMediaStreamTrack&,
- const WebVector<WebMediaStream>&) override;
- webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>> RemoveTrack(
- WebRTCRtpSender*) override;
- scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
- const WebString& label,
- const WebRTCDataChannelInit&) override;
- void Stop() override;
- webrtc::PeerConnectionInterface* NativePeerConnection() override;
- void RunSynchronousOnceClosureOnSignalingThread(
- base::OnceClosure closure,
- const char* trace_event_name) override;
- void RunSynchronousRepeatingClosureOnSignalingThread(
- const base::RepeatingClosure& closure,
- const char* trace_event_name) override;
- void TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
- webrtc::PeerConnectionInterface::IceConnectionState state) override;
-
- private:
- class DummyWebRTCRtpTransceiver;
-
- Vector<std::unique_ptr<DummyWebRTCRtpTransceiver>> transceivers_;
-};
-
-class TestingPlatformSupportWithWebRTC : public TestingPlatformSupport {
- public:
- std::unique_ptr<WebRTCPeerConnectionHandler> CreateRTCPeerConnectionHandler(
- WebRTCPeerConnectionHandlerClient*,
- scoped_refptr<base::SingleThreadTaskRunner>) override;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_TESTING_PLATFORM_SUPPORT_WITH_WEB_RTC_H_
diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
index b389c9cde40..a58efcf47f6 100644
--- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
@@ -108,7 +108,7 @@ void WebURLLoaderMock::LoadSynchronously(
void WebURLLoaderMock::LoadAsynchronously(const WebURLRequest& request,
WebURLLoaderClient* client) {
DCHECK(client);
- DCHECK(factory_->IsMockedURL(request.Url()));
+ DCHECK(factory_->IsMockedURL(request.Url())) << request.Url();
client_ = client;
factory_->LoadAsynchronouly(request, this);
}
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer.cc b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer.cc
new file mode 100644
index 00000000000..3064f62af38
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer.cc
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/text/date_time_format.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class DummyTokenHandler : public DateTimeFormat::TokenHandler {
+ public:
+ ~DummyTokenHandler() override = default;
+
+ void VisitField(DateTimeFormat::FieldType field_type, int count) override {
+ CHECK(field_type != DateTimeFormat::FieldType::kFieldTypeInvalid);
+ CHECK_GE(count, 1);
+ }
+
+ void VisitLiteral(const WTF::String& string) override {
+ CHECK_GT(string.length(), 0u);
+ }
+};
+
+} // namespace blink
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static blink::BlinkFuzzerTestSupport test_support =
+ blink::BlinkFuzzerTestSupport();
+ blink::DummyTokenHandler handler;
+ blink::DateTimeFormat::Parse(
+ WTF::String::FromUTF8(reinterpret_cast<const char*>(data), size),
+ handler);
+ return 0;
+}
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/a b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/a
new file mode 100644
index 00000000000..09f23df08e6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/a
@@ -0,0 +1 @@
+yyyy.MM.dd G 'at' HH:mm:ss zzz
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/b b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/b
new file mode 100644
index 00000000000..a1deed76df7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/b
@@ -0,0 +1 @@
+EEE, MMM d, ''yy
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/c b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/c
new file mode 100644
index 00000000000..a8eeb2a6f2b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/c
@@ -0,0 +1 @@
+h:mm a
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/d b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/d
new file mode 100644
index 00000000000..53bbe75bedc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/d
@@ -0,0 +1 @@
+hh 'o''clock' a, zzzz
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/e b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/e
new file mode 100644
index 00000000000..18404239963
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/e
@@ -0,0 +1 @@
+K:mm a, z
diff --git a/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/f b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/f
new file mode 100644
index 00000000000..b26f515c643
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/date_time_format_fuzzer_seed_corpus/f
@@ -0,0 +1 @@
+yyyyy.MMMM.dd GGG hh:mm aaa
diff --git a/chromium/third_party/blink/renderer/platform/timer.cc b/chromium/third_party/blink/renderer/platform/timer.cc
index 1025e12178c..a4ece579d68 100644
--- a/chromium/third_party/blink/renderer/platform/timer.cc
+++ b/chromium/third_party/blink/renderer/platform/timer.cc
@@ -103,10 +103,6 @@ void TimerBase::MoveToNewTaskRunner(
SetNextFireTime(now, next_fire_time - now);
}
-scoped_refptr<base::SingleThreadTaskRunner> TimerBase::TimerTaskRunner() const {
- return web_task_runner_;
-}
-
void TimerBase::SetNextFireTime(base::TimeTicks now, base::TimeDelta delay) {
#if DCHECK_IS_ON()
DCHECK_EQ(thread_, CurrentThread());
@@ -120,7 +116,7 @@ void TimerBase::SetNextFireTime(base::TimeTicks now, base::TimeDelta delay) {
// Cancel any previously posted task.
weak_ptr_factory_.InvalidateWeakPtrs();
- TimerTaskRunner()->PostDelayedTask(
+ web_task_runner_->PostDelayedTask(
location_,
WTF::Bind(&TimerBase::RunInternal, weak_ptr_factory_.GetWeakPtr()),
delay);
diff --git a/chromium/third_party/blink/renderer/platform/timer.h b/chromium/third_party/blink/renderer/platform/timer.h
index 2e8af8a0640..fd81a09959c 100644
--- a/chromium/third_party/blink/renderer/platform/timer.h
+++ b/chromium/third_party/blink/renderer/platform/timer.h
@@ -85,8 +85,6 @@ class PLATFORM_EXPORT TimerBase {
private:
virtual void Fired() = 0;
- virtual scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() const;
-
NO_SANITIZE_ADDRESS
virtual bool CanFire() const { return true; }
diff --git a/chromium/third_party/blink/renderer/platform/timer_test.cc b/chromium/third_party/blink/renderer/platform/timer_test.cc
index 32c6792ec09..0511f0f9bda 100644
--- a/chromium/third_party/blink/renderer/platform/timer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/timer_test.cc
@@ -678,7 +678,7 @@ class TaskObserver : public base::TaskObserver {
Vector<scoped_refptr<base::SingleThreadTaskRunner>>* run_order)
: task_runner_(std::move(task_runner)), run_order_(run_order) {}
- void WillProcessTask(const base::PendingTask&) override {}
+ void WillProcessTask(const base::PendingTask&, bool) override {}
void DidProcessTask(const base::PendingTask&) override {
run_order_->push_back(task_runner_);
diff --git a/chromium/third_party/blink/renderer/platform/transforms/identity_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/identity_transform_operation.h
index b3d2cab9eaf..f21acfb6e81 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/identity_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/identity_transform_operation.h
@@ -49,6 +49,12 @@ class PLATFORM_EXPORT IdentityTransformOperation final
void Apply(TransformationMatrix&, const FloatSize&) const override {}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override {
+ NOTREACHED();
+ return this;
+ }
+
scoped_refptr<TransformOperation> Blend(
const TransformOperation*,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc
index 2c15f0a45ff..a4c1c616001 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc
@@ -61,18 +61,24 @@ scoped_refptr<TransformOperation> InterpolatedTransformOperation::Blend(
bool blend_to_identity) {
if (from && !from->IsSameType(*this))
return this;
-
- TransformOperations this_operations;
- this_operations.Operations().push_back(this);
+ TransformOperations to_operations;
+ to_operations.Operations().push_back(this);
TransformOperations from_operations;
- if (blend_to_identity)
+ if (blend_to_identity) {
+ from_operations.Operations().push_back(
+ IdentityTransformOperation::Create());
+ return InterpolatedTransformOperation::Create(
+ to_operations, from_operations, 0, 1 - progress);
+ }
+ if (!from) {
from_operations.Operations().push_back(
IdentityTransformOperation::Create());
- else
+ } else {
from_operations.Operations().push_back(
const_cast<TransformOperation*>(from));
- return InterpolatedTransformOperation::Create(this_operations,
- from_operations, 0, progress);
+ }
+ return InterpolatedTransformOperation::Create(from_operations, to_operations,
+ 0, progress);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h
index 5b82a7d3683..341b2748097 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h
@@ -60,6 +60,12 @@ class PLATFORM_EXPORT InterpolatedTransformOperation final
void Apply(TransformationMatrix&,
const FloatSize& border_box_size) const override;
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation&) override {
+ NOTREACHED();
+ return this;
+ }
+
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
index 50bb4cf2066..1ee49fe627f 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
@@ -1,5 +1,3 @@
-
-
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
@@ -27,10 +25,70 @@
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
+#include "third_party/blink/renderer/platform/transforms/rotation.h"
+#include "ui/gfx/geometry/quaternion.h"
+
#include <algorithm>
namespace blink {
+scoped_refptr<TransformOperation> Matrix3DTransformOperation::Accumulate(
+ const TransformOperation& other_op) {
+ DCHECK(other_op.IsSameType(*this));
+ const auto& other = ToMatrix3DTransformOperation(other_op);
+
+ // If either matrix is non-invertible, fail and fallback to replace.
+ if (!matrix_.IsInvertible() || !other.matrix_.IsInvertible())
+ return nullptr;
+
+ // Similar to interpolation, accumulating 3D matrices is done by decomposing
+ // them, accumulating the individual functions, and then recomposing.
+
+ TransformationMatrix::DecomposedType from_decomp;
+ TransformationMatrix::DecomposedType to_decomp;
+ if (!matrix_.Decompose(from_decomp) || !other.matrix_.Decompose(to_decomp))
+ return nullptr;
+
+ // Scale is accumulated using 1-based addition.
+ from_decomp.scale_x += to_decomp.scale_x - 1;
+ from_decomp.scale_y += to_decomp.scale_y - 1;
+ from_decomp.scale_z += to_decomp.scale_z - 1;
+
+ // Skew can be added.
+ from_decomp.skew_xy += to_decomp.skew_xy;
+ from_decomp.skew_xz += to_decomp.skew_xz;
+ from_decomp.skew_yz += to_decomp.skew_yz;
+
+ // To accumulate quaternions, we multiply them. This is equivalent to 'adding'
+ // the rotations that they represent.
+ gfx::Quaternion from_quaternion(
+ from_decomp.quaternion_x, from_decomp.quaternion_y,
+ from_decomp.quaternion_z, from_decomp.quaternion_w);
+ gfx::Quaternion to_quaternion(to_decomp.quaternion_x, to_decomp.quaternion_y,
+ to_decomp.quaternion_z, to_decomp.quaternion_w);
+
+ gfx::Quaternion result_quaternion = from_quaternion * to_quaternion;
+ from_decomp.quaternion_x = result_quaternion.x();
+ from_decomp.quaternion_y = result_quaternion.y();
+ from_decomp.quaternion_z = result_quaternion.z();
+ from_decomp.quaternion_w = result_quaternion.w();
+
+ // Translate is a simple addition.
+ from_decomp.translate_x += to_decomp.translate_x;
+ from_decomp.translate_y += to_decomp.translate_y;
+ from_decomp.translate_z += to_decomp.translate_z;
+
+ // We sum the perspective components; note that w is 1-based.
+ from_decomp.perspective_x += to_decomp.perspective_x;
+ from_decomp.perspective_y += to_decomp.perspective_y;
+ from_decomp.perspective_z += to_decomp.perspective_z;
+ from_decomp.perspective_w += to_decomp.perspective_w - 1;
+
+ TransformationMatrix result;
+ result.Recompose(from_decomp);
+ return Matrix3DTransformOperation::Create(result);
+}
+
scoped_refptr<TransformOperation> Matrix3DTransformOperation::Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
index c5fd80342ce..9c61b1265e2 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
@@ -63,6 +63,9 @@ class PLATFORM_EXPORT Matrix3DTransformOperation final
transform.Multiply(TransformationMatrix(matrix_));
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
+
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
index 8cf0648c896..7ac6a31d386 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
@@ -25,6 +25,41 @@
namespace blink {
+scoped_refptr<TransformOperation> MatrixTransformOperation::Accumulate(
+ const TransformOperation& other_op) {
+ DCHECK(other_op.IsSameType(*this));
+ const MatrixTransformOperation& other = ToMatrixTransformOperation(other_op);
+
+ TransformationMatrix from_t(other.a_, other.b_, other.c_, other.d_, other.e_,
+ other.f_);
+ TransformationMatrix to_t(a_, b_, c_, d_, e_, f_);
+
+ // If either matrix is non-invertible, fail and fallback to replace.
+ if (!from_t.IsInvertible() || !to_t.IsInvertible())
+ return nullptr;
+
+ // Similar to interpolation, accumulating matrices is done by decomposing
+ // them, accumulating the individual functions, and then recomposing.
+
+ TransformationMatrix::Decomposed2dType from_decomp;
+ TransformationMatrix::Decomposed2dType to_decomp;
+ if (!from_t.Decompose2D(from_decomp) || !to_t.Decompose2D(to_decomp)) {
+ return nullptr;
+ }
+
+ // For a 2D matrix, the components can just be naively summed, noting that
+ // scale uses 1-based addition.
+ from_decomp.scale_x += to_decomp.scale_x - 1;
+ from_decomp.scale_y += to_decomp.scale_y - 1;
+ from_decomp.skew_xy += to_decomp.skew_xy;
+ from_decomp.translate_x += to_decomp.translate_x;
+ from_decomp.translate_y += to_decomp.translate_y;
+ from_decomp.angle += to_decomp.angle;
+
+ from_t.Recompose2D(from_decomp);
+ return MatrixTransformOperation::Create(from_t);
+}
+
scoped_refptr<TransformOperation> MatrixTransformOperation::Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
index 2c3c43a3166..bb943c2a603 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
@@ -77,6 +77,9 @@ class PLATFORM_EXPORT MatrixTransformOperation final
transform.Multiply(matrix);
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation&) override;
+
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
index a5753ed38cc..7a491ab9d84 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
@@ -30,6 +30,23 @@
namespace blink {
+scoped_refptr<TransformOperation> PerspectiveTransformOperation::Accumulate(
+ const TransformOperation& other) {
+ DCHECK(other.IsSameType(*this));
+ double other_p = ToPerspectiveTransformOperation(other).p_;
+
+ if (p_ == 0 && other_p == 0)
+ return nullptr;
+
+ // We want to solve:
+ // -1/p + -1/p' == -1/p'', where we know p and p'.
+ //
+ // This can be rewritten as:
+ // p'' == (p * p') / (p + p')
+ double p = (p_ * other_p) / (p_ + other_p);
+ return PerspectiveTransformOperation::Create(p);
+}
+
scoped_refptr<TransformOperation> PerspectiveTransformOperation::Blend(
const TransformOperation* from,
double progress,
@@ -62,7 +79,7 @@ scoped_refptr<TransformOperation> PerspectiveTransformOperation::Blend(
if (decomp.perspective_z) {
double val = -1.0 / decomp.perspective_z;
- return PerspectiveTransformOperation::Create(clampTo<int>(val, 0));
+ return PerspectiveTransformOperation::Create(clampTo<double>(val, 0));
}
return PerspectiveTransformOperation::Create(0);
}
diff --git a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
index 6928e93dd61..24628650440 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
@@ -62,12 +62,17 @@ class PLATFORM_EXPORT PerspectiveTransformOperation final
transform.ApplyPerspective(p_);
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
bool blend_to_identity = false) override;
scoped_refptr<TransformOperation> Zoom(double factor) final;
+ // Perspective does not, by itself, specify a 3D transform.
+ bool HasNonTrivial3DComponent() const override { return false; }
+
PerspectiveTransformOperation(double p) : p_(p) {}
double p_;
diff --git a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
index f02ea5f9e9f..4910951d0e3 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
@@ -24,6 +24,20 @@
#include "third_party/blink/renderer/platform/geometry/blend.h"
namespace blink {
+namespace {
+TransformOperation::OperationType GetTypeForRotation(const Rotation& rotation) {
+ float x = rotation.axis.X();
+ float y = rotation.axis.Y();
+ float z = rotation.axis.Z();
+ if (x && !y && !z)
+ return TransformOperation::kRotateX;
+ if (y && !x && !z)
+ return TransformOperation::kRotateY;
+ if (z && !x && !y)
+ return TransformOperation::kRotateZ;
+ return TransformOperation::kRotate3D;
+}
+} // namespace
bool RotateTransformOperation::operator==(
const TransformOperation& other) const {
@@ -44,6 +58,15 @@ bool RotateTransformOperation::GetCommonAxis(const RotateTransformOperation* a,
result_angle_a, result_angle_b);
}
+scoped_refptr<TransformOperation> RotateTransformOperation::Accumulate(
+ const TransformOperation& other) {
+ DCHECK(IsMatchingOperationType(other.GetType()));
+ Rotation new_rotation =
+ Rotation::Add(rotation_, ToRotateTransformOperation(other).rotation_);
+ return RotateTransformOperation::Create(new_rotation,
+ GetTypeForRotation(new_rotation));
+}
+
scoped_refptr<TransformOperation> RotateTransformOperation::Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
index 2aae491d965..d5f7bdd8d1e 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
@@ -86,6 +86,12 @@ class PLATFORM_EXPORT RotateTransformOperation : public TransformOperation {
protected:
bool operator==(const TransformOperation&) const override;
+ bool HasNonTrivial3DComponent() const override {
+ return Angle() && (X() || Y());
+ }
+
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
index 24a08849c2a..0f326e4ce8a 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
@@ -24,6 +24,40 @@
#include "third_party/blink/renderer/platform/geometry/blend.h"
namespace blink {
+namespace {
+// Return the correct OperationType for a given scale.
+TransformOperation::OperationType GetTypeForScale(double x,
+ double y,
+ double z) {
+ // Note: purely due to ordering, we will convert scale(1, 1, 1) to kScaleX.
+ // This is fine; they are equivalent.
+
+ if (z != 1)
+ return TransformOperation::kScale3D;
+
+ if (y == 1)
+ return TransformOperation::kScaleX;
+
+ if (x == 1)
+ return TransformOperation::kScaleY;
+
+ // Both x and y are non-1, so a 2D scale.
+ return TransformOperation::kScale;
+}
+} // namespace
+
+scoped_refptr<TransformOperation> ScaleTransformOperation::Accumulate(
+ const TransformOperation& other) {
+ DCHECK(other.CanBlendWith(*this));
+ const auto& other_op = ToScaleTransformOperation(other);
+ // Scale parameters are one in the identity transform function so use
+ // accumulation for one-based values.
+ double new_x = x_ + other_op.x_ - 1;
+ double new_y = y_ + other_op.y_ - 1;
+ double new_z = z_ + other_op.z_ - 1;
+ return ScaleTransformOperation::Create(new_x, new_y, new_z,
+ GetTypeForScale(new_x, new_y, new_z));
+}
scoped_refptr<TransformOperation> ScaleTransformOperation::Blend(
const TransformOperation* from,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
index 9ad90334544..874e3efd558 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
@@ -58,6 +58,8 @@ class PLATFORM_EXPORT ScaleTransformOperation final
void Apply(TransformationMatrix& transform, const FloatSize&) const override {
transform.Scale3d(x_, y_, z_);
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
index bf9558488a3..15eeabb0ed9 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
@@ -25,6 +25,14 @@
namespace blink {
+scoped_refptr<TransformOperation> SkewTransformOperation::Accumulate(
+ const TransformOperation& other) {
+ DCHECK(other.CanBlendWith(*this));
+ const SkewTransformOperation& skew_other = ToSkewTransformOperation(other);
+ return SkewTransformOperation::Create(angle_x_ + skew_other.angle_x_,
+ angle_y_ + skew_other.angle_y_, type_);
+}
+
scoped_refptr<TransformOperation> SkewTransformOperation::Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
index e638e60415d..368ddfcb371 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
@@ -62,6 +62,8 @@ class PLATFORM_EXPORT SkewTransformOperation final : public TransformOperation {
transform.Skew(angle_x_, angle_y_);
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
index ad257d3da9e..6ccfd1d7c04 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
@@ -74,6 +74,11 @@ class PLATFORM_EXPORT TransformOperation
virtual void Apply(TransformationMatrix&,
const FloatSize& border_box_size) const = 0;
+ // Implements the accumulative behavior described in
+ // https://drafts.csswg.org/css-transforms-2/#combining-transform-lists
+ virtual scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) = 0;
+
virtual scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
index b511af3367f..8e5477f54b2 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
@@ -28,9 +28,51 @@
#include "third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/rotate_transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
+namespace {
+using ApplyCallback = base::RepeatingCallback<scoped_refptr<TransformOperation>(
+ const scoped_refptr<TransformOperation>& from,
+ const scoped_refptr<TransformOperation>& to)>;
+
+// Applies a given function (|ApplyCallback|) to matching pairs of operations.
+TransformOperations ApplyFunctionToMatchingPrefix(
+ ApplyCallback apply_cb,
+ const TransformOperations& from,
+ const TransformOperations& to,
+ wtf_size_t matching_prefix_length,
+ bool* success) {
+ TransformOperations result;
+ wtf_size_t from_size = from.Operations().size();
+ wtf_size_t to_size = to.Operations().size();
+
+ // If the lists matched entirely but one was shorter, |matching_prefix_length|
+ // will be the length of the longer list and we implicitly consider the
+ // missing functions to be matching identity operations.
+ DCHECK(matching_prefix_length <= std::max(from_size, to_size));
+
+ for (wtf_size_t i = 0; i < matching_prefix_length; i++) {
+ scoped_refptr<TransformOperation> from_operation =
+ (i < from_size) ? from.Operations()[i].get() : nullptr;
+ scoped_refptr<TransformOperation> to_operation =
+ (i < to_size) ? to.Operations()[i].get() : nullptr;
+
+ scoped_refptr<TransformOperation> result_operation =
+ apply_cb.Run(from_operation, to_operation);
+
+ if (result_operation) {
+ result.Operations().push_back(result_operation);
+ } else {
+ *success = false;
+ return result;
+ }
+ }
+ return result;
+}
+} // namespace
+
TransformOperations::TransformOperations(bool make_identity) {
if (make_identity)
operations_.push_back(IdentityTransformOperation::Create());
@@ -75,36 +117,6 @@ wtf_size_t TransformOperations::MatchingPrefixLength(
return std::max(Operations().size(), other.Operations().size());
}
-TransformOperations TransformOperations::BlendPrefixByMatchingOperations(
- const TransformOperations& from,
- wtf_size_t matching_prefix_length,
- double progress,
- bool* success) const {
- TransformOperations result;
- wtf_size_t from_size = from.Operations().size();
- wtf_size_t to_size = Operations().size();
- for (wtf_size_t i = 0; i < matching_prefix_length; i++) {
- scoped_refptr<TransformOperation> from_operation =
- (i < from_size) ? from.Operations()[i].get() : nullptr;
- scoped_refptr<TransformOperation> to_operation =
- (i < to_size) ? Operations()[i].get() : nullptr;
-
- scoped_refptr<TransformOperation> blended_operation =
- to_operation
- ? to_operation->Blend(from_operation.get(), progress)
- : (from_operation ? from_operation->Blend(nullptr, progress, true)
- : nullptr);
-
- if (blended_operation)
- result.Operations().push_back(blended_operation);
- else {
- *success = false;
- return result;
- }
- }
- return result;
-}
-
scoped_refptr<TransformOperation>
TransformOperations::BlendRemainingByUsingMatrixInterpolation(
const TransformOperations& from,
@@ -146,8 +158,17 @@ TransformOperations TransformOperations::Blend(const TransformOperations& from,
std::max(Operations().size(), from.Operations().size());
bool success = true;
- TransformOperations result = BlendPrefixByMatchingOperations(
- from, matching_prefix_length, progress, &success);
+ TransformOperations result = ApplyFunctionToMatchingPrefix(
+ WTF::BindRepeating(
+ [](double progress, const scoped_refptr<TransformOperation>& from,
+ const scoped_refptr<TransformOperation>& to) {
+ // Where the lists matched but one was longer, the shorter list is
+ // padded with nullptr that represent matching identity operations.
+ return to ? to->Blend(from.get(), progress)
+ : (from ? from->Blend(nullptr, progress, true) : nullptr);
+ },
+ progress),
+ from, *this, matching_prefix_length, &success);
if (success && matching_prefix_length < max_path_length) {
scoped_refptr<TransformOperation> matrix_op =
BlendRemainingByUsingMatrixInterpolation(from, matching_prefix_length,
@@ -163,6 +184,54 @@ TransformOperations TransformOperations::Blend(const TransformOperations& from,
return result;
}
+TransformOperations TransformOperations::Accumulate(
+ const TransformOperations& to) const {
+ if (!to.size() && !size())
+ return *this;
+
+ bool success = true;
+ wtf_size_t matching_prefix_length = MatchingPrefixLength(to);
+ wtf_size_t max_path_length =
+ std::max(Operations().size(), to.Operations().size());
+
+ // Accumulate matching pairs of transform functions.
+ TransformOperations result = ApplyFunctionToMatchingPrefix(
+ WTF::BindRepeating([](const scoped_refptr<TransformOperation>& from,
+ const scoped_refptr<TransformOperation>& to) {
+ if (to && from)
+ return from->Accumulate(*to);
+ // Where the lists matched but one was longer, the shorter list is
+ // padded with nullptr that represent matching identity operations. For
+ // any function, accumulate(f, identity) == f, so just return f.
+ return to ? to : from;
+ }),
+ *this, to, matching_prefix_length, &success);
+
+ // Then, if there are leftover non-matching functions, accumulate the
+ // remaining matrices.
+ if (success && matching_prefix_length < max_path_length) {
+ TransformationMatrix from_transform;
+ TransformationMatrix to_transform;
+ ApplyRemaining(FloatSize(), matching_prefix_length, from_transform);
+ to.ApplyRemaining(FloatSize(), matching_prefix_length, to_transform);
+
+ scoped_refptr<TransformOperation> from_matrix =
+ Matrix3DTransformOperation::Create(from_transform);
+ scoped_refptr<TransformOperation> to_matrix =
+ Matrix3DTransformOperation::Create(to_transform);
+ scoped_refptr<TransformOperation> matrix_op =
+ from_matrix->Accumulate(*to_matrix);
+
+ if (matrix_op)
+ result.Operations().push_back(matrix_op);
+ else
+ success = false;
+ }
+
+ // On failure, behavior is to replace.
+ return success ? result : to;
+}
+
static void FindCandidatesInPlane(double px,
double py,
double nz,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.h b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.h
index 51d25367425..4e4978b4170 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.h
@@ -73,7 +73,7 @@ class PLATFORM_EXPORT TransformOperations {
}
// Return true if any of the operation types are non-perspective 3D operation
- // types (even if the values describe affine transforms)
+ // types (even if the values describe affine transforms).
bool HasNonPerspective3DOperation() const {
for (auto& operation : operations_) {
if (operation->Is3DOperation() &&
@@ -91,8 +91,7 @@ class PLATFORM_EXPORT TransformOperations {
return true;
}
- // Returns true if any operation has a non-trivial component in the Z
- // axis.
+ // Returns true if any operation has a non-trivial component in the Z axis.
bool HasNonTrivial3DComponent() const {
for (auto& operation : operations_) {
if (operation->HasNonTrivial3DComponent())
@@ -140,11 +139,6 @@ class PLATFORM_EXPORT TransformOperations {
const double& max_progress,
FloatBox* bounds) const;
- TransformOperations BlendPrefixByMatchingOperations(
- const TransformOperations& from,
- wtf_size_t matching_prefix_length,
- double progress,
- bool* success) const;
scoped_refptr<TransformOperation> BlendRemainingByUsingMatrixInterpolation(
const TransformOperations& from,
wtf_size_t matching_prefix_length,
@@ -155,6 +149,10 @@ class PLATFORM_EXPORT TransformOperations {
TransformOperations Add(const TransformOperations& addend) const;
TransformOperations Zoom(double factor) const;
+ // Perform accumulation of |to| onto |this|, as specified in
+ // https://drafts.csswg.org/css-transforms-2/#combining-transform-lists
+ TransformOperations Accumulate(const TransformOperations& to) const;
+
private:
Vector<scoped_refptr<TransformOperation>> operations_;
};
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operations_test.cc b/chromium/third_party/blink/renderer/platform/transforms/transform_operations_test.cc
index 2a9c9c3fe6b..fc6169ab273 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operations_test.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operations_test.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/platform/geometry/float_box.h"
#include "third_party/blink/renderer/platform/geometry/float_box_test_helpers.h"
#include "third_party/blink/renderer/platform/transforms/identity_transform_operation.h"
+#include "third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/matrix_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/perspective_transform_operation.h"
@@ -380,9 +381,9 @@ TEST(TransformOperationsTest, AbsoluteAnimatedPerspectiveBoundsTest) {
from_ops.BlendedBoundsForBox(box, to_ops, -0.25, 1.25, &bounds);
// The perspective range was [20, 40] and blending will extrapolate that to
- // [17, 53]. The cube has w/h/d of 10 and the observer is at 17, so the face
- // closest the observer is 17-10=7.
- double projected_size = 10.0 / 7.0 * 17.0;
+ // [17.777..., 53.333...]. The cube has w/h/d of 10 and the observer is at
+ // 17.777..., so the face closest the observer is 17.777...-10=7.777...
+ double projected_size = 10.0 / 7.7778 * 17.7778;
EXPECT_PRED_FORMAT2(
float_box_test::AssertAlmostEqual,
FloatBox(0, 0, 0, projected_size, projected_size, projected_size),
@@ -550,20 +551,55 @@ TEST(TransformOperationsTest, PerspectiveOpsTest) {
TransformOperations ops;
EXPECT_FALSE(ops.HasPerspective());
EXPECT_FALSE(ops.HasNonPerspective3DOperation());
+ EXPECT_FALSE(ops.HasNonTrivial3DComponent());
ops.Operations().push_back(TranslateTransformOperation::Create(
Length::Fixed(1), Length::Fixed(2), TransformOperation::kTranslate));
EXPECT_FALSE(ops.HasPerspective());
EXPECT_FALSE(ops.HasNonPerspective3DOperation());
+ EXPECT_FALSE(ops.HasNonTrivial3DComponent());
ops.Operations().push_back(PerspectiveTransformOperation::Create(1234));
EXPECT_TRUE(ops.HasPerspective());
EXPECT_FALSE(ops.HasNonPerspective3DOperation());
+ EXPECT_FALSE(ops.HasNonTrivial3DComponent());
ops.Operations().push_back(TranslateTransformOperation::Create(
Length::Fixed(1), Length::Fixed(2), 3, TransformOperation::kTranslate3D));
EXPECT_TRUE(ops.HasPerspective());
EXPECT_TRUE(ops.HasNonPerspective3DOperation());
+ EXPECT_TRUE(ops.HasNonTrivial3DComponent());
}
+TEST(TransformOperations, InterpolatedTransformBlendTest) {
+ // When interpolating transform lists of differing lengths,the length of the
+ // shorter list is padded with identity transforms. The Blend method accepts a
+ // null from operator when blending from an identity transform. This test
+ // verifies the correctness of an interpolated transform when the 'from
+ // transform' list is shorter than the 'to transform' list (crbug.com/998938).
+ TransformOperations empt_from, from_ops_padding;
+ TransformOperations to_ops, to_intrepolated;
+ double progress = 0.25, abs_difference = 1e-5;
+ to_ops.Operations().push_back(
+ ScaleTransformOperation::Create(5, 2, TransformOperation::kScale));
+ // to_interpolated is scale(2, 1.25)
+ to_intrepolated.Operations().push_back(
+ InterpolatedTransformOperation::Create(empt_from, to_ops, 0, progress));
+ // result is scale(1.25, 1.0625)
+ TransformOperations result = to_intrepolated.Blend(empt_from, progress);
+ from_ops_padding.Operations().push_back(TranslateTransformOperation::Create(
+ Length::Fixed(20), Length::Fixed(20), TransformOperation::kTranslate));
+ // Pad the from_ops_padding to have at least one operation, otherwise it would
+ // execute the matching prefix.
+ FloatPoint3D original_point(64, 64, 4);
+ FloatPoint3D expected_point(83, 80, 4);
+ TransformationMatrix blended_transform;
+ // result is scale(1.0625, 1.015625) and translate(15, 15)
+ result = result.Blend(from_ops_padding, progress);
+ result.Apply(FloatSize(), blended_transform);
+ FloatPoint3D final_point = blended_transform.MapPoint(original_point);
+ EXPECT_NEAR(expected_point.X(), final_point.X(), abs_difference);
+ EXPECT_NEAR(expected_point.Y(), final_point.Y(), abs_difference);
+ EXPECT_NEAR(expected_point.Z(), final_point.Z(), abs_difference);
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
index e7280ef2eae..86fc8ff89ec 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
@@ -22,9 +22,54 @@
#include "third_party/blink/renderer/platform/transforms/translate_transform_operation.h"
#include "third_party/blink/renderer/platform/geometry/blend.h"
+#include "third_party/blink/renderer/platform/geometry/calculation_value.h"
namespace blink {
+namespace {
+Length AddLengths(const Length& lhs, const Length& rhs) {
+ PixelsAndPercent lhs_pap = lhs.GetPixelsAndPercent();
+ PixelsAndPercent rhs_pap = rhs.GetPixelsAndPercent();
+
+ PixelsAndPercent result = PixelsAndPercent(lhs_pap.pixels + rhs_pap.pixels,
+ lhs_pap.percent + rhs_pap.percent);
+ if (result.percent == 0)
+ return Length(result.pixels, Length::kFixed);
+ if (result.pixels == 0)
+ return Length(result.percent, Length::kPercent);
+ return Length(CalculationValue::Create(result, kValueRangeAll));
+}
+
+TransformOperation::OperationType GetTypeForTranslate(const Length& x,
+ const Length& y,
+ double z) {
+ bool x_zero = x.IsZero();
+ bool y_zero = x.IsZero();
+ bool z_zero = !z;
+ if (!x_zero && !y_zero && !z_zero)
+ return TransformOperation::kTranslate3D;
+ if (y_zero && z_zero)
+ return TransformOperation::kTranslateX;
+ if (x_zero && z_zero)
+ return TransformOperation::kTranslateY;
+ if (x_zero && y_zero)
+ return TransformOperation::kTranslateZ;
+ return TransformOperation::kTranslate;
+}
+} // namespace
+
+scoped_refptr<TransformOperation> TranslateTransformOperation::Accumulate(
+ const TransformOperation& other) {
+ DCHECK(other.CanBlendWith(*this));
+
+ const auto& other_op = ToTranslateTransformOperation(other);
+ Length new_x = AddLengths(x_, other_op.x_);
+ Length new_y = AddLengths(y_, other_op.y_);
+ double new_z = z_ + other_op.z_;
+ return TranslateTransformOperation::Create(
+ new_x, new_y, new_z, GetTypeForTranslate(new_x, new_y, new_z));
+}
+
scoped_refptr<TransformOperation> TranslateTransformOperation::Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
index 6ead517ae12..b73cb80331e 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
@@ -91,6 +91,8 @@ class PLATFORM_EXPORT TranslateTransformOperation final
return x_ == t->x_ && y_ == t->y_ && z_ == t->z_;
}
+ scoped_refptr<TransformOperation> Accumulate(
+ const TransformOperation& other) override;
scoped_refptr<TransformOperation> Blend(
const TransformOperation* from,
double progress,
diff --git a/chromium/third_party/blink/renderer/platform/video_capture/local_video_capturer_source.cc b/chromium/third_party/blink/renderer/platform/video_capture/local_video_capturer_source.cc
index f32f764080a..9be33f3fa92 100644
--- a/chromium/third_party/blink/renderer/platform/video_capture/local_video_capturer_source.cc
+++ b/chromium/third_party/blink/renderer/platform/video_capture/local_video_capturer_source.cc
@@ -43,7 +43,7 @@ void LocalVideoCapturerSource::StartCapture(
stop_capture_cb_ = manager_->StartCapture(
session_id_, params,
media::BindToLoop(task_runner_,
- ConvertToBaseCallback(CrossThreadBindRepeating(
+ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&LocalVideoCapturerSource::OnStateUpdate,
weak_factory_.GetWeakPtr()))),
new_frame_callback);
diff --git a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
index eacd0c7d4ff..e88c93054d6 100644
--- a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -295,7 +295,7 @@ VideoCaptureImpl::VideoCaptureImpl(media::VideoCaptureSessionId session_id)
CHECK(!session_id.is_empty());
DETACH_FROM_THREAD(io_thread_checker_);
- Platform::Current()->GetBrowserInterfaceBrokerProxy()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
pending_video_capture_host_.InitWithNewPipeAndPassReceiver());
gpu_factories_ = Platform::Current()->GetGpuFactories();
diff --git a/chromium/third_party/blink/renderer/platform/web_test_support.cc b/chromium/third_party/blink/renderer/platform/web_test_support.cc
index 670799d70e5..2f705df2a59 100644
--- a/chromium/third_party/blink/renderer/platform/web_test_support.cc
+++ b/chromium/third_party/blink/renderer/platform/web_test_support.cc
@@ -53,7 +53,6 @@ bool FontAntialiasingEnabledForTest() {
}
static bool g_is_running_web_test = false;
-static bool g_is_mock_theme_enabled = false;
static bool g_is_font_antialiasing_enabled = false;
static bool g_is_subpixel_positioning_allowed = true;
@@ -65,15 +64,6 @@ void WebTestSupport::SetIsRunningWebTest(bool value) {
g_is_running_web_test = value;
}
-bool WebTestSupport::IsMockThemeEnabledForTest() {
- return g_is_mock_theme_enabled;
-}
-
-void WebTestSupport::SetMockThemeEnabledForTest(bool value) {
- DCHECK(g_is_running_web_test);
- g_is_mock_theme_enabled = value;
-}
-
bool WebTestSupport::IsFontAntialiasingEnabledForTest() {
return g_is_font_antialiasing_enabled;
}
diff --git a/chromium/third_party/blink/renderer/platform/web_test_support.h b/chromium/third_party/blink/renderer/platform/web_test_support.h
index afc920eaceb..451ed5c378e 100644
--- a/chromium/third_party/blink/renderer/platform/web_test_support.h
+++ b/chromium/third_party/blink/renderer/platform/web_test_support.h
@@ -42,8 +42,6 @@ class WebTestSupport {
public:
PLATFORM_EXPORT static bool IsRunningWebTest();
PLATFORM_EXPORT static void SetIsRunningWebTest(bool);
- PLATFORM_EXPORT static bool IsMockThemeEnabledForTest();
- PLATFORM_EXPORT static void SetMockThemeEnabledForTest(bool);
PLATFORM_EXPORT static bool IsFontAntialiasingEnabledForTest();
PLATFORM_EXPORT static void SetFontAntialiasingEnabledForTest(bool);
PLATFORM_EXPORT static bool IsTextSubpixelPositioningAllowedForTest();
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/DEPS b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
index 14eb4e427a2..0d5faf41ba0 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/DEPS
+++ b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
@@ -12,6 +12,7 @@ include_rules = [
"+services/network/public/cpp/cors/origin_access_entry.h",
"+services/network/public/cpp/cors/origin_access_list.h",
"+third_party/blink/renderer/platform/blob/blob_url.h",
+ "+third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/runtime_enabled_features.h",
"+third_party/blink/renderer/platform/testing",
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/known_ports.cc b/chromium/third_party/blink/renderer/platform/weborigin/known_ports.cc
index 5cf7ba7f156..6b3054a58ad 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/known_ports.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/known_ports.cc
@@ -46,8 +46,6 @@ bool IsDefaultPortForProtocol(uint16_t port, const WTF::String& protocol) {
return protocol == "ftp";
case 990:
return protocol == "ftps";
- case 70:
- return protocol == "gopher";
}
return false;
}
@@ -61,8 +59,6 @@ uint16_t DefaultPortForProtocol(const WTF::String& protocol) {
return 21;
if (protocol == "ftps")
return 990;
- if (protocol == "gopher")
- return 70;
return 0;
}
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
index 32e4c6904d6..4ab44fc6c7d 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
@@ -476,11 +476,27 @@ static String ParsePortFromStringPosition(const String& value,
}
void KURL::SetHostAndPort(const String& host_and_port) {
- wtf_size_t separator = host_and_port.find(':');
- if (!separator)
+ // This method intentionally does very sloppy parsing for backwards
+ // compatibility. See https://url.spec.whatwg.org/#host-state for what we
+ // theoretically should be doing.
+
+ // This logic for handling IPv6 addresses is adapted from ParseServerInfo in
+ // //url/third_party/mozilla/url_parse.cc. There's a slight behaviour
+ // difference for compatibility with the tests: the first colon after the
+ // address is considered to start the port, instead of the last.
+ wtf_size_t ipv6_terminator = host_and_port.ReverseFind(']');
+ if (ipv6_terminator == kNotFound) {
+ ipv6_terminator =
+ host_and_port.StartsWith('[') ? host_and_port.length() : 0;
+ }
+
+ wtf_size_t colon = host_and_port.find(':', ipv6_terminator);
+
+ if (colon == 0)
return;
- if (separator == kNotFound) {
+ if (colon == kNotFound) {
+ // |host_and_port| does not include a port, so only overwrite the host.
url::Replacements<char> replacements;
StringUTF8Adaptor host_utf8(host_and_port);
replacements.SetHost(CharactersOrEmpty(host_utf8),
@@ -489,8 +505,8 @@ void KURL::SetHostAndPort(const String& host_and_port) {
return;
}
- String host = host_and_port.Substring(0, separator);
- String port = ParsePortFromStringPosition(host_and_port, separator + 1);
+ String host = host_and_port.Substring(0, colon);
+ String port = ParsePortFromStringPosition(host_and_port, colon + 1);
StringUTF8Adaptor host_utf8(host);
StringUTF8Adaptor port_utf8(port);
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
index d254daa132f..32b3ae8a580 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
@@ -987,6 +987,8 @@ TEST_P(KURLPortTest, SetHostAndPort) {
}
}
-INSTANTIATE_TEST_SUITE_P(, KURLPortTest, ::testing::ValuesIn(port_test_cases));
+INSTANTIATE_TEST_SUITE_P(All,
+ KURLPortTest,
+ ::testing::ValuesIn(port_test_cases));
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
index 373f344b4ba..3903a94f5df 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
@@ -249,7 +249,7 @@ String SchemeRegistry::ListOfCorsEnabledURLSchemes() {
}
bool SchemeRegistry::ShouldTreatURLSchemeAsLegacy(const String& scheme) {
- return scheme == "ftp" || scheme == "gopher";
+ return scheme == "ftp";
}
bool SchemeRegistry::ShouldTrackUsageMetricsForScheme(const String& scheme) {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
index 9620bbee516..4ef1bdfd07f 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
@@ -92,8 +92,8 @@ class PLATFORM_EXPORT SchemeRegistry {
// Serialize the registered schemes in a comma-separated list.
static String ListOfCorsEnabledURLSchemes();
- // "Legacy" schemes (e.g. 'ftp:', 'gopher:') which we might want to treat
- // differently from "webby" schemes.
+ // "Legacy" schemes (e.g. 'ftp:') which we might want to treat differently
+ // from "webby" schemes.
static bool ShouldTreatURLSchemeAsLegacy(const String& scheme);
// Does the scheme represent a location relevant to web compatibility metrics?
@@ -112,6 +112,9 @@ class PLATFORM_EXPORT SchemeRegistry {
static bool IsFetchScheme(const String& scheme);
// Schemes which override the first-/third-party checks on a Document.
+ // TODO(chlily): This should also reflect the fact that chrome:// scheme
+ // should be considered first-party if the embedded origin is secure, to be
+ // consistent with other places that check this.
static void RegisterURLSchemeAsFirstPartyWhenTopLevel(const String& scheme);
static void RemoveURLSchemeAsFirstPartyWhenTopLevel(const String& scheme);
static bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
index 922fbdee70a..e71853c7d3c 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -35,13 +35,14 @@
#include <utility>
#include "net/base/url_util.h"
+#include "third_party/blink/renderer/platform/blob/blob_url.h"
+#include "third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
-#include "third_party/blink/renderer/platform/weborigin/url_security_origin_map.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -63,15 +64,6 @@ const String& EnsureNonNull(const String& string) {
} // namespace
-static URLSecurityOriginMap* g_blob_url_null_origin_map = nullptr;
-
-static SecurityOrigin* GetNullOriginFromBlobURL(const KURL& blob_url) {
- DCHECK(blob_url.ProtocolIs("blob"));
- if (g_blob_url_null_origin_map)
- return g_blob_url_null_origin_map->GetOrigin(blob_url);
- return nullptr;
-}
-
bool SecurityOrigin::ShouldUseInnerURL(const KURL& url) {
// FIXME: Blob URLs don't have inner URLs. Their form is
// "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL
@@ -94,12 +86,6 @@ KURL SecurityOrigin::ExtractInnerURL(const KURL& url) {
return KURL(url.GetPath());
}
-void SecurityOrigin::SetBlobURLNullOriginMap(
- URLSecurityOriginMap* blob_url_null_origin_map) {
- DCHECK(!g_blob_url_null_origin_map);
- g_blob_url_null_origin_map = blob_url_null_origin_map;
-}
-
static bool ShouldTreatAsOpaqueOrigin(const KURL& url) {
if (!url.IsValid())
return true;
@@ -205,8 +191,9 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other,
scoped_refptr<SecurityOrigin> SecurityOrigin::CreateWithReferenceOrigin(
const KURL& url,
const SecurityOrigin* reference_origin) {
- if (url.ProtocolIs("blob")) {
- if (scoped_refptr<SecurityOrigin> origin = GetNullOriginFromBlobURL(url))
+ if (url.ProtocolIs("blob") && BlobURL::GetOrigin(url) == "null") {
+ if (scoped_refptr<SecurityOrigin> origin =
+ BlobURLNullOriginMap::GetInstance()->Get(url))
return origin;
}
@@ -419,9 +406,16 @@ bool SecurityOrigin::CanRequest(const KURL& url) const {
if (SerializesAsNull()) {
// Allow the request if the URL is blob and it has the same "null" origin
// with |this|.
- // TODO(nhiroki): Probably we should check the equality by
- // SecurityOrigin::IsSameSchemeHostPort().
- if (url.ProtocolIs("blob") && GetNullOriginFromBlobURL(url) == this)
+ if (!url.ProtocolIs("blob") || BlobURL::GetOrigin(url) != "null")
+ return false;
+ if (BlobURLNullOriginMap::GetInstance()->Get(url) == this)
+ return true;
+ // BlobURLNullOriginMap doesn't work for cross-thread blob URL loading
+ // (e.g., top-level worker script loading) because SecurityOrigin and
+ // BlobURLNullOriginMap are thread-specific. For the case, check
+ // BlobURLOpaqueOriginNonceMap.
+ base::Optional<base::UnguessableToken> nonce = GetNonceForSerialization();
+ if (nonce && BlobURLOpaqueOriginNonceMap::GetInstance().Get(url) == nonce)
return true;
return false;
}
@@ -432,9 +426,9 @@ bool SecurityOrigin::CanRequest(const KURL& url) const {
if (target_origin->IsOpaque())
return false;
- // We call isSameSchemeHostPort here instead of canAccess because we want
- // to ignore document.domain effects.
- if (IsSameSchemeHostPort(target_origin.get()))
+ // We call IsSameOriginWith here instead of canAccess because we want to
+ // ignore `document.domain` effects.
+ if (IsSameOriginWith(target_origin.get()))
return true;
if (SecurityPolicy::IsOriginAccessAllowed(this, target_origin.get()))
@@ -603,7 +597,7 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol,
return Create(KURL(NullURL(), protocol + "://" + host + port_part + "/"));
}
-bool SecurityOrigin::IsSameSchemeHostPort(const SecurityOrigin* other) const {
+bool SecurityOrigin::IsSameOriginWith(const SecurityOrigin* other) const {
// This is needed to ensure a local origin considered to have the same scheme,
// host, and port to itself.
// TODO(tzik): Make the local origin unique but not opaque, and remove this
@@ -629,10 +623,10 @@ bool SecurityOrigin::IsSameSchemeHostPort(const SecurityOrigin* other) const {
return true;
}
-bool SecurityOrigin::AreSameSchemeHostPort(const KURL& a, const KURL& b) {
+bool SecurityOrigin::AreSameOrigin(const KURL& a, const KURL& b) {
scoped_refptr<const SecurityOrigin> origin_a = SecurityOrigin::Create(a);
scoped_refptr<const SecurityOrigin> origin_b = SecurityOrigin::Create(b);
- return origin_b->IsSameSchemeHostPort(origin_a.get());
+ return origin_b->IsSameOriginWith(origin_a.get());
}
const KURL& SecurityOrigin::UrlWithUniqueOpaqueOrigin() {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
index 19595353110..7a02c33ca25 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -47,7 +47,6 @@ struct UrlOriginAdapter;
namespace blink {
class KURL;
-class URLSecurityOriginMap;
struct SecurityOriginHash;
// An identifier which defines the source of content (e.g. a document) and
@@ -95,10 +94,6 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
static scoped_refptr<SecurityOrigin> CreateFromUrlOrigin(const url::Origin&);
url::Origin ToUrlOrigin() const;
- // Sets the map to look up a SecurityOrigin instance serialized to "null" from
- // a blob URL.
- static void SetBlobURLNullOriginMap(URLSecurityOriginMap*);
-
// Some URL schemes use nested URLs for their security context. For example,
// filesystem URLs look like the following:
//
@@ -227,6 +222,7 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
bool CanAccessCookies() const { return !IsOpaque(); }
bool CanAccessPasswordManager() const { return !IsOpaque(); }
bool CanAccessFileSystem() const { return !IsOpaque(); }
+ bool CanAccessNativeFileSystem() const { return !IsOpaque(); }
bool CanAccessCacheStorage() const { return !IsOpaque(); }
bool CanAccessLocks() const { return !IsOpaque(); }
@@ -285,12 +281,18 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
// https://html.spec.whatwg.org/C/origin.html#same-origin-domain
String ToTokenForFastCheck() const;
- // This method checks for equality, ignoring the value of document.domain
- // (and whether it was set) but considering the host. It is used for
- // postMessage.
- bool IsSameSchemeHostPort(const SecurityOrigin*) const;
-
- static bool AreSameSchemeHostPort(const KURL& a, const KURL& b);
+ // This method implements HTML's "same origin" check, which verifies equality
+ // of opaque origins, or exact (scheme,host,port) matches. Note that
+ // `document.domain` does not come into play for this comparison.
+ //
+ // This method does not take the "universal access" flag into account. It does
+ // take the "local access" flag into account, considering `file:` origins that
+ // set the flag to be same-origin with all other `file:` origins that set the
+ // flag.
+ //
+ // https://html.spec.whatwg.org/#same-origin
+ bool IsSameOriginWith(const SecurityOrigin*) const;
+ static bool AreSameOrigin(const KURL& a, const KURL& b);
static const KURL& UrlWithUniqueOpaqueOrigin();
@@ -345,6 +347,9 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
friend struct mojo::UrlOriginAdapter;
friend struct blink::SecurityOriginHash;
+ // For calling GetNonceForSerialization().
+ friend class BlobURLOpaqueOriginNonceMap;
+
// Creates a new opaque SecurityOrigin using the supplied |precursor| origin
// and |nonce|.
static scoped_refptr<SecurityOrigin> CreateOpaque(
@@ -370,8 +375,9 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
bool PassesFileCheck(const SecurityOrigin*) const;
void BuildRawString(StringBuilder&) const;
- // Get the nonce associated with this origin, if it is unique. This should be
- // used only when trying to send an Origin across an IPC pipe.
+ // Get the nonce associated with this origin, if it is opaque. This should be
+ // used only when trying to send an Origin across an IPC pipe or comparing
+ // blob URL's opaque origins in the thread-safe way.
base::Optional<base::UnguessableToken> GetNonceForSerialization() const;
const String protocol_ = g_empty_string;
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_hash.h b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_hash.h
index eb710187725..4660755ecc0 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_hash.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_hash.h
@@ -71,7 +71,7 @@ struct SecurityOriginHash {
if (!a || !b)
return a == b;
- return a->IsSameSchemeHostPort(b);
+ return a->IsSameOriginWith(b);
}
static bool Equal(const SecurityOrigin* a,
const scoped_refptr<const SecurityOrigin>& b) {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
index d58dedd4d21..3c10ca1288f 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -75,9 +75,9 @@ TEST_F(SecurityOriginTest, LocalAccess) {
scoped_refptr<const SecurityOrigin> file2 =
SecurityOrigin::CreateFromString("file:///etc/shadow");
- EXPECT_TRUE(file1->IsSameSchemeHostPort(file1.get()));
- EXPECT_TRUE(file1->IsSameSchemeHostPort(file2.get()));
- EXPECT_TRUE(file2->IsSameSchemeHostPort(file1.get()));
+ EXPECT_TRUE(file1->IsSameOriginWith(file1.get()));
+ EXPECT_TRUE(file1->IsSameOriginWith(file2.get()));
+ EXPECT_TRUE(file2->IsSameOriginWith(file1.get()));
EXPECT_TRUE(file1->CanAccess(file1.get()));
EXPECT_TRUE(file1->CanAccess(file2.get()));
@@ -86,9 +86,9 @@ TEST_F(SecurityOriginTest, LocalAccess) {
// Block |file1|'s access to local origins. It should now be same-origin
// with itself, but shouldn't have access to |file2|.
file1->BlockLocalAccessFromLocalOrigin();
- EXPECT_TRUE(file1->IsSameSchemeHostPort(file1.get()));
- EXPECT_FALSE(file1->IsSameSchemeHostPort(file2.get()));
- EXPECT_FALSE(file2->IsSameSchemeHostPort(file1.get()));
+ EXPECT_TRUE(file1->IsSameOriginWith(file1.get()));
+ EXPECT_FALSE(file1->IsSameOriginWith(file2.get()));
+ EXPECT_FALSE(file2->IsSameOriginWith(file1.get()));
EXPECT_TRUE(file1->CanAccess(file1.get()));
EXPECT_FALSE(file1->CanAccess(file2.get()));
@@ -580,7 +580,6 @@ TEST_F(SecurityOriginTest, CreateFromTuple) {
{"https", "example.com", 444, "https://example.com:444"},
{"file", "", 0, "file://"},
{"file", "example.com", 0, "file://"},
- {"gopher", "Foo.com", 70, "gopher://foo.com"},
};
for (const auto& test : cases) {
@@ -623,17 +622,17 @@ TEST_F(SecurityOriginTest, OpaquenessPropagatesToBlobUrls) {
}
}
-TEST_F(SecurityOriginTest, OpaqueOriginIsSameSchemeHostPort) {
+TEST_F(SecurityOriginTest, OpaqueOriginIsSameOriginWith) {
scoped_refptr<const SecurityOrigin> opaque_origin =
SecurityOrigin::CreateUniqueOpaque();
scoped_refptr<const SecurityOrigin> tuple_origin =
SecurityOrigin::CreateFromString("http://example.com");
- EXPECT_TRUE(opaque_origin->IsSameSchemeHostPort(opaque_origin.get()));
- EXPECT_FALSE(SecurityOrigin::CreateUniqueOpaque()->IsSameSchemeHostPort(
+ EXPECT_TRUE(opaque_origin->IsSameOriginWith(opaque_origin.get()));
+ EXPECT_FALSE(SecurityOrigin::CreateUniqueOpaque()->IsSameOriginWith(
opaque_origin.get()));
- EXPECT_FALSE(tuple_origin->IsSameSchemeHostPort(opaque_origin.get()));
- EXPECT_FALSE(opaque_origin->IsSameSchemeHostPort(tuple_origin.get()));
+ EXPECT_FALSE(tuple_origin->IsSameOriginWith(opaque_origin.get()));
+ EXPECT_FALSE(opaque_origin->IsSameOriginWith(tuple_origin.get()));
}
TEST_F(SecurityOriginTest, CanonicalizeHost) {
@@ -700,9 +699,6 @@ TEST_F(SecurityOriginTest, UrlOriginConversions) {
// Registered URLs
{"ftp://example.com/", "ftp", "example.com", 21},
- // crbug.com/781342
- // Conversion doesn't work for gopher.
- // {"gopher://example.com/", "gopher", "example.com", 70},
{"ws://example.com/", "ws", "example.com", 80},
{"wss://example.com/", "wss", "example.com", 443},
@@ -722,9 +718,6 @@ TEST_F(SecurityOriginTest, UrlOriginConversions) {
123},
{"blob:https://example.com/guid-goes-here", "https", "example.com", 443},
{"blob:http://u:p@example.com/guid-goes-here", "http", "example.com", 80},
-
- // Gopher:
- {"gopher://8u.9.Vx6/", "gopher", "8u.9.vx6", 70},
};
for (const auto& test_case : cases) {
@@ -751,23 +744,23 @@ TEST_F(SecurityOriginTest, UrlOriginConversions) {
EXPECT_EQ(test_case.port, security_origin_via_kurl->EffectivePort());
EXPECT_EQ(test_case.opaque, security_origin_via_gurl->IsOpaque());
EXPECT_EQ(test_case.opaque, security_origin_via_kurl->IsOpaque());
- EXPECT_EQ(!test_case.opaque, security_origin_via_kurl->IsSameSchemeHostPort(
+ EXPECT_EQ(!test_case.opaque, security_origin_via_kurl->IsSameOriginWith(
security_origin_via_gurl.get()));
- EXPECT_EQ(!test_case.opaque, security_origin_via_gurl->IsSameSchemeHostPort(
+ EXPECT_EQ(!test_case.opaque, security_origin_via_gurl->IsSameOriginWith(
security_origin_via_kurl.get()));
if (!test_case.opaque) {
scoped_refptr<const SecurityOrigin> security_origin =
SecurityOrigin::Create(test_case.scheme, test_case.host,
test_case.port);
- EXPECT_TRUE(security_origin->IsSameSchemeHostPort(
- security_origin_via_gurl.get()));
- EXPECT_TRUE(security_origin->IsSameSchemeHostPort(
- security_origin_via_kurl.get()));
- EXPECT_TRUE(security_origin_via_gurl->IsSameSchemeHostPort(
- security_origin.get()));
- EXPECT_TRUE(security_origin_via_kurl->IsSameSchemeHostPort(
- security_origin.get()));
+ EXPECT_TRUE(
+ security_origin->IsSameOriginWith(security_origin_via_gurl.get()));
+ EXPECT_TRUE(
+ security_origin->IsSameOriginWith(security_origin_via_kurl.get()));
+ EXPECT_TRUE(
+ security_origin_via_gurl->IsSameOriginWith(security_origin.get()));
+ EXPECT_TRUE(
+ security_origin_via_kurl->IsSameOriginWith(security_origin.get()));
}
// Test ToUrlOrigin
@@ -906,7 +899,7 @@ TEST_F(SecurityOriginTest, OpaqueIsolatedCopy) {
SecurityOrigin::CreateUniqueOpaque();
scoped_refptr<const SecurityOrigin> copied = origin->IsolatedCopy();
EXPECT_TRUE(origin->CanAccess(copied.get()));
- EXPECT_TRUE(origin->IsSameSchemeHostPort(copied.get()));
+ EXPECT_TRUE(origin->IsSameOriginWith(copied.get()));
EXPECT_EQ(SecurityOriginHash::GetHash(origin),
SecurityOriginHash::GetHash(copied));
EXPECT_TRUE(SecurityOriginHash::Equal(origin, copied));
@@ -921,7 +914,7 @@ TEST_F(SecurityOriginTest, EdgeCases) {
scoped_refptr<SecurityOrigin> local =
SecurityOrigin::CreateFromString("file:///foo/bar");
local->BlockLocalAccessFromLocalOrigin();
- EXPECT_TRUE(local->IsSameSchemeHostPort(local.get()));
+ EXPECT_TRUE(local->IsSameOriginWith(local.get()));
}
TEST_F(SecurityOriginTest, RegistrableDomain) {
@@ -945,4 +938,102 @@ TEST_F(SecurityOriginTest, RegistrableDomain) {
EXPECT_EQ(String("example.com"), subdomain->RegistrableDomain());
}
+TEST_F(SecurityOriginTest, IsSameOriginWith) {
+ struct TestCase {
+ bool same_origin;
+ const char* a;
+ const char* b;
+ } tests[] = {{true, "https://a.com", "https://a.com"},
+
+ // Schemes
+ {false, "https://a.com", "http://a.com"},
+
+ // Hosts
+ {false, "https://a.com", "https://not-a.com"},
+ {false, "https://a.com", "https://sub.a.com"},
+
+ // Ports
+ {true, "https://a.com", "https://a.com:443"},
+ {false, "https://a.com", "https://a.com:444"},
+ {false, "https://a.com:442", "https://a.com:443"},
+
+ // Opaque
+ {false, "data:text/html,whatever", "data:text/html,whatever"}};
+
+ for (auto test : tests) {
+ SCOPED_TRACE(testing::Message() << "Origin 1: `" << test.a << "` "
+ << "Origin 2: `" << test.b << "`\n");
+ scoped_refptr<SecurityOrigin> a = SecurityOrigin::CreateFromString(test.a);
+ scoped_refptr<SecurityOrigin> b = SecurityOrigin::CreateFromString(test.b);
+ EXPECT_EQ(test.same_origin, a->IsSameOriginWith(b.get()));
+ EXPECT_EQ(test.same_origin, b->IsSameOriginWith(a.get()));
+
+ // Self-comparison
+ EXPECT_TRUE(a->IsSameOriginWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginWith(b.get()));
+
+ // DeriveNewOpaqueOrigin
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(a.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(a.get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->IsSameOriginWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(
+ a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(
+ b->DeriveNewOpaqueOrigin().get()));
+
+ // UniversalAccess does not change the result.
+ a->GrantUniversalAccess();
+ EXPECT_EQ(test.same_origin, a->IsSameOriginWith(b.get()));
+ EXPECT_EQ(test.same_origin, b->IsSameOriginWith(a.get()));
+ }
+}
+
+TEST_F(SecurityOriginTest, IsSameOriginWithWithLocalScheme) {
+ scoped_refptr<SecurityOrigin> a =
+ SecurityOrigin::CreateFromString("file:///etc/passwd");
+ scoped_refptr<SecurityOrigin> b =
+ SecurityOrigin::CreateFromString("file:///etc/hosts");
+
+ // Self-comparison
+ EXPECT_TRUE(a->IsSameOriginWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginWith(b.get()));
+
+ // block_local_access_from_local_origin_ defaults to `false`:
+ EXPECT_TRUE(a->IsSameOriginWith(b.get()));
+ EXPECT_TRUE(b->IsSameOriginWith(a.get()));
+
+ // DeriveNewOpaqueOrigin
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(a.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(a.get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->IsSameOriginWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginWith(
+ a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginWith(
+ b->DeriveNewOpaqueOrigin().get()));
+
+ // Set block_local_access_from_local_origin_ to `true`:
+ a->BlockLocalAccessFromLocalOrigin();
+ EXPECT_FALSE(a->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a.get()));
+
+ // Self-comparison should still be true.
+ EXPECT_TRUE(a->IsSameOriginWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginWith(b.get()));
+
+ // UniversalAccess does not override
+ a->GrantUniversalAccess();
+ EXPECT_FALSE(a->IsSameOriginWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginWith(a.get()));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
index 28062e71cfa..6f93952427c 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -137,7 +137,7 @@ Referrer SecurityPolicy::GenerateReferrer(
SecurityOrigin::Create(referrer_url);
scoped_refptr<const SecurityOrigin> url_origin =
SecurityOrigin::Create(url);
- if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+ if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
String origin = referrer_origin->ToString();
return Referrer(origin + "/", referrer_policy_no_default);
}
@@ -148,7 +148,7 @@ Referrer SecurityPolicy::GenerateReferrer(
SecurityOrigin::Create(referrer_url);
scoped_refptr<const SecurityOrigin> url_origin =
SecurityOrigin::Create(url);
- if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+ if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
}
return Referrer(referrer, referrer_policy_no_default);
@@ -166,7 +166,7 @@ Referrer SecurityPolicy::GenerateReferrer(
SecurityOrigin::Create(referrer_url);
scoped_refptr<const SecurityOrigin> url_origin =
SecurityOrigin::Create(url);
- if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+ if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
String origin = referrer_origin->ToString();
return Referrer(ShouldHideReferrer(url, referrer_url)
? Referrer::NoReferrer()
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/url_security_origin_map.h b/chromium/third_party/blink/renderer/platform/weborigin/url_security_origin_map.h
deleted file mode 100644
index 0cfe303ef9c..00000000000
--- a/chromium/third_party/blink/renderer/platform/weborigin/url_security_origin_map.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* Copyright (C) 2013 Google Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following disclaimer
-* in the documentation and/or other materials provided with the
-* distribution.
-* * Neither the name of Google Inc. nor the names of its
-* contributors may be used to endorse or promote products derived from
-* this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class KURL;
-class SecurityOrigin;
-
-class URLSecurityOriginMap {
- USING_FAST_MALLOC(URLSecurityOriginMap);
-
- public:
- URLSecurityOriginMap() = default;
- virtual ~URLSecurityOriginMap() = default;
-
- // Returns a SecurityOrigin instance that represents the origin of the given
- // URL. May return nullptr.
- virtual SecurityOrigin* GetOrigin(const KURL&) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(URLSecurityOriginMap);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
index 69ddc1649f7..46305d1b6b4 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
+++ b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
@@ -9,8 +9,8 @@
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/media_stream_interface.h"
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/track_observer.cc b/chromium/third_party/blink/renderer/platform/webrtc/track_observer.cc
index 20be5a1bd2c..782057f8812 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/track_observer.cc
+++ b/chromium/third_party/blink/renderer/platform/webrtc/track_observer.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/public/platform/modules/webrtc/track_observer.h"
+#include "third_party/blink/renderer/platform/webrtc/track_observer.h"
#include "base/bind.h"
#include "base/location.h"
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/track_observer.h b/chromium/third_party/blink/renderer/platform/webrtc/track_observer.h
new file mode 100644
index 00000000000..86237deff20
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/webrtc/track_observer.h
@@ -0,0 +1,37 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_TRACK_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_TRACK_OBSERVER_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/media_stream_interface.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT TrackObserver {
+ public:
+ TrackObserver(const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
+ const scoped_refptr<webrtc::MediaStreamTrackInterface>& track);
+ ~TrackObserver();
+
+ using OnChangedCallback = base::RepeatingCallback<void(
+ webrtc::MediaStreamTrackInterface::TrackState)>;
+ void SetCallback(const OnChangedCallback& callback);
+
+ const scoped_refptr<webrtc::MediaStreamTrackInterface>& track() const;
+
+ private:
+ class TrackObserverImpl;
+ const scoped_refptr<TrackObserverImpl> observer_;
+ DISALLOW_COPY_AND_ASSIGN(TrackObserver);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_TRACK_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_logging.cc b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_logging.cc
index ce20111c902..c4416dd4ee3 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_logging.cc
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_logging.cc
@@ -25,6 +25,7 @@ void InitWebRtcLogging() {
}
void WebRtcLogMessage(const std::string& message) {
+ DVLOG(1) << message;
if (g_webrtc_logging_delegate)
g_webrtc_logging_delegate->LogMessage(message);
}
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h
new file mode 100644
index 00000000000..8ef336fe2e4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h
@@ -0,0 +1,92 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_WEBRTC_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_WEBRTC_SOURCE_H_
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace base {
+class UnguessableToken;
+}
+
+namespace media {
+class AudioBus;
+}
+
+namespace blink {
+
+class WebRtcAudioRenderer;
+
+// TODO(xians): Move the following two interfaces to webrtc so that
+// libjingle can own references to the renderer and capturer.
+class PLATFORM_EXPORT WebRtcAudioRendererSource {
+ public:
+ // Callback to get the rendered data.
+ // |audio_bus| must have buffer size |sample_rate/100| and 1-2 channels.
+ virtual void RenderData(media::AudioBus* audio_bus,
+ int sample_rate,
+ int audio_delay_milliseconds,
+ base::TimeDelta* current_time) = 0;
+
+ // Callback to notify the client that the renderer is going away.
+ virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) = 0;
+
+ // Callback to notify the client that the audio renderer thread stopped.
+ // This function must be called only when that thread is actually stopped.
+ // Otherwise a race may occur.
+ virtual void AudioRendererThreadStopped() = 0;
+
+ // Callback to notify the client of the output device the renderer is using.
+ virtual void SetOutputDeviceForAec(const std::string& output_device_id) = 0;
+
+ // Returns the UnguessableToken used to connect this stream to an input stream
+ // for echo cancellation.
+ virtual base::UnguessableToken GetAudioProcessingId() const = 0;
+
+ protected:
+ virtual ~WebRtcAudioRendererSource() {}
+};
+
+// TODO(xians): Merge this interface with WebRtcAudioRendererSource.
+// The reason why we could not do it today is that WebRtcAudioRendererSource
+// gets the data by pulling, while the data is pushed into
+// WebRtcPlayoutDataSource::Sink.
+class PLATFORM_EXPORT WebRtcPlayoutDataSource {
+ public:
+ class Sink {
+ public:
+ // Callback to get the playout data.
+ // Called on the audio render thread.
+ // |audio_bus| must have buffer size |sample_rate/100| and 1-2 channels.
+ virtual void OnPlayoutData(media::AudioBus* audio_bus,
+ int sample_rate,
+ int audio_delay_milliseconds) = 0;
+
+ // Callback to notify the sink that the source has changed.
+ // Called on the main render thread.
+ virtual void OnPlayoutDataSourceChanged() = 0;
+
+ // Called to notify that the audio render thread has changed, and
+ // OnPlayoutData() will from now on be called on the new thread.
+ // Called on the new audio render thread.
+ virtual void OnRenderThreadChanged() = 0;
+
+ protected:
+ virtual ~Sink() {}
+ };
+
+ // Adds/Removes the sink of WebRtcAudioRendererSource to the ADM.
+ // These methods are used by the MediaStreamAudioProcesssor to get the
+ // rendered data for AEC.
+ virtual void AddPlayoutSink(Sink* sink) = 0;
+ virtual void RemovePlayoutSink(Sink* sink) = 0;
+
+ protected:
+ virtual ~WebRtcPlayoutDataSource() {}
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_WEBRTC_SOURCE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
index ae3e47514a1..6e9a1056bfa 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -171,27 +171,6 @@ jumbo_component("wtf") {
"threading_win.cc",
"tree_node.h",
"type_traits.h",
- "typed_arrays/array_buffer.cc",
- "typed_arrays/array_buffer.h",
- "typed_arrays/array_buffer_contents.cc",
- "typed_arrays/array_buffer_contents.h",
- "typed_arrays/array_buffer_view.cc",
- "typed_arrays/array_buffer_view.h",
- "typed_arrays/array_piece.cc",
- "typed_arrays/array_piece.h",
- "typed_arrays/bigint64_array.h",
- "typed_arrays/biguint64_array.h",
- "typed_arrays/float32_array.h",
- "typed_arrays/float64_array.h",
- "typed_arrays/int16_array.h",
- "typed_arrays/int32_array.h",
- "typed_arrays/int8_array.h",
- "typed_arrays/integral_typed_array_base.h",
- "typed_arrays/typed_array_base.h",
- "typed_arrays/uint16_array.h",
- "typed_arrays/uint32_array.h",
- "typed_arrays/uint8_array.h",
- "typed_arrays/uint8_clamped_array.h",
"uuid.cc",
"uuid.h",
"vector.h",
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
index 709c28baa11..af536529a6d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
@@ -156,4 +156,20 @@ inline void* operator new(size_t, NotNullTag, void* location) {
return location;
}
+#if defined(__clang__) && __has_attribute(uninitialized)
+// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
+// the specified variable.
+//
+// -ftrivial-auto-var-init is security risk mitigation feature, so attribute
+// should not be used "just in case", but only to fix real performance
+// bottlenecks when other approaches do not work. In general the compiler is
+// quite effective at eliminating unneeded initializations introduced by the
+// flag, e.g. when they are followed by actual initialization by a program.
+// However if compiler optimization fails and code refactoring is hard, the
+// attribute can be used as a workaround.
+#define STACK_UNINITIALIZED __attribute__((uninitialized))
+#else
+#define STACK_UNINITIALIZED
+#endif
+
#endif /* WTF_Allocator_h */
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
index 30686ea6182..212561bfdd0 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
@@ -27,10 +27,4 @@ char* PartitionAllocator::AllocateVectorBacking<char>(size_t size) {
AllocateBacking(size, "PartitionAllocator::allocateVectorBacking<char>"));
}
-template <>
-char* PartitionAllocator::AllocateExpandedVectorBacking<char>(size_t size) {
- return reinterpret_cast<char*>(AllocateBacking(
- size, "PartitionAllocator::allocateExpandedVectorBacking<char>"));
-}
-
} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
index c1edfc8f00f..143b0584ce5 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
@@ -18,13 +18,8 @@
namespace WTF {
-class PartitionAllocatorDummyVisitor {
- DISALLOW_NEW();
-};
-
class WTF_EXPORT PartitionAllocator {
public:
- typedef PartitionAllocatorDummyVisitor Visitor;
static constexpr bool kIsGarbageCollected = false;
template <typename T>
@@ -42,11 +37,6 @@ class WTF_EXPORT PartitionAllocator {
return reinterpret_cast<T*>(
AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T)));
}
- template <typename T>
- static T* AllocateExpandedVectorBacking(size_t size) {
- return reinterpret_cast<T*>(
- AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T)));
- }
static void FreeVectorBacking(void* address);
static inline bool ExpandVectorBacking(void*, size_t) { return false; }
static inline bool ShrinkVectorBacking(void* address,
@@ -56,20 +46,6 @@ class WTF_EXPORT PartitionAllocator {
// we can skip reallocation.
return quantized_current_size == quantized_shrunk_size;
}
- template <typename T>
- static T* AllocateInlineVectorBacking(size_t size) {
- return AllocateVectorBacking<T>(size);
- }
- static inline void FreeInlineVectorBacking(void* address) {
- FreeVectorBacking(address);
- }
- static inline bool ExpandInlineVectorBacking(void*, size_t) { return false; }
- static inline bool ShrinkInlineVectorBacking(void* address,
- size_t quantized_current_size,
- size_t quantized_shrunk_size) {
- return ShrinkVectorBacking(address, quantized_current_size,
- quantized_shrunk_size);
- }
template <typename T, typename HashTable>
static T* AllocateHashTableBacking(size_t size) {
@@ -102,7 +78,6 @@ class WTF_EXPORT PartitionAllocator {
static void TraceMarkedBackingStore(void*) {}
static void BackingWriteBarrier(void*) {}
- static void BackingWriteBarrier(void*, size_t) {}
template <typename>
static void BackingWriteBarrierForHashTable(void*) {}
@@ -128,9 +103,6 @@ class WTF_EXPORT PartitionAllocator {
// heap.)
template <>
WTF_EXPORT char* PartitionAllocator::AllocateVectorBacking<char>(size_t);
-template <>
-WTF_EXPORT char* PartitionAllocator::AllocateExpandedVectorBacking<char>(
- size_t);
} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/bloom_filter.h b/chromium/third_party/blink/renderer/platform/wtf/bloom_filter.h
index 1a839a2f789..c97ff234fb9 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/bloom_filter.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/bloom_filter.h
@@ -27,7 +27,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BLOOM_FILTER_H_
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace WTF {
@@ -60,20 +59,6 @@ class BloomFilter {
// Otherwise overflowed keys will stick around.
void Clear();
- void Add(const AtomicString& string) { Add(string.Impl()->ExistingHash()); }
- void Add(const String& string) { Add(string.Impl()->GetHash()); }
- void Remove(const AtomicString& string) {
- Remove(string.Impl()->ExistingHash());
- }
- void Remove(const String& string) { Remove(string.Impl()->GetHash()); }
-
- bool MayContain(const AtomicString& string) const {
- return MayContain(string.Impl()->ExistingHash());
- }
- bool MayContain(const String& string) const {
- return MayContain(string.Impl()->GetHash());
- }
-
#if DCHECK_IS_ON()
// Slow.
bool LikelyEmpty() const;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h b/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
index 79f41015d79..7812accbc0b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
@@ -22,14 +22,23 @@ class ConstructTraits {
// Construct a single element that would otherwise be constructed using
// placement new.
template <typename... Args>
+ static T* Construct(void* location, Args&&... args) {
+ return new (NotNull, location) T(std::forward<Args>(args)...);
+ }
+
+ // After constructing elements using memcopy or memmove (or similar)
+ // |NotifyNewElement| needs to be called to propagate that information.
+ static void NotifyNewElement(T* element) {
+ Allocator::template NotifyNewObject<T, Traits>(element);
+ }
+
+ template <typename... Args>
static T* ConstructAndNotifyElement(void* location, Args&&... args) {
- T* object = new (NotNull, location) T(std::forward<Args>(args)...);
- Allocator::template NotifyNewObject<T, Traits>(object);
+ T* object = Construct(location, std::forward<Args>(args)...);
+ NotifyNewElement(object);
return object;
}
- // After constructing elements using memcopy or memmove (or similar)
- // |NotifyNewElements| needs to be called to propagate that information.
static void NotifyNewElements(T* array, size_t len) {
Allocator::template NotifyNewObjects<T, Traits>(array, len);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
index 94209ae764b..51b1575473f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
@@ -51,6 +51,7 @@ class RefCountedThreadSafe;
class TimeDelta;
class TimeTicks;
class Time;
+class UnguessableToken;
} // namespace base
class SkRefCnt;
@@ -149,6 +150,12 @@ struct CrossThreadCopier<base::File> {
};
template <>
+struct CrossThreadCopier<base::UnguessableToken>
+ : public CrossThreadCopierPassThrough<base::UnguessableToken> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
struct CrossThreadCopier<gpu::SyncToken>
: public CrossThreadCopierPassThrough<gpu::SyncToken> {
STATIC_ONLY(CrossThreadCopier);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
index 92706732025..86f58560098 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
@@ -57,7 +57,7 @@ decltype(auto) CoerceFunctorForCrossThreadBind(T&& functor) {
template <typename Signature>
base::RepeatingCallback<Signature> CoerceFunctorForCrossThreadBind(
CrossThreadFunction<Signature>&& functor) {
- return ConvertToBaseCallback(std::move(functor));
+ return ConvertToBaseRepeatingCallback(std::move(functor));
}
template <typename Signature>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/deque.h b/chromium/third_party/blink/renderer/platform/wtf/deque.h
index 4a98ffbe84e..e3e444e701b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/deque.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/deque.h
@@ -691,19 +691,19 @@ Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
if (start_ <= end_) {
for (const T* buffer_entry = buffer_begin + start_; buffer_entry != end;
buffer_entry++) {
- Allocator::template Trace<VisitorDispatcher, T, VectorTraits<T>>(
+ Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
} else {
for (const T* buffer_entry = buffer_begin; buffer_entry != end;
buffer_entry++) {
- Allocator::template Trace<VisitorDispatcher, T, VectorTraits<T>>(
+ Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
const T* buffer_end = buffer_.Buffer() + buffer_.capacity();
for (const T* buffer_entry = buffer_begin + start_;
buffer_entry != buffer_end; buffer_entry++) {
- Allocator::template Trace<VisitorDispatcher, T, VectorTraits<T>>(
+ Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/forward.h b/chromium/third_party/blink/renderer/platform/wtf/forward.h
index 1395b79b0ea..82cbdcbdb49 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/forward.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/forward.h
@@ -39,18 +39,8 @@ template <typename T,
typename Allocator = PartitionAllocator>
class Vector;
-class ArrayBuffer;
-class ArrayBufferView;
-class ArrayPiece;
class AtomicString;
-class BigInt64Array;
-class BigUint64Array;
class CaseMap;
-class Float32Array;
-class Float64Array;
-class Int8Array;
-class Int16Array;
-class Int32Array;
class OrdinalNumber;
class SharedBuffer;
class String;
@@ -59,27 +49,13 @@ class StringImpl;
class StringView;
class TextOffsetMap;
class TextStream;
-class Uint8Array;
-class Uint8ClampedArray;
-class Uint16Array;
-class Uint32Array;
} // namespace WTF
using WTF::Vector;
-using WTF::ArrayBuffer;
-using WTF::ArrayBufferView;
-using WTF::ArrayPiece;
using WTF::AtomicString;
-using WTF::BigInt64Array;
-using WTF::BigUint64Array;
using WTF::CaseMap;
-using WTF::Float32Array;
-using WTF::Float64Array;
-using WTF::Int8Array;
-using WTF::Int16Array;
-using WTF::Int32Array;
using WTF::SharedBuffer;
using WTF::String;
using WTF::StringBuffer;
@@ -87,9 +63,5 @@ using WTF::StringBuilder;
using WTF::StringImpl;
using WTF::StringView;
using WTF::TextOffsetMap;
-using WTF::Uint8Array;
-using WTF::Uint8ClampedArray;
-using WTF::Uint16Array;
-using WTF::Uint32Array;
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_FORWARD_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/functional.h b/chromium/third_party/blink/renderer/platform/wtf/functional.h
index 51a04791af2..8ac7422d441 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/functional.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/functional.h
@@ -314,7 +314,7 @@ class CrossThreadFunction<R(Args...)> {
public:
CrossThreadFunction() = default;
- explicit CrossThreadFunction(base::Callback<R(Args...)> callback)
+ explicit CrossThreadFunction(base::RepeatingCallback<R(Args...)> callback)
: callback_(std::move(callback)) {}
~CrossThreadFunction() = default;
@@ -332,13 +332,13 @@ class CrossThreadFunction<R(Args...)> {
void Reset() { callback_.Reset(); }
explicit operator bool() const { return static_cast<bool>(callback_); }
- friend base::Callback<R(Args...)> ConvertToBaseCallback(
+ friend base::RepeatingCallback<R(Args...)> ConvertToBaseRepeatingCallback(
CrossThreadFunction function) {
return std::move(function.callback_);
}
private:
- base::Callback<R(Args...)> callback_;
+ base::RepeatingCallback<R(Args...)> callback_;
};
template <typename Signature>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
index 52483ec5926..472e2232846 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -23,6 +23,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TABLE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TABLE_H_
+#include <atomic>
#include <memory>
#include "base/numerics/checked_math.h"
@@ -42,7 +43,6 @@
#endif
#if DUMP_HASHTABLE_STATS
-#include <atomic>
#include "third_party/blink/renderer/platform/wtf/threading.h"
#endif
@@ -92,6 +92,13 @@
#endif
#endif
+namespace {
+template <typename T>
+ALWAYS_INLINE std::atomic<T>& AsAtomic(T& t) {
+ return reinterpret_cast<std::atomic<T>&>(t);
+}
+} // namespace
+
namespace WTF {
// This is for tracing inside collections that have special support for weak
@@ -1353,13 +1360,13 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
DCHECK(!IsEmptyOrDeletedBucket(*entry));
// Translate constructs an element so we need to notify using the trait. Avoid
// doing that in the translator so that they can be easily customized.
- ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(entry, 1);
+ ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElement(entry);
++key_count_;
if (ShouldExpand()) {
entry = Expand(entry);
- } else if (Traits::kWeakHandlingFlag == kWeakHandling && ShouldShrink()) {
+ } else if (WTF::IsWeak<ValueType>::value && ShouldShrink()) {
// When weak hash tables are processed by the garbage collector,
// elements with no other strong references to them will have their
// table entries cleared. But no shrinking of the backing store is
@@ -1421,7 +1428,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
DCHECK(!IsEmptyOrDeletedBucket(*entry));
// Translate constructs an element so we need to notify using the trait. Avoid
// doing that in the translator so that they can be easily customized.
- ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(entry, 1);
+ ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElement(entry);
++key_count_;
if (ShouldExpand())
@@ -1786,8 +1793,8 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
stats_->numRehashes.fetch_add(1, std::memory_order_relaxed);
#endif
- table_ = new_table;
- Allocator::template BackingWriteBarrierForHashTable<HashTable>(table_);
+ AsAtomic<ValueType*>(table_).store(new_table, std::memory_order_relaxed);
+ Allocator::template BackingWriteBarrierForHashTable<HashTable>(new_table);
table_size_ = new_table_size;
Value* new_entry = nullptr;
@@ -1805,7 +1812,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
// Rescan the contents of the backing store as no write barriers were emitted
// during re-insertion. Traits::NeedsToForbidGCOnMove ensures that no
// garbage collection is triggered during moving.
- Allocator::TraceMarkedBackingStore(table_);
+ Allocator::TraceMarkedBackingStore(new_table);
deleted_count_ = 0;
@@ -1963,7 +1970,15 @@ void HashTable<Key,
KeyTraits,
Allocator>::swap(HashTable& other) {
DCHECK(!AccessForbidden());
- std::swap(table_, other.table_);
+ // Following 3 lines swap table_ and other.table_ using atomic stores. These
+ // are needed for Oilpan concurrent marking which might trace the hash table
+ // while it is being swapped (i.e. the atomic stores are to avoid a data
+ // race). Atomic reads are not needed here because this method is only called
+ // on the mutator thread, which is also the only one that writes to them, so
+ // there is *no* risk of data races when reading.
+ Value* tmp_table = other.table_;
+ AsAtomic<Value*>(other.table_).store(table_, std::memory_order_relaxed);
+ AsAtomic<Value*>(table_).store(tmp_table, std::memory_order_relaxed);
Allocator::template BackingWriteBarrierForHashTable<HashTable>(table_);
Allocator::template BackingWriteBarrierForHashTable<HashTable>(other.table_);
std::swap(table_size_, other.table_size_);
@@ -2021,27 +2036,9 @@ template <WeakHandlingFlag weakHandlingFlag,
typename Traits,
typename KeyTraits,
typename Allocator>
-struct WeakProcessingHashTableHelper;
-
-template <typename Key,
- typename Value,
- typename Extractor,
- typename HashFunctions,
- typename Traits,
- typename KeyTraits,
- typename Allocator>
-struct WeakProcessingHashTableHelper<kNoWeakHandling,
- Key,
- Value,
- Extractor,
- HashFunctions,
- Traits,
- KeyTraits,
- Allocator> {
+struct WeakProcessingHashTableHelper {
STATIC_ONLY(WeakProcessingHashTableHelper);
- static void Process(typename Allocator::Visitor* visitor, void* closure) {}
- static void EphemeronIteration(typename Allocator::Visitor* visitor,
- void* closure) {}
+ static void Process(const typename Allocator::WeakCallbackInfo&, void*) {}
};
template <typename Key,
@@ -2071,25 +2068,19 @@ struct WeakProcessingHashTableHelper<kWeakHandling,
using ValueType = typename HashTableType::ValueType;
// Used for purely weak and for weak-and-strong tables (ephemerons).
- static void Process(typename Allocator::Visitor* visitor, void* closure) {
- HashTableType* table = reinterpret_cast<HashTableType*>(closure);
+ static void Process(const typename Allocator::WeakCallbackInfo&,
+ void* parameter) {
+ HashTableType* table = reinterpret_cast<HashTableType*>(parameter);
// During incremental marking, the table may be freed after the callback has
// been registered.
if (!table->table_)
return;
- // Only trace the backing store. Its fields will be processed below.
- Allocator::template TraceHashTableBackingOnly<ValueType, HashTableType>(
- visitor, table->table_, &(table->table_));
- // Now perform weak processing (this is a no-op if the backing was
- // accessible through an iterator and was already marked strongly).
+ // Weak processing: If the backing was accessible through an iterator and
+ // thus marked strongly this loop will find all buckets as non-empty.
for (ValueType* element = table->table_ + table->table_size_ - 1;
element >= table->table_; element--) {
if (!HashTableType::IsEmptyOrDeletedBucket(*element)) {
- // At this stage calling trace can make no difference
- // (everything is already traced), but we use the return value
- // to remove things from the collection.
-
if (!TraceInCollectionTrait<kWeakHandling, ValueType, Traits>::IsAlive(
*element)) {
table->RegisterModification();
@@ -2102,26 +2093,6 @@ struct WeakProcessingHashTableHelper<kWeakHandling,
}
}
}
-
- // Called repeatedly for tables that have both weak and strong pointers.
- static void EphemeronIteration(typename Allocator::Visitor* visitor,
- void* closure) {
- HashTableType* table = reinterpret_cast<HashTableType*>(closure);
- // During incremental marking, the table may be freed after the callback has
- // been registered.
- if (!table->table_)
- return;
- // Check the hash table for elements that we now know will not be
- // removed by weak processing. Those elements need to have their strong
- // pointers traced.
- for (ValueType* element = table->table_ + table->table_size_ - 1;
- element >= table->table_; element--) {
- if (!HashTableType::IsEmptyOrDeletedBucket(*element)) {
- TraceInCollectionTrait<kWeakHandling, ValueType, Traits>::Trace(
- visitor, *element);
- }
- }
- }
};
template <typename Key,
@@ -2135,38 +2106,39 @@ template <typename VisitorDispatcher, typename A>
std::enable_if_t<A::kIsGarbageCollected>
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
Trace(VisitorDispatcher visitor) {
- if (Traits::kWeakHandlingFlag == kNoWeakHandling) {
+ static_assert(WTF::IsWeak<ValueType>::value ||
+ IsTraceableInCollectionTrait<Traits>::value,
+ "Value should not be traced");
+ ValueType* table =
+ AsAtomic<ValueType*>(table_).load(std::memory_order_relaxed);
+ if (!WTF::IsWeak<ValueType>::value) {
// Strong HashTable.
- DCHECK(IsTraceableInCollectionTrait<Traits>::value);
Allocator::template TraceHashTableBackingStrongly<ValueType, HashTable>(
- visitor, table_, &table_);
+ visitor, table, &table_);
} else {
// Weak HashTable. The HashTable may be held alive strongly from somewhere
// else, e.g., an iterator.
+ // Only trace the backing store. Its buckets will be processed after
+ // marking. The interesting cases for marking are:
+ // - The backing is dropped using clear(): The backing can still be
+ // compacted but empty/deleted buckets will only be destroyed once the
+ // backing is reclaimed by the garbage collector on the next cycle.
+ // - The hash table expands/shrinks: Buckets are moved to the new backing
+ // store and strongified, resulting in all buckets being alive. The old
+ // backing store is marked but only contains empty/deleted buckets as all
+ // non-empty/deleted buckets have been moved to the new backing store.
+ Allocator::template TraceHashTableBackingOnly<ValueType, HashTable>(
+ visitor, table, &table_);
// Trace the table weakly. For marking this will result in delaying the
// processing until the end of the atomic pause. It is safe to trace
// weakly multiple times.
Allocator::template TraceHashTableBackingWeakly<ValueType, HashTable>(
- visitor, table_, &table_,
- WeakProcessingHashTableHelper<Traits::kWeakHandlingFlag, Key, Value,
- Extractor, HashFunctions, Traits,
+ visitor, table, &table_,
+ WeakProcessingHashTableHelper<WeakHandlingTrait<ValueType>::value, Key,
+ Value, Extractor, HashFunctions, Traits,
KeyTraits, Allocator>::Process,
this);
-
- if (IsTraceableInCollectionTrait<Traits>::value) {
- // Mix of strong and weak fields. We use an approach similar to ephemeron
- // marking to find a fixed point, c.f.:
- // - http://dl.acm.org/citation.cfm?doid=263698.263733
- // - http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak
- // Adding the table for ephemeron marking delays marking any elements in
- // the backing until regular marking is finished.
- Allocator::RegisterWeakTable(
- visitor, this,
- WeakProcessingHashTableHelper<
- Traits::kWeakHandlingFlag, Key, Value, Extractor, HashFunctions,
- Traits, KeyTraits, Allocator>::EphemeronIteration);
- }
}
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h b/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
index bdfe33dcd15..fe2bea5d8d8 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
@@ -86,9 +86,6 @@ struct GenericHashTraitsBase<false, T> {
static const bool value = !std::is_pod<T>::value;
};
- static const WeakHandlingFlag kWeakHandlingFlag =
- IsWeak<T>::value ? kWeakHandling : kNoWeakHandling;
-
static constexpr bool kCanHaveDeletedValue = true;
// The kHasMovingCallback value is only used for HashTable backing stores.
@@ -406,6 +403,10 @@ struct KeyValuePair {
ValueTypeArg value;
};
+template <typename K, typename V>
+struct IsWeak<KeyValuePair<K, V>>
+ : std::integral_constant<bool, IsWeak<K>::value || IsWeak<V>::value> {};
+
template <typename KeyTraitsArg, typename ValueTraitsArg>
struct KeyValuePairHashTraits
: GenericHashTraits<KeyValuePair<typename KeyTraitsArg::TraitType,
@@ -440,12 +441,6 @@ struct KeyValuePairHashTraits
ValueTraits::template NeedsToForbidGCOnMove<>::value;
};
- static const WeakHandlingFlag kWeakHandlingFlag =
- (KeyTraits::kWeakHandlingFlag == kWeakHandling ||
- ValueTraits::kWeakHandlingFlag == kWeakHandling)
- ? kWeakHandling
- : kNoWeakHandling;
-
static const unsigned kMinimumTableSize = KeyTraits::kMinimumTableSize;
static void ConstructDeletedValue(TraitType& slot, bool zero_value) {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
index 1f0e0105d05..9c12afcda68 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -161,6 +161,10 @@ class LinkedHashSetNode : public LinkedHashSetNodeBase {
DISALLOW_COPY_AND_ASSIGN(LinkedHashSetNode);
};
+template <typename T>
+struct IsWeak<LinkedHashSetNode<T>>
+ : std::integral_constant<bool, IsWeak<T>::value> {};
+
template <typename ValueArg,
typename HashFunctions = typename DefaultHash<ValueArg>::Hash,
typename TraitsArg = HashTraits<ValueArg>,
@@ -434,8 +438,6 @@ struct LinkedHashSetTraits
static const bool value =
ValueTraits::template IsTraceableInCollection<>::value;
};
- static const WeakHandlingFlag kWeakHandlingFlag =
- ValueTraits::kWeakHandlingFlag;
static constexpr bool kHasMovingCallback = true;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
index 78bd279a7cb..39fd2a0dfdb 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
@@ -381,8 +381,8 @@ struct ListHashSetAllocator : public PartitionAllocator {
bool InPool(Node* node) { return node >= Pool() && node < PastPool(); }
- static void TraceValue(typename PartitionAllocator::Visitor* visitor,
- Node* node) {}
+ template <typename VisitorDispatcher>
+ static void TraceValue(VisitorDispatcher, Node*) {}
private:
Node* Pool() { return reinterpret_cast_ptr<Node*>(pool_); }
@@ -451,8 +451,8 @@ class ListHashSetNode : public ListHashSetNodeBase<ValueArg> {
allocator->Deallocate(this);
}
- template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ template <typename VisitorDispatcher, typename A = NodeAllocator>
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
// The conservative stack scan can find nodes that have been removed
// from the set and destructed. We don't need to trace these, and it
// would be wrong to do so, because the class will not expect the trace
@@ -1127,7 +1127,7 @@ void ListHashSet<T, inlineCapacity, U, V>::DeleteAllNodes() {
template <typename T, size_t inlineCapacity, typename U, typename V>
template <typename VisitorDispatcher>
void ListHashSet<T, inlineCapacity, U, V>::Trace(VisitorDispatcher visitor) {
- static_assert(HashTraits<T>::kWeakHandlingFlag == kNoWeakHandling,
+ static_assert(!IsWeak<T>::value,
"HeapListHashSet does not support weakness, consider using "
"HeapLinkedHashSet instead.");
// This marks all the nodes and their contents live that can be accessed
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
index 6c96808a5d9..0abbbf7db47 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
index 7378c5385ba..44c6f9219ca 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
@@ -37,16 +37,24 @@ inline const char* GetStringWithTypeName() {
return PRETTY_FUNCTION;
}
+// Specifies whether a type should be treated weakly by the memory management
+// system. Only supported by the garbage collector and not by PartitionAlloc.
+// Requires garbage collection support, so it is only safe to override in sync
+// with changing garbage collection semantics.
template <typename T>
-struct IsWeak {
- static const bool value = false;
-};
+struct IsWeak : std::false_type {};
enum WeakHandlingFlag {
kNoWeakHandling,
kWeakHandling,
};
+template <typename T>
+struct WeakHandlingTrait
+ : std::integral_constant<WeakHandlingFlag,
+ IsWeak<T>::value ? kWeakHandling
+ : kNoWeakHandling> {};
+
template <typename T, typename U>
struct IsSubclass {
private:
@@ -124,41 +132,30 @@ class Visitor;
namespace WTF {
-template <typename T>
-class IsTraceable {
- typedef char YesType;
- typedef struct NoType { char padding[8]; } NoType;
+template <typename T, typename = void>
+struct IsTraceable : std::false_type {
+ // Fail on incomplete types.
+ static_assert(sizeof(T), "incomplete type T");
+};
- // Note that this also checks if a superclass of V has a trace method.
- template <typename V>
- static YesType CheckHasTraceMethod(
- V* v,
- blink::Visitor* p = nullptr,
- typename std::enable_if<
- std::is_same<decltype(v->Trace(p)), void>::value>::type* g = nullptr);
- template <typename V>
- static NoType CheckHasTraceMethod(...);
+// Note: This also checks if a superclass of T has a trace method.
+template <typename T>
+struct IsTraceable<T,
+ base::void_t<decltype(std::declval<T>().Trace(
+ std::declval<blink::Visitor*>()))>> : std::true_type {};
- public:
- // We add sizeof(T) to both sides here, because we want it to fail for
- // incomplete types. Otherwise it just assumes that incomplete types do not
- // have a trace method, which may not be true.
- static const bool value = sizeof(YesType) + sizeof(T) ==
- sizeof(CheckHasTraceMethod<T>(nullptr)) + sizeof(T);
-};
+template <typename T, typename U>
+struct IsTraceable<std::pair<T, U>>
+ : std::integral_constant<bool,
+ IsTraceable<T>::value || IsTraceable<U>::value> {};
// Convenience template wrapping the IsTraceableInCollection template in
// Collection Traits. It helps make the code more readable.
template <typename Traits>
-class IsTraceableInCollectionTrait {
- public:
- static const bool value = Traits::template IsTraceableInCollection<>::value;
-};
-
-template <typename T, typename U>
-struct IsTraceable<std::pair<T, U>> {
- static const bool value = IsTraceable<T>::value || IsTraceable<U>::value;
-};
+struct IsTraceableInCollectionTrait
+ : std::integral_constant<
+ bool,
+ Traits::template IsTraceableInCollection<>::value> {};
// This is used to check that DISALLOW_NEW objects are not
// stored in off-heap Vectors, HashTables etc.
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.cc b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.cc
deleted file mode 100644
index 5bc3bdd6016..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h"
-
-namespace WTF {
-
-bool ArrayBuffer::Transfer(ArrayBufferContents& result) {
- DCHECK(!IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (!contents_.Data()) {
- result.Detach();
- return false;
- }
-
- bool all_views_are_detachable = true;
- for (ArrayBufferView* i = first_view_; i; i = i->next_view_) {
- if (!i->IsDetachable())
- all_views_are_detachable = false;
- }
-
- if (all_views_are_detachable) {
- contents_.Transfer(result);
-
- while (first_view_) {
- ArrayBufferView* current = first_view_;
- RemoveView(current);
- current->Detach();
- }
-
- is_detached_ = true;
- } else {
- // TODO(https://crbug.com/763038): See original bug at
- // https://crbug.com/254728. Copying the buffer instead of transferring is
- // not spec compliant but was added for a WebAudio bug fix. The only time
- // this branch is taken is when attempting to transfer an AudioBuffer's
- // channel data ArrayBuffer.
- contents_.CopyTo(result);
- if (!result.Data())
- return false;
- }
-
- return true;
-}
-
-bool ArrayBuffer::ShareContentsWith(ArrayBufferContents& result) {
- DCHECK(IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (!contents_.DataShared()) {
- result.Detach();
- return false;
- }
-
- contents_.ShareWith(result);
- return true;
-}
-
-bool ArrayBuffer::ShareNonSharedForInternalUse(ArrayBufferContents& result) {
- DCHECK(!IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (!contents_.Data()) {
- result.Detach();
- return false;
- }
-
- contents_.ShareNonSharedForInternalUse(result);
- return true;
-}
-
-void ArrayBuffer::AddView(ArrayBufferView* view) {
- view->buffer_ = this;
- view->prev_view_ = nullptr;
- view->next_view_ = first_view_;
- if (first_view_)
- first_view_->prev_view_ = view;
- first_view_ = view;
-}
-
-void ArrayBuffer::RemoveView(ArrayBufferView* view) {
- DCHECK_EQ(this, view->buffer_.get());
- if (view->next_view_)
- view->next_view_->prev_view_ = view->prev_view_;
- if (view->prev_view_)
- view->prev_view_->next_view_ = view->next_view_;
- if (first_view_ == view)
- first_view_ = view->next_view_;
- view->prev_view_ = view->next_view_ = nullptr;
-}
-
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h
deleted file mode 100644
index 2f97faf9897..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_H_
-
-#include "base/allocator/partition_allocator/oom.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-class ArrayBufferView;
-
-class WTF_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> {
- USING_FAST_MALLOC(ArrayBuffer);
-
- public:
- static inline scoped_refptr<ArrayBuffer> Create(unsigned num_elements,
- unsigned element_byte_size);
- static inline scoped_refptr<ArrayBuffer> Create(ArrayBuffer*);
- static inline scoped_refptr<ArrayBuffer> Create(const void* source,
- size_t byte_length);
- static inline scoped_refptr<ArrayBuffer> Create(ArrayBufferContents&);
-
- static inline scoped_refptr<ArrayBuffer> CreateOrNull(
- unsigned num_elements,
- unsigned element_byte_size);
-
- // Only for use by DOMArrayBuffer::CreateUninitializedOrNull().
- static inline scoped_refptr<ArrayBuffer> CreateUninitializedOrNull(
- unsigned num_elements,
- unsigned element_byte_size);
-
- static inline scoped_refptr<ArrayBuffer> CreateShared(
- unsigned num_elements,
- unsigned element_byte_size);
- static inline scoped_refptr<ArrayBuffer> CreateShared(const void* source,
- unsigned byte_length);
-
- inline void* Data();
- inline const void* Data() const;
- inline void* DataShared();
- inline const void* DataShared() const;
- inline void* DataMaybeShared();
- inline const void* DataMaybeShared() const;
- inline unsigned ByteLength() const;
-
- // Creates a new ArrayBuffer object with copy of bytes in this object
- // ranging from |begin| up to but not including |end|.
- inline scoped_refptr<ArrayBuffer> Slice(unsigned begin, unsigned end) const;
-
- void AddView(ArrayBufferView*);
- void RemoveView(ArrayBufferView*);
-
- bool Transfer(ArrayBufferContents&);
- bool ShareContentsWith(ArrayBufferContents&);
- // Documentation see DOMArrayBuffer.
- bool ShareNonSharedForInternalUse(ArrayBufferContents&);
- bool IsDetached() const { return is_detached_; }
- bool IsShared() const { return contents_.IsShared(); }
-
- ~ArrayBuffer() = default;
-
- protected:
- inline explicit ArrayBuffer(ArrayBufferContents&);
-
- private:
- static inline scoped_refptr<ArrayBuffer> Create(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy);
- static inline scoped_refptr<ArrayBuffer> CreateOrNull(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy);
- static inline scoped_refptr<ArrayBuffer> CreateShared(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy);
-
- inline unsigned ClampIndex(unsigned index) const;
-
- ArrayBufferContents contents_;
- ArrayBufferView* first_view_;
- bool is_detached_;
-};
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(unsigned num_elements,
- unsigned element_byte_size) {
- return Create(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBuffer* other) {
- // TODO(binji): support creating a SharedArrayBuffer by copying another
- // ArrayBuffer?
- DCHECK(!other->IsShared());
- return ArrayBuffer::Create(other->Data(), other->ByteLength());
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source,
- size_t byte_length) {
- ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kNotShared,
- ArrayBufferContents::kDontInitialize);
- if (UNLIKELY(!contents.Data()))
- OOM_CRASH();
- scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
- memcpy(buffer->Data(), source, byte_length);
- return buffer;
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBufferContents& contents) {
- CHECK(contents.DataMaybeShared());
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(
- unsigned num_elements,
- unsigned element_byte_size) {
- return CreateOrNull(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateUninitializedOrNull(
- unsigned num_elements,
- unsigned element_byte_size) {
- return CreateOrNull(num_elements, element_byte_size,
- ArrayBufferContents::kDontInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kNotShared, policy);
- if (UNLIKELY(!contents.Data()))
- OOM_CRASH();
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kNotShared, policy);
- if (!contents.Data())
- return nullptr;
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(
- unsigned num_elements,
- unsigned element_byte_size) {
- return CreateShared(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(const void* source,
- unsigned byte_length) {
- ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared,
- ArrayBufferContents::kDontInitialize);
- CHECK(contents.DataShared());
- scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
- memcpy(buffer->DataShared(), source, byte_length);
- return buffer;
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(
- unsigned num_elements,
- unsigned element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kShared, policy);
- CHECK(contents.DataShared());
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents)
- : first_view_(nullptr), is_detached_(false) {
- if (contents.IsShared())
- contents.ShareWith(contents_);
- else
- contents.Transfer(contents_);
-}
-
-void* ArrayBuffer::Data() {
- return contents_.Data();
-}
-
-const void* ArrayBuffer::Data() const {
- return contents_.Data();
-}
-
-void* ArrayBuffer::DataShared() {
- return contents_.DataShared();
-}
-
-const void* ArrayBuffer::DataShared() const {
- return contents_.DataShared();
-}
-
-void* ArrayBuffer::DataMaybeShared() {
- return contents_.DataMaybeShared();
-}
-
-const void* ArrayBuffer::DataMaybeShared() const {
- return contents_.DataMaybeShared();
-}
-
-unsigned ArrayBuffer::ByteLength() const {
- // TODO(dtapuska): Revisit this cast. ArrayBufferContents
- // uses size_t for storing data. Whereas ArrayBuffer IDL is
- // only uint32_t based.
- return static_cast<unsigned>(contents_.DataLength());
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Slice(unsigned begin,
- unsigned end) const {
- begin = ClampIndex(begin);
- end = ClampIndex(end);
- size_t size = static_cast<size_t>(begin <= end ? end - begin : 0);
- return ArrayBuffer::Create(static_cast<const char*>(Data()) + begin, size);
-}
-
-unsigned ArrayBuffer::ClampIndex(unsigned index) const {
- return index < ByteLength() ? index : ByteLength();
-}
-
-} // namespace WTF
-
-using WTF::ArrayBuffer;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
deleted file mode 100644
index ac76d127b96..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
-
-#include <string.h>
-#include "base/allocator/partition_allocator/partition_alloc.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-
-namespace WTF {
-
-void ArrayBufferContents::DefaultAdjustAmountOfExternalAllocatedMemoryFunction(
- int64_t diff) {
- // Do nothing by default.
-}
-
-ArrayBufferContents::AdjustAmountOfExternalAllocatedMemoryFunction
- ArrayBufferContents::adjust_amount_of_external_allocated_memory_function_ =
- DefaultAdjustAmountOfExternalAllocatedMemoryFunction;
-
-#if DCHECK_IS_ON()
-ArrayBufferContents::AdjustAmountOfExternalAllocatedMemoryFunction
- ArrayBufferContents::
- last_used_adjust_amount_of_external_allocated_memory_function_;
-#endif
-
-ArrayBufferContents::ArrayBufferContents()
- : holder_(base::AdoptRef(new DataHolder())) {}
-
-ArrayBufferContents::ArrayBufferContents(
- size_t num_elements,
- unsigned element_byte_size,
- SharingType is_shared,
- ArrayBufferContents::InitializationPolicy policy)
- : holder_(base::AdoptRef(new DataHolder())) {
- // Do not allow 32-bit overflow of the total size.
- size_t total_size = num_elements * element_byte_size;
- if (num_elements) {
- if (total_size / num_elements != element_byte_size) {
- return;
- }
- }
-
- holder_->AllocateNew(total_size, is_shared, policy);
-}
-
-ArrayBufferContents::ArrayBufferContents(DataHandle data,
- SharingType is_shared)
- : holder_(base::AdoptRef(new DataHolder())) {
- if (data) {
- holder_->Adopt(std::move(data), is_shared);
- } else {
- // Allow null data if size is 0 bytes, make sure data is valid pointer.
- // (PartitionAlloc guarantees valid pointer for size 0)
- holder_->AllocateNew(0, is_shared, kZeroInitialize);
- }
-}
-
-ArrayBufferContents::~ArrayBufferContents() = default;
-
-void ArrayBufferContents::Detach() {
- holder_ = nullptr;
-}
-
-void ArrayBufferContents::Transfer(ArrayBufferContents& other) {
- DCHECK(!IsShared());
- DCHECK(!other.holder_->Data());
- other.holder_ = holder_;
- Detach();
-}
-
-void ArrayBufferContents::ShareWith(ArrayBufferContents& other) {
- DCHECK(IsShared());
- DCHECK(!other.holder_->Data());
- other.holder_ = holder_;
-}
-
-void ArrayBufferContents::ShareNonSharedForInternalUse(
- ArrayBufferContents& other) {
- DCHECK(!IsShared());
- DCHECK(!other.holder_->Data());
- DCHECK(holder_->Data());
- other.holder_ = holder_;
-}
-
-void ArrayBufferContents::CopyTo(ArrayBufferContents& other) {
- DCHECK(!holder_->IsShared() && !other.holder_->IsShared());
- other.holder_->CopyMemoryFrom(*holder_);
-}
-
-void* ArrayBufferContents::AllocateMemoryWithFlags(size_t size,
- InitializationPolicy policy,
- int flags) {
- if (policy == kZeroInitialize) {
- flags |= base::PartitionAllocZeroFill;
- }
- void* data = PartitionAllocGenericFlags(
- Partitions::ArrayBufferPartition(), flags, size,
- WTF_HEAP_PROFILER_TYPE_NAME(ArrayBufferContents));
- return data;
-}
-
-void* ArrayBufferContents::AllocateMemoryOrNull(size_t size,
- InitializationPolicy policy) {
- return AllocateMemoryWithFlags(size, policy, base::PartitionAllocReturnNull);
-}
-
-void ArrayBufferContents::FreeMemory(void* data) {
- Partitions::ArrayBufferPartition()->Free(data);
-}
-
-ArrayBufferContents::DataHandle ArrayBufferContents::CreateDataHandle(
- size_t size,
- InitializationPolicy policy) {
- return DataHandle(
- ArrayBufferContents::AllocateMemoryOrNull(size, policy), size,
- [](void* buffer, size_t, void*) { FreeMemory(buffer); }, nullptr);
-}
-
-ArrayBufferContents::DataHolder::DataHolder()
- : data_(nullptr, 0, [](void*, size_t, void*) {}, nullptr),
- is_shared_(kNotShared),
- has_registered_external_allocation_(false) {}
-
-ArrayBufferContents::DataHolder::~DataHolder() {
- if (has_registered_external_allocation_)
- AdjustAmountOfExternalAllocatedMemory(-static_cast<int64_t>(DataLength()));
-
- is_shared_ = kNotShared;
-}
-
-void ArrayBufferContents::DataHolder::AllocateNew(size_t length,
- SharingType is_shared,
- InitializationPolicy policy) {
- DCHECK(!data_);
- DCHECK(!has_registered_external_allocation_);
-
- data_ = CreateDataHandle(length, policy);
- if (!data_)
- return;
-
- is_shared_ = is_shared;
-
- RegisterExternalAllocationWithCurrentContext();
-}
-
-void ArrayBufferContents::DataHolder::Adopt(DataHandle data,
- SharingType is_shared) {
- DCHECK(!data_);
- DCHECK(!has_registered_external_allocation_);
-
- data_ = std::move(data);
- is_shared_ = is_shared;
-
- RegisterExternalAllocationWithCurrentContext();
-}
-
-void ArrayBufferContents::DataHolder::CopyMemoryFrom(const DataHolder& source) {
- DCHECK(!data_);
- DCHECK(!has_registered_external_allocation_);
-
- data_ = CreateDataHandle(source.DataLength(), kDontInitialize);
- if (!data_)
- return;
-
- memcpy(data_.Data(), source.Data(), source.DataLength());
-
- RegisterExternalAllocationWithCurrentContext();
-}
-
-void ArrayBufferContents::DataHolder::
- RegisterExternalAllocationWithCurrentContext() {
- DCHECK(!has_registered_external_allocation_);
- // Currently, we can only track an allocation if we have a single owner. For
- // shared data this is not true, hence do not attempt to track at all.
- // TODO(crbug.com/877055) Implement tracking of shared external allocations.
- if (IsShared())
- return;
- AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(DataLength()));
-}
-
-void ArrayBufferContents::DataHolder::
- UnregisterExternalAllocationWithCurrentContext() {
- if (!has_registered_external_allocation_)
- return;
- DCHECK(!IsShared());
- AdjustAmountOfExternalAllocatedMemory(-static_cast<int64_t>(DataLength()));
-}
-
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
deleted file mode 100644
index 4b398f937d1..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_CONTENTS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_CONTENTS_H_
-
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/wtf.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
-
-namespace WTF {
-
-class WTF_EXPORT ArrayBufferContents {
- DISALLOW_NEW();
-
- public:
- using AdjustAmountOfExternalAllocatedMemoryFunction = void (*)(int64_t diff);
- // Types that need to be used when injecting external memory.
- // DataHandle allows specifying a deleter which will be invoked when
- // DataHandle instance goes out of scope. If the data memory is allocated
- // using ArrayBufferContents::AllocateMemoryOrNull, it is necessary to specify
- // ArrayBufferContents::FreeMemory as the DataDeleter. Most clients would want
- // to use ArrayBufferContents::CreateDataHandle, which allocates memory and
- // specifies the correct deleter.
- using DataDeleter = void (*)(void* data, size_t length, void* info);
-
- class DataHandle {
- DISALLOW_COPY_AND_ASSIGN(DataHandle);
-
- public:
- DataHandle() {}
-
- DataHandle(void* data,
- size_t length,
- DataDeleter deleter,
- void* deleter_info)
- : data_(data),
- data_length_(data ? length : 0),
- deleter_(deleter),
- deleter_info_(deleter_info) {}
- // Move constructor
- DataHandle(DataHandle&& other) { *this = std::move(other); }
- ~DataHandle() {
- if (!data_)
- return;
- deleter_(data_, data_length_, deleter_info_);
- }
-
- // Move operator
- DataHandle& operator=(DataHandle&& other) {
- if (data_)
- deleter_(data_, data_length_, deleter_info_);
- data_ = other.data_;
- data_length_ = other.data_length_;
- deleter_ = other.deleter_;
- deleter_info_ = other.deleter_info_;
- other.data_ = nullptr;
- return *this;
- }
-
- void reset() { *this = DataHandle(); }
-
- void* Data() const { return data_; }
- size_t DataLength() const { return data_length_; }
-
- operator bool() const { return data_; }
-
- private:
- void* data_ = nullptr;
- size_t data_length_ = 0;
-
- DataDeleter deleter_ = nullptr;
- void* deleter_info_ = nullptr;
- };
-
- enum InitializationPolicy { kZeroInitialize, kDontInitialize };
-
- enum SharingType {
- kNotShared,
- kShared,
- };
-
- ArrayBufferContents();
- ArrayBufferContents(size_t num_elements,
- unsigned element_byte_size,
- SharingType is_shared,
- InitializationPolicy);
- ArrayBufferContents(DataHandle,
- SharingType is_shared);
- ArrayBufferContents(ArrayBufferContents&&) = default;
-
- ~ArrayBufferContents();
-
- ArrayBufferContents& operator=(ArrayBufferContents&&) = default;
-
- void Detach();
-
- void* Data() const {
- DCHECK(!IsShared());
- return DataMaybeShared();
- }
- void* DataShared() const {
- DCHECK(IsShared());
- return DataMaybeShared();
- }
- void* DataMaybeShared() const { return holder_ ? holder_->Data() : nullptr; }
- size_t DataLength() const { return holder_ ? holder_->DataLength() : 0; }
- bool IsShared() const { return holder_ ? holder_->IsShared() : false; }
-
- void Transfer(ArrayBufferContents& other);
- void ShareWith(ArrayBufferContents& other);
- void ShareNonSharedForInternalUse(ArrayBufferContents& other);
- void CopyTo(ArrayBufferContents& other);
-
- static void* AllocateMemoryOrNull(size_t, InitializationPolicy);
- static void FreeMemory(void*);
- static DataHandle CreateDataHandle(size_t, InitializationPolicy);
- static void Initialize(
- AdjustAmountOfExternalAllocatedMemoryFunction function) {
- DCHECK(IsMainThread());
- DCHECK_EQ(adjust_amount_of_external_allocated_memory_function_,
- DefaultAdjustAmountOfExternalAllocatedMemoryFunction);
- adjust_amount_of_external_allocated_memory_function_ = function;
- }
-
- void RegisterExternalAllocationWithCurrentContext() {
- if (holder_)
- holder_->RegisterExternalAllocationWithCurrentContext();
- }
-
- void UnregisterExternalAllocationWithCurrentContext() {
- if (holder_)
- holder_->UnregisterExternalAllocationWithCurrentContext();
- }
-
- private:
- static void* AllocateMemoryWithFlags(size_t, InitializationPolicy, int);
-
- static void DefaultAdjustAmountOfExternalAllocatedMemoryFunction(
- int64_t diff);
-
- class WTF_EXPORT DataHolder : public ThreadSafeRefCounted<DataHolder> {
- DISALLOW_COPY_AND_ASSIGN(DataHolder);
-
- public:
- DataHolder();
- ~DataHolder();
-
- void AllocateNew(size_t length,
- SharingType is_shared,
- InitializationPolicy);
- void Adopt(DataHandle, SharingType is_shared);
- void CopyMemoryFrom(const DataHolder& source);
-
- const void* Data() const { return data_.Data(); }
- void* Data() { return data_.Data(); }
- size_t DataLength() const { return data_.DataLength(); }
- bool IsShared() const { return is_shared_ == kShared; }
-
- void RegisterExternalAllocationWithCurrentContext();
- void UnregisterExternalAllocationWithCurrentContext();
-
- private:
- void AdjustAmountOfExternalAllocatedMemory(int64_t diff) {
- has_registered_external_allocation_ =
- !has_registered_external_allocation_;
- DCHECK(!diff || (has_registered_external_allocation_ == (diff > 0)));
- CheckIfAdjustAmountOfExternalAllocatedMemoryIsConsistent();
- adjust_amount_of_external_allocated_memory_function_(diff);
- }
-
- void AdjustAmountOfExternalAllocatedMemory(size_t diff) {
- AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(diff));
- }
-
- void CheckIfAdjustAmountOfExternalAllocatedMemoryIsConsistent() {
- DCHECK(adjust_amount_of_external_allocated_memory_function_);
-
-#if DCHECK_IS_ON()
- // Make sure that the function actually used is always the same.
- // Shouldn't be updated during its use.
- if (!last_used_adjust_amount_of_external_allocated_memory_function_) {
- last_used_adjust_amount_of_external_allocated_memory_function_ =
- adjust_amount_of_external_allocated_memory_function_;
- }
- DCHECK_EQ(adjust_amount_of_external_allocated_memory_function_,
- last_used_adjust_amount_of_external_allocated_memory_function_);
-#endif
- }
-
- DataHandle data_;
- SharingType is_shared_;
- bool has_registered_external_allocation_;
- };
-
- scoped_refptr<DataHolder> holder_;
- static AdjustAmountOfExternalAllocatedMemoryFunction
- adjust_amount_of_external_allocated_memory_function_;
-#if DCHECK_IS_ON()
- static AdjustAmountOfExternalAllocatedMemoryFunction
- last_used_adjust_amount_of_external_allocated_memory_function_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(ArrayBufferContents);
-};
-
-template <>
-struct CrossThreadCopier<ArrayBufferContents::DataHandle> {
- STATIC_ONLY(CrossThreadCopier);
- using Type = ArrayBufferContents::DataHandle;
- static Type Copy(Type handle) {
- return handle; // This is in fact a move.
- }
-};
-
-} // namespace WTF
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_CONTENTS_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.cc b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.cc
deleted file mode 100644
index 1daa4ef9b57..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h"
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-
-namespace WTF {
-
-ArrayBufferView::ArrayBufferView(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset)
- : byte_offset_(byte_offset),
- is_detachable_(true),
- buffer_(std::move(buffer)),
- prev_view_(nullptr),
- next_view_(nullptr) {
- base_address_ =
- buffer_ ? (static_cast<char*>(buffer_->DataMaybeShared()) + byte_offset_)
- : nullptr;
- if (buffer_)
- buffer_->AddView(this);
-}
-
-ArrayBufferView::~ArrayBufferView() {
- if (buffer_)
- buffer_->RemoveView(this);
-}
-
-void ArrayBufferView::Detach() {
- buffer_ = nullptr;
- base_address_ = nullptr;
- byte_offset_ = 0;
-}
-
-const char* ArrayBufferView::TypeName() {
- switch (GetType()) {
- case kTypeInt8:
- return "Int8";
- break;
- case kTypeUint8:
- return "UInt8";
- break;
- case kTypeUint8Clamped:
- return "UInt8Clamped";
- break;
- case kTypeInt16:
- return "Int16";
- break;
- case kTypeUint16:
- return "UInt16";
- break;
- case kTypeInt32:
- return "Int32";
- break;
- case kTypeUint32:
- return "Uint32";
- break;
- case kTypeBigInt64:
- return "BigInt64";
- break;
- case kTypeBigUint64:
- return "BigUint64";
- break;
- case kTypeFloat32:
- return "Float32";
- break;
- case kTypeFloat64:
- return "Float64";
- break;
- case kTypeDataView:
- return "DataView";
- break;
- }
- NOTREACHED();
- return "Unknown";
-}
-
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h
deleted file mode 100644
index bf595280c9b..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_VIEW_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_VIEW_H_
-
-#include <limits.h>
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
-
-namespace WTF {
-
-class WTF_EXPORT ArrayBufferView : public RefCounted<ArrayBufferView> {
- USING_FAST_MALLOC(ArrayBuffer);
-
- public:
- enum ViewType {
- kTypeInt8,
- kTypeUint8,
- kTypeUint8Clamped,
- kTypeInt16,
- kTypeUint16,
- kTypeInt32,
- kTypeUint32,
- kTypeFloat32,
- kTypeFloat64,
- kTypeBigInt64,
- kTypeBigUint64,
- kTypeDataView
- };
- virtual ViewType GetType() const = 0;
- const char* TypeName();
-
- ArrayBuffer* Buffer() const { return buffer_.get(); }
-
- void* BaseAddress() const {
- DCHECK(!IsShared());
- return base_address_;
- }
- void* BaseAddressMaybeShared() const { return base_address_; }
-
- unsigned ByteOffset() const { return byte_offset_; }
-
- virtual unsigned ByteLength() const = 0;
- virtual unsigned TypeSize() const = 0;
-
- void SetDetachable(bool flag) { is_detachable_ = flag; }
- bool IsDetachable() const { return is_detachable_; }
- bool IsShared() const { return buffer_ ? buffer_->IsShared() : false; }
-
- virtual ~ArrayBufferView();
-
- protected:
- ArrayBufferView(scoped_refptr<ArrayBuffer>, unsigned byte_offset);
-
- inline bool SetImpl(ArrayBufferView*, unsigned byte_offset);
-
- // Helper to verify that a given sub-range of an ArrayBuffer is
- // within range.
- template <typename T>
- static bool VerifySubRange(const ArrayBuffer* buffer,
- unsigned byte_offset,
- unsigned num_elements) {
- if (!buffer)
- return false;
- if (sizeof(T) > 1 && byte_offset % sizeof(T))
- return false;
- if (byte_offset > buffer->ByteLength())
- return false;
- unsigned remaining_elements =
- static_cast<unsigned>((buffer->ByteLength() - byte_offset) / sizeof(T));
- if (num_elements > remaining_elements)
- return false;
- return true;
- }
-
- virtual void Detach();
-
- // This is the address of the ArrayBuffer's storage, plus the byte offset.
- void* base_address_;
-
- unsigned byte_offset_ : 31;
- unsigned is_detachable_ : 1;
-
- private:
- friend class ArrayBuffer;
- scoped_refptr<ArrayBuffer> buffer_;
- ArrayBufferView* prev_view_;
- ArrayBufferView* next_view_;
-};
-
-bool ArrayBufferView::SetImpl(ArrayBufferView* array, unsigned byte_offset) {
- if (byte_offset > ByteLength() ||
- byte_offset + array->ByteLength() > ByteLength() ||
- byte_offset + array->ByteLength() < byte_offset) {
- // Out of range offset or overflow
- return false;
- }
-
- char* base = static_cast<char*>(BaseAddress());
- memmove(base + byte_offset, array->BaseAddress(), array->ByteLength());
- return true;
-}
-
-} // namespace WTF
-
-using WTF::ArrayBufferView;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_BUFFER_VIEW_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.cc b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.cc
deleted file mode 100644
index 795f578214a..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.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 "third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.h"
-
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h"
-
-namespace WTF {
-
-ArrayPiece::ArrayPiece() {
- InitNull();
-}
-
-ArrayPiece::ArrayPiece(ArrayBuffer* buffer) {
- InitWithArrayBuffer(buffer);
-}
-
-ArrayPiece::ArrayPiece(ArrayBufferView* buffer) {
- InitWithArrayBufferView(buffer);
-}
-
-bool ArrayPiece::IsNull() const {
- return is_null_;
-}
-
-bool ArrayPiece::IsDetached() const {
- return is_detached_;
-}
-
-void* ArrayPiece::Data() const {
- DCHECK(!IsNull());
- return data_;
-}
-
-unsigned char* ArrayPiece::Bytes() const {
- return static_cast<unsigned char*>(Data());
-}
-
-unsigned ArrayPiece::ByteLength() const {
- DCHECK(!IsNull());
- return byte_length_;
-}
-
-void ArrayPiece::InitWithArrayBuffer(ArrayBuffer* buffer) {
- if (buffer) {
- InitWithData(buffer->Data(), SafeCast<unsigned>(buffer->ByteLength()));
- is_detached_ = buffer->IsDetached();
- } else {
- InitNull();
- }
-}
-
-void ArrayPiece::InitWithArrayBufferView(ArrayBufferView* buffer) {
- if (buffer) {
- InitWithData(buffer->BaseAddress(), buffer->ByteLength());
- is_detached_ = buffer->Buffer() ? buffer->Buffer()->IsDetached() : true;
- } else {
- InitNull();
- }
-}
-
-void ArrayPiece::InitWithData(void* data, unsigned byte_length) {
- byte_length_ = byte_length;
- data_ = data;
- is_null_ = false;
- is_detached_ = false;
-}
-
-void ArrayPiece::InitNull() {
- byte_length_ = 0;
- data_ = nullptr;
- is_null_ = true;
- is_detached_ = false;
-}
-
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.h
deleted file mode 100644
index dd77748ea4c..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_piece.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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_PIECE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_PIECE_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
-
-namespace WTF {
-
-// This class is for passing around un-owned bytes as a pointer + length.
-// It supports implicit conversion from several other data types.
-//
-// ArrayPiece has the concept of being "null". This is different from an empty
-// byte range. It is invalid to call methods other than isNull() on such
-// instances.
-//
-// IMPORTANT: The data contained by ArrayPiece is NOT OWNED, so caution must be
-// taken to ensure it is kept alive.
-class WTF_EXPORT ArrayPiece {
- DISALLOW_NEW();
-
- public:
- // Constructs a "null" ArrayPiece object.
- ArrayPiece();
-
- // Constructs an ArrayPiece from the given ArrayBuffer. If the input is a
- // nullptr, then the constructed instance will be isNull().
- ArrayPiece(ArrayBuffer*);
- ArrayPiece(ArrayBufferView*);
-
- bool IsNull() const;
- bool IsDetached() const;
- void* Data() const;
- unsigned char* Bytes() const;
- unsigned ByteLength() const;
-
- protected:
- void InitWithArrayBuffer(ArrayBuffer*);
- void InitWithArrayBufferView(ArrayBufferView*);
- void InitWithData(void* data, unsigned byte_length);
-
- private:
- void InitNull();
-
- void* data_;
- unsigned byte_length_;
- bool is_null_;
- bool is_detached_;
-};
-
-} // namespace WTF
-
-using WTF::ArrayPiece;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_ARRAY_PIECE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/bigint64_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/bigint64_array.h
deleted file mode 100644
index 07a52592e1d..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/bigint64_array.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGINT64_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGINT64_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h"
-
-namespace WTF {
-
-class BigInt64Array final : public TypedArrayBase<int64_t> {
- public:
- static inline scoped_refptr<BigInt64Array> Create(unsigned length);
- static inline scoped_refptr<BigInt64Array> Create(const int64_t* array,
- unsigned length);
- static inline scoped_refptr<BigInt64Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- // Should only be used when it is known the entire array will be filled. Do
- // not return these results directly to JavaScript without filling first.
- static inline scoped_refptr<BigInt64Array> CreateUninitialized(
- unsigned length);
-
- using TypedArrayBase<int64_t>::Set;
-
- void Set(unsigned index, int64_t value) {
- if (index >= TypedArrayBase<int64_t>::length_)
- return;
- TypedArrayBase<int64_t>::Data()[index] = value;
- }
-
- ViewType GetType() const override { return kTypeBigInt64; }
-
- private:
- inline BigInt64Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<int64_t>;
-};
-
-scoped_refptr<BigInt64Array> BigInt64Array::Create(unsigned length) {
- return TypedArrayBase<int64_t>::Create<BigInt64Array>(length);
-}
-
-scoped_refptr<BigInt64Array> BigInt64Array::Create(const int64_t* array,
- unsigned length) {
- return TypedArrayBase<int64_t>::Create<BigInt64Array>(array, length);
-}
-
-scoped_refptr<BigInt64Array> BigInt64Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<int64_t>::Create<BigInt64Array>(std::move(buffer),
- byte_offset, length);
-}
-
-BigInt64Array::BigInt64Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : TypedArrayBase<int64_t>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::BigInt64Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGINT64_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/biguint64_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/biguint64_array.h
deleted file mode 100644
index d6a1861fdde..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/biguint64_array.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGUINT64_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGUINT64_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h"
-
-namespace WTF {
-
-class BigUint64Array final : public TypedArrayBase<uint64_t> {
- public:
- static inline scoped_refptr<BigUint64Array> Create(unsigned length);
- static inline scoped_refptr<BigUint64Array> Create(const uint64_t* array,
- unsigned length);
- static inline scoped_refptr<BigUint64Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- // Should only be used when it is known the entire array will be filled. Do
- // not return these results directly to JavaScript without filling first.
- static inline scoped_refptr<BigUint64Array> CreateUninitialized(
- unsigned length);
-
- using TypedArrayBase<uint64_t>::Set;
-
- void Set(unsigned index, uint64_t value) {
- if (index >= TypedArrayBase<uint64_t>::length_)
- return;
- TypedArrayBase<uint64_t>::Data()[index] = value;
- }
-
- ViewType GetType() const override { return kTypeBigUint64; }
-
- private:
- inline BigUint64Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<uint64_t>;
-};
-
-scoped_refptr<BigUint64Array> BigUint64Array::Create(unsigned length) {
- return TypedArrayBase<uint64_t>::Create<BigUint64Array>(length);
-}
-
-scoped_refptr<BigUint64Array> BigUint64Array::Create(const uint64_t* array,
- unsigned length) {
- return TypedArrayBase<uint64_t>::Create<BigUint64Array>(array, length);
-}
-
-scoped_refptr<BigUint64Array> BigUint64Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<uint64_t>::Create<BigUint64Array>(std::move(buffer),
- byte_offset, length);
-}
-
-BigUint64Array::BigUint64Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : TypedArrayBase<uint64_t>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::BigUint64Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_BIGUINT64_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float32_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float32_array.h
deleted file mode 100644
index b31717b0c8a..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float32_array.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT32_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT32_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h"
-
-namespace WTF {
-
-class Float32Array final : public TypedArrayBase<float> {
- public:
- static inline scoped_refptr<Float32Array> Create(unsigned length);
- static inline scoped_refptr<Float32Array> Create(const float* array,
- unsigned length);
- static inline scoped_refptr<Float32Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- static inline scoped_refptr<Float32Array> CreateOrNull(unsigned length);
- static inline scoped_refptr<Float32Array> CreateUninitializedOrNull(
- unsigned length);
-
- using TypedArrayBase<float>::Set;
-
- void Set(unsigned index, double value) {
- if (index >= TypedArrayBase<float>::length_)
- return;
- TypedArrayBase<float>::Data()[index] = static_cast<float>(value);
- }
-
- ViewType GetType() const override { return kTypeFloat32; }
-
- private:
- inline Float32Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<float>;
-};
-
-scoped_refptr<Float32Array> Float32Array::Create(unsigned length) {
- return TypedArrayBase<float>::Create<Float32Array>(length);
-}
-
-scoped_refptr<Float32Array> Float32Array::Create(const float* array,
- unsigned length) {
- return TypedArrayBase<float>::Create<Float32Array>(array, length);
-}
-
-scoped_refptr<Float32Array> Float32Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<float>::Create<Float32Array>(std::move(buffer),
- byte_offset, length);
-}
-
-scoped_refptr<Float32Array> Float32Array::CreateOrNull(unsigned length) {
- return TypedArrayBase<float>::CreateOrNull<Float32Array>(length);
-}
-
-scoped_refptr<Float32Array> Float32Array::CreateUninitializedOrNull(
- unsigned length) {
- return TypedArrayBase<float>::CreateUninitializedOrNull<Float32Array>(length);
-}
-
-Float32Array::Float32Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : TypedArrayBase<float>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::Float32Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT32_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float64_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float64_array.h
deleted file mode 100644
index 94d8e3452fb..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/float64_array.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT64_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT64_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h"
-
-namespace WTF {
-
-class Float64Array final : public TypedArrayBase<double> {
- public:
- static inline scoped_refptr<Float64Array> Create(unsigned length);
- static inline scoped_refptr<Float64Array> Create(const double* array,
- unsigned length);
- static inline scoped_refptr<Float64Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- // Should only be used when it is known the entire array will be filled. Do
- // not return these results directly to JavaScript without filling first.
- static inline scoped_refptr<Float64Array> CreateUninitialized(
- unsigned length);
-
- using TypedArrayBase<double>::Set;
-
- void Set(unsigned index, double value) {
- if (index >= TypedArrayBase<double>::length_)
- return;
- TypedArrayBase<double>::Data()[index] = static_cast<double>(value);
- }
-
- ViewType GetType() const override { return kTypeFloat64; }
-
- private:
- inline Float64Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<double>;
-};
-
-scoped_refptr<Float64Array> Float64Array::Create(unsigned length) {
- return TypedArrayBase<double>::Create<Float64Array>(length);
-}
-
-scoped_refptr<Float64Array> Float64Array::Create(const double* array,
- unsigned length) {
- return TypedArrayBase<double>::Create<Float64Array>(array, length);
-}
-
-scoped_refptr<Float64Array> Float64Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<double>::Create<Float64Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Float64Array::Float64Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : TypedArrayBase<double>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::Float64Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_FLOAT64_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int16_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int16_array.h
deleted file mode 100644
index 4bafdd055b1..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int16_array.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT16_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT16_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-
-class Int16Array final : public IntegralTypedArrayBase<int16_t> {
- public:
- static inline scoped_refptr<Int16Array> Create(unsigned length);
- static inline scoped_refptr<Int16Array> Create(const int16_t* array,
- unsigned length);
- static inline scoped_refptr<Int16Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<int16_t>::Set;
- using IntegralTypedArrayBase<int16_t>::Set;
-
- ViewType GetType() const override { return kTypeInt16; }
-
- private:
- inline Int16Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<int16_t>;
-};
-
-scoped_refptr<Int16Array> Int16Array::Create(unsigned length) {
- return TypedArrayBase<int16_t>::Create<Int16Array>(length);
-}
-
-scoped_refptr<Int16Array> Int16Array::Create(const int16_t* array,
- unsigned length) {
- return TypedArrayBase<int16_t>::Create<Int16Array>(array, length);
-}
-
-scoped_refptr<Int16Array> Int16Array::Create(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<int16_t>::Create<Int16Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Int16Array::Int16Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<int16_t>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::Int16Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT16_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int32_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int32_array.h
deleted file mode 100644
index 12497813d40..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int32_array.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT32_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT32_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class Int32Array final : public IntegralTypedArrayBase<int> {
- public:
- static inline scoped_refptr<Int32Array> Create(unsigned length);
- static inline scoped_refptr<Int32Array> Create(const int* array,
- unsigned length);
- static inline scoped_refptr<Int32Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<int>::Set;
- using IntegralTypedArrayBase<int>::Set;
-
- ViewType GetType() const override { return kTypeInt32; }
-
- private:
- inline Int32Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<int>;
-};
-
-scoped_refptr<Int32Array> Int32Array::Create(unsigned length) {
- return TypedArrayBase<int>::Create<Int32Array>(length);
-}
-
-scoped_refptr<Int32Array> Int32Array::Create(const int* array,
- unsigned length) {
- return TypedArrayBase<int>::Create<Int32Array>(array, length);
-}
-
-scoped_refptr<Int32Array> Int32Array::Create(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<int>::Create<Int32Array>(std::move(buffer), byte_offset,
- length);
-}
-
-Int32Array::Int32Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<int>(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::Int32Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT32_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int8_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int8_array.h
deleted file mode 100644
index 35d35dee6ea..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/int8_array.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT8_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT8_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-
-class Int8Array final : public IntegralTypedArrayBase<signed char> {
- public:
- static inline scoped_refptr<Int8Array> Create(unsigned length);
- static inline scoped_refptr<Int8Array> Create(const signed char* array,
- unsigned length);
- static inline scoped_refptr<Int8Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<signed char>::Set;
- using IntegralTypedArrayBase<signed char>::Set;
-
- ViewType GetType() const override { return kTypeInt8; }
-
- private:
- inline Int8Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<signed char>;
-};
-
-scoped_refptr<Int8Array> Int8Array::Create(unsigned length) {
- return TypedArrayBase<signed char>::Create<Int8Array>(length);
-}
-
-scoped_refptr<Int8Array> Int8Array::Create(const signed char* array,
- unsigned length) {
- return TypedArrayBase<signed char>::Create<Int8Array>(array, length);
-}
-
-scoped_refptr<Int8Array> Int8Array::Create(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<signed char>::Create<Int8Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Int8Array::Int8Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<signed char>(std::move(buffer),
- byte_offset,
- length) {}
-
-} // namespace WTF
-
-using WTF::Int8Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INT8_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h
deleted file mode 100644
index 65075ec98af..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (c) 2010, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INTEGRAL_TYPED_ARRAY_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INTEGRAL_TYPED_ARRAY_BASE_H_
-
-#include <limits>
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h"
-
-namespace WTF {
-
-// Base class for all WebGL<T>Array types holding integral
-// (non-floating-point) values.
-template <typename T>
-class IntegralTypedArrayBase : public TypedArrayBase<T> {
- public:
- void Set(unsigned index, double value) {
- if (index >= TypedArrayBase<T>::length_)
- return;
- if (std::isnan(value)) // Clamp NaN to 0
- value = 0;
- // The double cast is necessary to get the correct wrapping
- // for out-of-range values with Int32Array and Uint32Array.
- TypedArrayBase<T>::Data()[index] =
- static_cast<T>(static_cast<int64_t>(value));
- }
-
- protected:
- IntegralTypedArrayBase(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : TypedArrayBase<T>(std::move(buffer), byte_offset, length) {}
-};
-
-} // namespace WTF
-
-using WTF::IntegralTypedArrayBase;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_INTEGRAL_TYPED_ARRAY_BASE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h
deleted file mode 100644
index dd7308df040..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/typed_array_base.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (c) 2010, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_TYPED_ARRAY_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_TYPED_ARRAY_BASE_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h"
-
-namespace WTF {
-
-template <typename T>
-class TypedArrayBase : public ArrayBufferView {
- public:
- typedef T ValueType;
-
- T* Data() const { return static_cast<T*>(BaseAddress()); }
- T* DataMaybeShared() const {
- return static_cast<T*>(BaseAddressMaybeShared());
- }
-
- bool Set(TypedArrayBase<T>* array, unsigned offset) {
- return SetImpl(array, offset * sizeof(T));
- }
-
- // Overridden from ArrayBufferView. This must be public because of
- // rules about inheritance of members in template classes, and
- // because it is accessed via pointers to subclasses.
- unsigned length() const { return length_; }
-
- unsigned ByteLength() const final { return length_ * sizeof(T); }
-
- unsigned TypeSize() const final { return sizeof(T); }
-
- // Invoked by the indexed getter. Does not perform range checks; caller
- // is responsible for doing so and returning undefined as necessary.
- T Item(unsigned index) const {
- SECURITY_DCHECK(index < TypedArrayBase<T>::length_);
- return TypedArrayBase<T>::Data()[index];
- }
-
- protected:
- TypedArrayBase(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : ArrayBufferView(std::move(buffer), byte_offset), length_(length) {}
-
- template <class Subclass>
- static scoped_refptr<Subclass> Create(unsigned length) {
- scoped_refptr<ArrayBuffer> buffer = ArrayBuffer::Create(length, sizeof(T));
- return Create<Subclass>(std::move(buffer), 0, length);
- }
-
- template <class Subclass>
- static scoped_refptr<Subclass> Create(const T* array, unsigned length) {
- scoped_refptr<Subclass> a = Create<Subclass>(length);
- if (a)
- for (unsigned i = 0; i < length; ++i)
- a->Set(i, array[i]);
- return a;
- }
-
- template <class Subclass>
- static scoped_refptr<Subclass> Create(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- CHECK(VerifySubRange<T>(buffer.get(), byte_offset, length));
- return base::AdoptRef(new Subclass(std::move(buffer), byte_offset, length));
- }
-
- template <class Subclass>
- static scoped_refptr<Subclass> CreateOrNull(unsigned length) {
- scoped_refptr<ArrayBuffer> buffer =
- ArrayBuffer::CreateOrNull(length, sizeof(T));
- if (!buffer)
- return nullptr;
- return Create<Subclass>(std::move(buffer), 0, length);
- }
-
- template <class Subclass>
- static scoped_refptr<Subclass> CreateUninitializedOrNull(unsigned length) {
- scoped_refptr<ArrayBuffer> buffer =
- ArrayBuffer::CreateUninitializedOrNull(length, sizeof(T));
- if (!buffer)
- return nullptr;
- return Create<Subclass>(std::move(buffer), 0, length);
- }
-
- void Detach() final {
- ArrayBufferView::Detach();
- length_ = 0;
- }
-
- // We do not want to have to access this via a virtual function in subclasses,
- // which is why it is protected rather than private.
- unsigned length_;
-};
-
-} // namespace WTF
-
-using WTF::TypedArrayBase;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_TYPED_ARRAY_BASE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint16_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint16_array.h
deleted file mode 100644
index fd1837e6816..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint16_array.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT16_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT16_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-
-class Uint16Array final : public IntegralTypedArrayBase<uint16_t> {
- public:
- static inline scoped_refptr<Uint16Array> Create(unsigned length);
- static inline scoped_refptr<Uint16Array> Create(const uint16_t* array,
- unsigned length);
- static inline scoped_refptr<Uint16Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<uint16_t>::Set;
- using IntegralTypedArrayBase<uint16_t>::Set;
-
- ViewType GetType() const override { return kTypeUint16; }
-
- private:
- inline Uint16Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<uint16_t>;
-};
-
-scoped_refptr<Uint16Array> Uint16Array::Create(unsigned length) {
- return TypedArrayBase<uint16_t>::Create<Uint16Array>(length);
-}
-
-scoped_refptr<Uint16Array> Uint16Array::Create(const uint16_t* array,
- unsigned length) {
- return TypedArrayBase<uint16_t>::Create<Uint16Array>(array, length);
-}
-
-scoped_refptr<Uint16Array> Uint16Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<uint16_t>::Create<Uint16Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Uint16Array::Uint16Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<uint16_t>(std::move(buffer), byte_offset, length) {
-}
-
-} // namespace WTF
-
-using WTF::Uint16Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT16_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint32_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint32_array.h
deleted file mode 100644
index 1533c27b163..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint32_array.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT32_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT32_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-
-class Uint32Array final : public IntegralTypedArrayBase<unsigned> {
- public:
- static inline scoped_refptr<Uint32Array> Create(unsigned length);
- static inline scoped_refptr<Uint32Array> Create(const unsigned* array,
- unsigned length);
- static inline scoped_refptr<Uint32Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<unsigned>::Set;
- using IntegralTypedArrayBase<unsigned>::Set;
-
- ViewType GetType() const override { return kTypeUint32; }
-
- private:
- inline Uint32Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<unsigned>;
-};
-
-scoped_refptr<Uint32Array> Uint32Array::Create(unsigned length) {
- return TypedArrayBase<unsigned>::Create<Uint32Array>(length);
-}
-
-scoped_refptr<Uint32Array> Uint32Array::Create(const unsigned* array,
- unsigned length) {
- return TypedArrayBase<unsigned>::Create<Uint32Array>(array, length);
-}
-
-scoped_refptr<Uint32Array> Uint32Array::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<unsigned>::Create<Uint32Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Uint32Array::Uint32Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<unsigned>(std::move(buffer), byte_offset, length) {
-}
-
-} // namespace WTF
-
-using WTF::Uint32Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT32_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h
deleted file mode 100644
index 5e43e6500ca..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/integral_typed_array_base.h"
-
-namespace WTF {
-
-class ArrayBuffer;
-
-class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
- public:
- static inline scoped_refptr<Uint8Array> Create(unsigned length);
- static inline scoped_refptr<Uint8Array> Create(const unsigned char* array,
- unsigned length);
- static inline scoped_refptr<Uint8Array> Create(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
-
- using TypedArrayBase<unsigned char>::Set;
- using IntegralTypedArrayBase<unsigned char>::Set;
-
- ViewType GetType() const override { return kTypeUint8; }
-
- protected:
- inline Uint8Array(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<unsigned char>;
-};
-
-scoped_refptr<Uint8Array> Uint8Array::Create(unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8Array>(length);
-}
-
-scoped_refptr<Uint8Array> Uint8Array::Create(const unsigned char* array,
- unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8Array>(array, length);
-}
-
-scoped_refptr<Uint8Array> Uint8Array::Create(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8Array>(std::move(buffer),
- byte_offset, length);
-}
-
-Uint8Array::Uint8Array(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : IntegralTypedArrayBase<unsigned char>(std::move(buffer),
- byte_offset,
- length) {}
-
-} // namespace WTF
-
-using WTF::Uint8Array;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_clamped_array.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_clamped_array.h
deleted file mode 100644
index 9ffa2324b1b..00000000000
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/uint8_clamped_array.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_CLAMPED_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_CLAMPED_ARRAY_H_
-
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h"
-
-namespace WTF {
-
-class Uint8ClampedArray final : public Uint8Array {
- public:
- static inline scoped_refptr<Uint8ClampedArray> Create(unsigned length);
- static inline scoped_refptr<Uint8ClampedArray> Create(
- const unsigned char* array,
- unsigned length);
- static inline scoped_refptr<Uint8ClampedArray>
- Create(scoped_refptr<ArrayBuffer>, unsigned byte_offset, unsigned length);
-
- using TypedArrayBase<unsigned char>::Set;
- inline void Set(unsigned index, double value);
-
- ViewType GetType() const override { return kTypeUint8Clamped; }
-
- private:
- inline Uint8ClampedArray(scoped_refptr<ArrayBuffer>,
- unsigned byte_offset,
- unsigned length);
- // Make constructor visible to superclass.
- friend class TypedArrayBase<unsigned char>;
-};
-
-scoped_refptr<Uint8ClampedArray> Uint8ClampedArray::Create(unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8ClampedArray>(length);
-}
-
-scoped_refptr<Uint8ClampedArray> Uint8ClampedArray::Create(
- const unsigned char* array,
- unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8ClampedArray>(array,
- length);
-}
-
-scoped_refptr<Uint8ClampedArray> Uint8ClampedArray::Create(
- scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length) {
- return TypedArrayBase<unsigned char>::Create<Uint8ClampedArray>(
- std::move(buffer), byte_offset, length);
-}
-
-void Uint8ClampedArray::Set(unsigned index, double value) {
- if (index >= length_)
- return;
- if (std::isnan(value) || value < 0)
- value = 0;
- else if (value > 255)
- value = 255;
- Data()[index] = static_cast<unsigned char>(lrint(value));
-}
-
-Uint8ClampedArray::Uint8ClampedArray(scoped_refptr<ArrayBuffer> buffer,
- unsigned byte_offset,
- unsigned length)
- : Uint8Array(std::move(buffer), byte_offset, length) {}
-
-} // namespace WTF
-
-using WTF::Uint8ClampedArray;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TYPED_ARRAYS_UINT8_CLAMPED_ARRAY_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector.h b/chromium/third_party/blink/renderer/platform/wtf/vector.h
index 43a27f72f79..1b321ec9462 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector.h
@@ -151,27 +151,31 @@ struct VectorMover;
template <typename T, typename Allocator>
struct VectorMover<false, T, Allocator> {
STATIC_ONLY(VectorMover);
- static void Move(T* src, T* src_end, T* dst) {
+ using Traits = ConstructTraits<T, VectorTraits<T>, Allocator>;
+ static void Move(T* src, T* src_end, T* dst, bool has_inline_buffer) {
while (src != src_end) {
- ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
- dst, std::move(*src));
+ T* newly_created = Traits::Construct(dst, std::move(*src));
+ if (has_inline_buffer)
+ Traits::NotifyNewElement(newly_created);
src->~T();
++dst;
++src;
}
}
- static void MoveOverlapping(T* src, T* src_end, T* dst) {
+ static void MoveOverlapping(T* src,
+ T* src_end,
+ T* dst,
+ bool has_inline_buffer) {
if (src > dst) {
- Move(src, src_end, dst);
+ Move(src, src_end, dst, has_inline_buffer);
} else {
T* dst_end = dst + (src_end - src);
while (src != src_end) {
--src_end;
--dst_end;
- ConstructTraits<T, VectorTraits<T>,
- Allocator>::ConstructAndNotifyElement(dst_end,
- std::move(
- *src_end));
+ T* newly_created = Traits::Construct(dst_end, std::move(*src_end));
+ if (has_inline_buffer)
+ Traits::NotifyNewElement(newly_created);
src_end->~T();
}
}
@@ -179,30 +183,37 @@ struct VectorMover<false, T, Allocator> {
static void Swap(T* src, T* src_end, T* dst) {
std::swap_ranges(src, src_end, dst);
const size_t len = src_end - src;
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(src, len);
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(dst, len);
+ Traits::NotifyNewElements(src, len);
+ Traits::NotifyNewElements(dst, len);
}
};
template <typename T, typename Allocator>
struct VectorMover<true, T, Allocator> {
STATIC_ONLY(VectorMover);
- static void Move(const T* src, const T* src_end, T* dst) {
+ using Traits = ConstructTraits<T, VectorTraits<T>, Allocator>;
+ static void Move(const T* src,
+ const T* src_end,
+ T* dst,
+ bool has_inline_buffer) {
if (LIKELY(dst && src)) {
memcpy(dst, src,
reinterpret_cast<const char*>(src_end) -
reinterpret_cast<const char*>(src));
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
- dst, src_end - src);
+ if (has_inline_buffer)
+ Traits::NotifyNewElements(dst, src_end - src);
}
}
- static void MoveOverlapping(const T* src, const T* src_end, T* dst) {
+ static void MoveOverlapping(const T* src,
+ const T* src_end,
+ T* dst,
+ bool has_inline_buffer) {
if (LIKELY(dst && src)) {
memmove(dst, src,
reinterpret_cast<const char*>(src_end) -
reinterpret_cast<const char*>(src));
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
- dst, src_end - src);
+ if (has_inline_buffer)
+ Traits::NotifyNewElements(dst, src_end - src);
}
}
static void Swap(T* src, T* src_end, T* dst) {
@@ -210,8 +221,8 @@ struct VectorMover<true, T, Allocator> {
reinterpret_cast<char*>(src_end),
reinterpret_cast<char*>(dst));
const size_t len = src_end - src;
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(src, len);
- ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(dst, len);
+ Traits::NotifyNewElements(src, len);
+ Traits::NotifyNewElements(dst, len);
}
};
@@ -332,14 +343,18 @@ struct VectorTypeOperations {
Allocator>::Initialize(begin, end);
}
- static void Move(T* src, T* src_end, T* dst) {
+ static void Move(T* src, T* src_end, T* dst, bool has_inline_buffer = true) {
VectorMover<VectorTraits<T>::kCanMoveWithMemcpy, T, Allocator>::Move(
- src, src_end, dst);
+ src, src_end, dst, has_inline_buffer);
}
- static void MoveOverlapping(T* src, T* src_end, T* dst) {
+ static void MoveOverlapping(T* src,
+ T* src_end,
+ T* dst,
+ bool has_inline_buffer = true) {
VectorMover<VectorTraits<T>::kCanMoveWithMemcpy, T,
- Allocator>::MoveOverlapping(src, src_end, dst);
+ Allocator>::MoveOverlapping(src, src_end, dst,
+ has_inline_buffer);
}
static void Swap(T* src, T* src_end, T* dst) {
@@ -379,36 +394,26 @@ struct VectorTypeOperations {
//
// Not meant for general consumption.
-template <typename T, bool hasInlineCapacity, typename Allocator>
+template <typename T, typename Allocator>
class VectorBufferBase {
DISALLOW_NEW();
public:
- void AllocateBuffer(wtf_size_t new_capacity) {
+ VectorBufferBase(VectorBufferBase&&) = default;
+ VectorBufferBase& operator=(VectorBufferBase&&) = default;
+
+ void AllocateBufferNoBarrier(wtf_size_t new_capacity) {
DCHECK(new_capacity);
DCHECK_LE(new_capacity,
Allocator::template MaxElementCountInBackingStore<T>());
size_t size_to_allocate = AllocationSize(new_capacity);
- if (hasInlineCapacity)
- buffer_ =
- Allocator::template AllocateInlineVectorBacking<T>(size_to_allocate);
- else
- buffer_ = Allocator::template AllocateVectorBacking<T>(size_to_allocate);
+ buffer_ = Allocator::template AllocateVectorBacking<T>(size_to_allocate);
capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
- Allocator::BackingWriteBarrier(buffer_, 0);
}
- void AllocateExpandedBuffer(wtf_size_t new_capacity) {
- DCHECK(new_capacity);
- size_t size_to_allocate = AllocationSize(new_capacity);
- if (hasInlineCapacity)
- buffer_ =
- Allocator::template AllocateInlineVectorBacking<T>(size_to_allocate);
- else
- buffer_ = Allocator::template AllocateExpandedVectorBacking<T>(
- size_to_allocate);
- capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
- Allocator::BackingWriteBarrier(buffer_, 0);
+ void AllocateBuffer(wtf_size_t new_capacity) {
+ AllocateBufferNoBarrier(new_capacity);
+ Allocator::BackingWriteBarrier(buffer_);
}
size_t AllocationSize(size_t capacity) const {
@@ -440,6 +445,11 @@ class VectorBufferBase {
#endif
}
+ void MoveBufferInto(VectorBufferBase& other) {
+ other.buffer_ = buffer_;
+ other.capacity_ = capacity_;
+ }
+
// |end| is exclusive, a la STL.
struct OffsetRange final {
OffsetRange() : begin(0), end(0) {}
@@ -453,6 +463,12 @@ class VectorBufferBase {
};
protected:
+ static VectorBufferBase AllocateTemporaryBuffer(wtf_size_t capacity) {
+ VectorBufferBase buffer;
+ buffer.AllocateBufferNoBarrier(capacity);
+ return buffer;
+ }
+
VectorBufferBase() : buffer_(nullptr), capacity_(0) {}
VectorBufferBase(T* buffer, wtf_size_t capacity)
@@ -460,6 +476,7 @@ class VectorBufferBase {
VectorBufferBase(HashTableDeletedValueType value)
: buffer_(reinterpret_cast<T*>(-1)) {}
+
bool IsHashTableDeletedValue() const {
return buffer_ == reinterpret_cast<T*>(-1);
}
@@ -477,10 +494,9 @@ template <typename T,
class VectorBuffer;
template <typename T, typename Allocator>
-class VectorBuffer<T, 0, Allocator>
- : protected VectorBufferBase<T, false, Allocator> {
+class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocator> {
private:
- using Base = VectorBufferBase<T, false, Allocator>;
+ using Base = VectorBufferBase<T, Allocator>;
public:
using OffsetRange = typename Base::OffsetRange;
@@ -538,8 +554,8 @@ class VectorBuffer<T, 0, Allocator>
std::swap(buffer_, other.buffer_);
std::swap(capacity_, other.capacity_);
std::swap(size_, other.size_);
- Allocator::BackingWriteBarrier(buffer_, size_);
- Allocator::BackingWriteBarrier(other.buffer_, other.size_);
+ Allocator::BackingWriteBarrier(buffer_);
+ Allocator::BackingWriteBarrier(other.buffer_);
}
using Base::AllocateBuffer;
@@ -568,9 +584,9 @@ class VectorBuffer<T, 0, Allocator>
};
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
-class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
+class VectorBuffer : protected VectorBufferBase<T, Allocator> {
private:
- using Base = VectorBufferBase<T, true, Allocator>;
+ using Base = VectorBufferBase<T, Allocator>;
public:
using OffsetRange = typename Base::OffsetRange;
@@ -594,7 +610,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
}
NOINLINE void ReallyDeallocateBuffer(T* buffer_to_deallocate) {
- Allocator::FreeInlineVectorBacking(buffer_to_deallocate);
+ Allocator::FreeVectorBacking(buffer_to_deallocate);
}
void DeallocateBuffer(T* buffer_to_deallocate) {
@@ -608,7 +624,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
return false;
size_t size_to_allocate = AllocationSize(new_capacity);
- if (Allocator::ExpandInlineVectorBacking(buffer_, size_to_allocate)) {
+ if (Allocator::ExpandVectorBacking(buffer_, size_to_allocate)) {
capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
return true;
}
@@ -624,8 +640,8 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
}
DCHECK_NE(buffer_, InlineBuffer());
size_t new_size = AllocationSize(new_capacity);
- if (!Allocator::ShrinkInlineVectorBacking(
- buffer_, AllocationSize(capacity()), new_size))
+ if (!Allocator::ShrinkVectorBacking(buffer_, AllocationSize(capacity()),
+ new_size))
return false;
capacity_ = static_cast<wtf_size_t>(new_size / sizeof(T));
return true;
@@ -644,13 +660,6 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
ResetBufferPointer();
}
- void AllocateExpandedBuffer(wtf_size_t new_capacity) {
- if (new_capacity > inlineCapacity)
- Base::AllocateExpandedBuffer(new_capacity);
- else
- ResetBufferPointer();
- }
-
size_t AllocationSize(size_t capacity) const {
if (capacity <= inlineCapacity)
return kInlineBufferSize;
@@ -685,8 +694,8 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
std::swap(buffer_, other.buffer_);
std::swap(capacity_, other.capacity_);
std::swap(size_, other.size_);
- Allocator::BackingWriteBarrier(buffer_, size_);
- Allocator::BackingWriteBarrier(other.buffer_, other.size_);
+ Allocator::BackingWriteBarrier(buffer_);
+ Allocator::BackingWriteBarrier(other.buffer_);
return;
}
@@ -747,7 +756,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
other.buffer_ = other.InlineBuffer();
std::swap(size_, other.size_);
ANNOTATE_NEW_BUFFER(other.buffer_, inlineCapacity, other.size_);
- Allocator::BackingWriteBarrier(buffer_, size_);
+ Allocator::BackingWriteBarrier(buffer_);
} else if (!this_source_begin &&
other_source_begin) { // Their buffer is inline, ours is not.
DCHECK_NE(Buffer(), InlineBuffer());
@@ -757,7 +766,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
buffer_ = InlineBuffer();
std::swap(size_, other.size_);
ANNOTATE_NEW_BUFFER(buffer_, inlineCapacity, size_);
- Allocator::BackingWriteBarrier(other.buffer_, other.size_);
+ Allocator::BackingWriteBarrier(other.buffer_);
} else { // Both buffers are inline.
DCHECK(this_source_begin);
DCHECK(other_source_begin);
@@ -1311,6 +1320,12 @@ class Vector
template <typename U>
void AppendSlowCase(U&&);
+ bool HasInlineBuffer() const {
+ return INLINE_CAPACITY && !this->HasOutOfLineBuffer();
+ }
+
+ void ReallocateBuffer(wtf_size_t);
+
// This is to prevent compilation of deprecated calls like 'vector.erase(0)'.
void erase(std::nullptr_t) = delete;
@@ -1640,8 +1655,7 @@ void Vector<T, inlineCapacity, Allocator>::ReserveCapacity(
wtf_size_t new_capacity) {
if (UNLIKELY(new_capacity <= capacity()))
return;
- T* old_buffer = begin();
- if (!old_buffer) {
+ if (!data()) {
Base::AllocateBuffer(new_capacity);
return;
}
@@ -1658,13 +1672,7 @@ void Vector<T, inlineCapacity, Allocator>::ReserveCapacity(
// Reallocating a backing buffer may resurrect a dead object.
CHECK(Allocator::IsAllocationAllowed());
- T* old_end = end();
- Base::AllocateExpandedBuffer(new_capacity);
- ANNOTATE_NEW_BUFFER(begin(), capacity(), size_);
- TypeOperations::Move(old_buffer, old_end, begin());
- ClearUnusedSlots(old_buffer, old_end);
- ANNOTATE_DELETE_BUFFER(old_buffer, old_capacity, size_);
- Base::DeallocateBuffer(old_buffer);
+ ReallocateBuffer(new_capacity);
}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
@@ -1701,24 +1709,16 @@ void Vector<T, inlineCapacity, Allocator>::ShrinkCapacity(
if (!Allocator::IsAllocationAllowed())
return;
- T* old_end = end();
- Base::AllocateBuffer(new_capacity);
- if (begin() != old_buffer) {
- ANNOTATE_NEW_BUFFER(begin(), capacity(), size_);
- TypeOperations::Move(old_buffer, old_end, begin());
- ClearUnusedSlots(old_buffer, old_end);
- ANNOTATE_DELETE_BUFFER(old_buffer, old_capacity, size_);
- }
- } else {
- Base::ResetBufferPointer();
+ ReallocateBuffer(new_capacity);
+ return;
+ }
+ Base::ResetBufferPointer();
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- if (old_buffer != begin()) {
- ANNOTATE_NEW_BUFFER(begin(), capacity(), size_);
- ANNOTATE_DELETE_BUFFER(old_buffer, old_capacity, size_);
- }
-#endif
+ if (old_buffer != begin()) {
+ ANNOTATE_NEW_BUFFER(begin(), capacity(), size_);
+ ANNOTATE_DELETE_BUFFER(old_buffer, old_capacity, size_);
}
-
+#endif
Base::DeallocateBuffer(old_buffer);
}
@@ -1995,7 +1995,7 @@ Vector<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
if (IsTraceableInCollectionTrait<VectorTraits<T>>::value) {
for (const T* buffer_entry = buffer_begin; buffer_entry != buffer_end;
buffer_entry++) {
- Allocator::template Trace<VisitorDispatcher, T, VectorTraits<T>>(
+ Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
CheckUnusedSlots(Buffer() + size(), Buffer() + capacity());
@@ -2003,6 +2003,41 @@ Vector<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
}
}
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+void Vector<T, inlineCapacity, Allocator>::ReallocateBuffer(
+ wtf_size_t new_capacity) {
+ if (new_capacity <= INLINE_CAPACITY) {
+ if (HasInlineBuffer()) {
+ Base::ResetBufferPointer();
+ return;
+ }
+ // Shrinking to inline buffer from out-of-line one.
+ T *old_begin = begin(), *old_end = end();
+#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
+ const wtf_size_t old_capacity = capacity();
+#endif
+ Base::ResetBufferPointer();
+ TypeOperations::Move(old_begin, old_end, begin());
+ ClearUnusedSlots(old_begin, old_end);
+ ANNOTATE_DELETE_BUFFER(old_begin, old_capacity, size_);
+ Base::DeallocateBuffer(old_begin);
+ return;
+ }
+ // Shrinking/resizing to out-of-line buffer.
+ VectorBufferBase<T, Allocator> buffer =
+ Base::AllocateTemporaryBuffer(new_capacity);
+ ANNOTATE_NEW_BUFFER(buffer.Buffer(), buffer.capacity(), size_);
+ // If there was a new out-of-line buffer allocated, there is no need in
+ // calling write barriers for entries in that backing store as it is still
+ // white.
+ TypeOperations::Move(begin(), end(), buffer.Buffer(), HasInlineBuffer());
+ ClearUnusedSlots(begin(), end());
+ ANNOTATE_DELETE_BUFFER(begin(), capacity(), size_);
+ Base::DeallocateBuffer(begin());
+ buffer.MoveBufferInto(*this);
+ Allocator::BackingWriteBarrier(begin());
+}
+
} // namespace WTF
namespace base {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector_traits.h b/chromium/third_party/blink/renderer/platform/wtf/vector_traits.h
index 1de690e2b90..0efa4ccf760 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_traits.h
@@ -63,8 +63,6 @@ struct VectorTraitsBase {
struct IsTraceableInCollection {
static const bool value = IsTraceable<T>::value;
};
- // We don't support weak handling in vectors.
- static const WeakHandlingFlag kWeakHandlingFlag = kNoWeakHandling;
// Vectors do not support deleting values.
static constexpr bool kCanHaveDeletedValue = false;
@@ -145,8 +143,6 @@ struct VectorTraits<std::pair<First, Second>> {
IsTraceableInCollectionTrait<FirstTraits>::value ||
IsTraceableInCollectionTrait<SecondTraits>::value;
};
- // We don't support weak handling in vectors.
- static const WeakHandlingFlag kWeakHandlingFlag = kNoWeakHandling;
// Vectors do not support deleting values.
static constexpr bool kCanHaveDeletedValue = false;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
index 50809fbd5a6..c98254eec1d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
@@ -41,7 +41,6 @@
#include "third_party/blink/renderer/platform/wtf/text/string_statics.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
namespace WTF {